>From 845c8f6b7921b8b8558793a15b52628a2575e292 Mon Sep 17 00:00:00 2001 From: Jiebing Li <[email protected]> Date: Fri, 22 Oct 2010 15:44:52 +0800 Subject: [PATCH] usb gadget: add Intel ACM composite gadget for Medfield.
This composite gadget provides support several ACM functions in only one composite gadget device for Medfield. Kernel config: CONFIG_USB_G_INTEL_ACM Signed-off-by: Jiebing Li <[email protected]> Signed-off-by: Hao Wu <[email protected]> --- drivers/usb/gadget/Kconfig | 9 ++ drivers/usb/gadget/Makefile | 2 + drivers/usb/gadget/intel_acm.c | 232 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 243 insertions(+), 0 deletions(-) create mode 100644 drivers/usb/gadget/intel_acm.c diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index eaac013..05e2ab7 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -951,6 +951,15 @@ config USB_STILL_IMAGE Say "y" to link the driver statically, or "m" to build a dynamically linked module called "g_still_image". +config USB_G_INTEL_ACM + tristate "Intel ACM composite gadget" + help + The Intel composite gadget provides support for several ACM + functions in only one composite gadget driver. + + If you're building a kernel for Intel MID product, say Y + or M here. If unsure, say N. + endchoice diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 3e5ff83..4ff1ba7 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -47,6 +47,7 @@ g_hid-objs := hid.o g_nokia-objs := nokia.o g_webcam-objs := webcam.o g_still_image-objs := still_image.o +g_intel_acm-objs := intel_acm.o obj-$(CONFIG_USB_ZERO) += g_zero.o obj-$(CONFIG_USB_AUDIO) += g_audio.o @@ -65,4 +66,5 @@ obj-$(CONFIG_USB_G_MULTI) += g_multi.o obj-$(CONFIG_USB_G_NOKIA) += g_nokia.o obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o obj-$(CONFIG_USB_STILL_IMAGE) += g_still_image.o +obj-$(CONFIG_USB_G_INTEL_ACM) += g_intel_acm.o diff --git a/drivers/usb/gadget/intel_acm.c b/drivers/usb/gadget/intel_acm.c new file mode 100644 index 0000000..ad308d8 --- /dev/null +++ b/drivers/usb/gadget/intel_acm.c @@ -0,0 +1,232 @@ +/* + * intel_acm.c -- Intel ACM Composite Gadget Driver + * Copyright (C) 2008-2010, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * This gadget driver borrows from nokia.c which is: + * + * Copyright (C) 2008-2010 Nokia Corporation + */ + +#include <linux/kernel.h> +#include <linux/utsname.h> +#include <linux/device.h> + +#include "u_serial.h" +#include "gadget_chips.h" + +/* Defines */ + +#define VERSION_NUM 0x0101 + +/*-------------------------------------------------------------------------*/ + +/* + * Kbuild is not very cooperative with respect to linking separately + * compiled library objects into one module. So for now we won't use + * separate compilation ... ensuring init/exit sections work to shrink + * the runtime footprint, and giving us at least some parts of what + * a "gcc --combine ... part1.c part2.c part3.c ... " build would. + */ +#include "composite.c" +#include "usbstring.c" +#include "config.c" +#include "epautoconf.c" + +#include "u_serial.c" +#include "f_acm.c" +#include "f_serial.c" + + +/*-------------------------------------------------------------------------*/ + +/* Temporarily use below PID and will update it soon */ +#define DRIVER_VENDOR_ID 0x8087 +#define DRIVER_PRODUCT_ID 0xffff + +/* string IDs are assigned dynamically */ + +#define STRING_MANUFACTURER_IDX 0 +#define STRING_PRODUCT_IDX 1 +#define STRING_DESCRIPTION_IDX 2 + + +static struct usb_string strings_dev[] = { + [STRING_MANUFACTURER_IDX].s = "Intel", + [STRING_PRODUCT_IDX].s = "Medfield", + [STRING_DESCRIPTION_IDX].s = "ACM configuration", + { } /* end of list */ +}; + +static struct usb_gadget_strings stringtab_dev = { + .language = 0x0409, /* en-us */ + .strings = strings_dev, +}; + +static struct usb_gadget_strings *dev_strings[] = { + &stringtab_dev, + NULL, +}; + +static struct usb_device_descriptor device_desc = { + .bLength = sizeof device_desc, + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = __constant_cpu_to_le16(0x0200), + .bDeviceClass = USB_CLASS_COMM, + .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_ID), + .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_ID), + /* .iManufacturer = DYNAMIC */ + /* .iProduct = DYNAMIC */ + .bNumConfigurations = 1, +}; + +/*-------------------------------------------------------------------------*/ + +/* Module */ + +/*-------------------------------------------------------------------------*/ + + +static int __init intel_acm_bind_config(struct usb_configuration *c) +{ + int status = 0; + + status = acm_bind_config(c, 0); + if (status) + printk(KERN_DEBUG "could not bind acm 0 config\n"); + + status = acm_bind_config(c, 1); + if (status) + printk(KERN_DEBUG "could not bind acm 1 config\n"); + + /* IN endpoint is not enough for 3rd interface + status = acm_bind_config(c, 2); + if (status) + printk(KERN_DEBUG "could not bind acm 2 config\n"); + */ + return status; +} + +static struct usb_configuration intel_acm_config_500ma_driver = { + .label = "Bus Powered", + .bind = intel_acm_bind_config, + .bConfigurationValue = 1, + /* .iConfiguration = DYNAMIC */ + .bmAttributes = USB_CONFIG_ATT_ONE, + .bMaxPower = 250, /* 500mA */ +}; + +static struct usb_configuration intel_acm_config_100ma_driver = { + .label = "Self Powered", + .bind = intel_acm_bind_config, + .bConfigurationValue = 2, + /* .iConfiguration = DYNAMIC */ + .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, + .bMaxPower = 50, /* 100 mA */ +}; + +static int __init intel_acm_bind(struct usb_composite_dev *cdev) +{ + int gcnum; + struct usb_gadget *gadget = cdev->gadget; + int status; + + status = gserial_setup(cdev->gadget, 3); + if (status < 0) + goto err_serial; + + status = usb_string_id(cdev); + if (status < 0) + goto err_usb; + strings_dev[STRING_MANUFACTURER_IDX].id = status; + + device_desc.iManufacturer = status; + + status = usb_string_id(cdev); + if (status < 0) + goto err_usb; + strings_dev[STRING_PRODUCT_IDX].id = status; + + device_desc.iProduct = status; + + /* config description */ + status = usb_string_id(cdev); + if (status < 0) + goto err_usb; + strings_dev[STRING_DESCRIPTION_IDX].id = status; + + intel_acm_config_500ma_driver.iConfiguration = status; + intel_acm_config_100ma_driver.iConfiguration = status; + + /* set up other descriptors */ + gcnum = usb_gadget_controller_number(gadget); + if (gcnum >= 0) + device_desc.bcdDevice = cpu_to_le16(VERSION_NUM); + else { + pr_err("intel_acm_bind: controller '%s' not recognized\n", + gadget->name); + goto err_usb; + } + + /* finaly register the configuration */ + status = usb_add_config(cdev, &intel_acm_config_500ma_driver); + if (status < 0) + goto err_usb; + + status = usb_add_config(cdev, &intel_acm_config_100ma_driver); + if (status < 0) + goto err_usb; + + return 0; + +err_usb: + gserial_cleanup(); +err_serial: + return status; +} + +static int __exit intel_acm_unbind(struct usb_composite_dev *cdev) +{ + gserial_cleanup(); + + return 0; +} + +static struct usb_composite_driver intel_acm_driver = { + .name = "intel_acm", + .dev = &device_desc, + .strings = dev_strings, + .bind = intel_acm_bind, + .unbind = __exit_p(intel_acm_unbind), +}; + + +static int __init intel_acm_init(void) +{ + return usb_composite_register(&intel_acm_driver); +} +module_init(intel_acm_init); + +static void __exit intel_acm_cleanup(void) +{ + usb_composite_unregister(&intel_acm_driver); +} +module_exit(intel_acm_cleanup); + + +MODULE_DESCRIPTION("Intel ACM composite gadget driver"); +MODULE_AUTHOR("Jiebing Li"); +MODULE_LICENSE("GPL"); + -- 1.6.0.6
0001-usb-gadget-add-Intel-ACM-composite-gadget-for-Medfi.patch
Description: 0001-usb-gadget-add-Intel-ACM-composite-gadget-for-Medfi.patch
_______________________________________________ Meego-kernel mailing list [email protected] http://lists.meego.com/listinfo/meego-kernel
