1 From d96b241bd2ad42b6c49d5f6435c69b23818f001e Mon Sep 17 00:00:00 2001
2 From: Felipe Balbi <felipe.balbi@nokia.com>
3 Date: Tue, 5 Jan 2010 16:10:13 +0200
4 Subject: [PATCH 9/10] USB: gadget: introduce g_nokia gadget driver
7 Git-commit: f358f5b40af67caf28b627889d007294614170b2
9 g_nokia is the gadget driver implementing
10 WMCDC Wireless Handset Control Model for the N900
13 Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>
14 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
16 drivers/usb/gadget/Kconfig | 10 +
17 drivers/usb/gadget/Makefile | 2
18 drivers/usb/gadget/nokia.c | 259 ++++++++++++++++++++++++++++++++++++++++++++
19 3 files changed, 271 insertions(+)
20 create mode 100644 drivers/usb/gadget/nokia.c
22 --- a/drivers/usb/gadget/Kconfig
23 +++ b/drivers/usb/gadget/Kconfig
25 Say "y" to link the driver statically, or "m" to build a
26 dynamically linked module.
29 + tristate "Nokia composite gadget"
32 + The Nokia composite gadget provides support for acm, obex
33 + and phonet in only one composite gadget driver.
35 + It's only really useful for N900 hardware. If you're building
36 + a kernel for N900, say Y or M here. If unsure, say N.
39 tristate "Multifunction Composite Gadget (EXPERIMENTAL)"
40 depends on BLOCK && NET
41 --- a/drivers/usb/gadget/Makefile
42 +++ b/drivers/usb/gadget/Makefile
45 g_multi-objs := multi.o
46 g_still_image-objs := still_image.o
47 +g_nokia-objs := nokia.o
49 obj-$(CONFIG_USB_ZERO) += g_zero.o
50 obj-$(CONFIG_USB_AUDIO) += g_audio.o
52 obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o
53 obj-$(CONFIG_USB_G_MULTI) += g_multi.o
54 obj-$(CONFIG_USB_STILL_IMAGE) += g_still_image.o
55 +obj-$(CONFIG_USB_G_NOKIA) += g_nokia.o
57 ifeq ($(CONFIG_USB_GADGET_DEBUG),y)
58 EXTRA_CFLAGS += -DDMA_PPB_MODE
60 +++ b/drivers/usb/gadget/nokia.c
63 + * nokia.c -- Nokia Composite Gadget Driver
65 + * Copyright (C) 2008-2010 Nokia Corporation
66 + * Contact: Felipe Balbi <felipe.balbi@nokia.com>
68 + * This gadget driver borrows from serial.c which is:
70 + * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
71 + * Copyright (C) 2008 by David Brownell
72 + * Copyright (C) 2008 by Nokia Corporation
74 + * This software is distributed under the terms of the GNU General
75 + * Public License ("GPL") as published by the Free Software Foundation,
76 + * version 2 of that License.
79 +#include <linux/kernel.h>
80 +#include <linux/utsname.h>
81 +#include <linux/device.h>
83 +#include "u_serial.h"
85 +#include "u_phonet.h"
86 +#include "gadget_chips.h"
90 +#define NOKIA_VERSION_NUM 0x0211
91 +#define NOKIA_LONG_NAME "N900 (PC-Suite Mode)"
93 +/*-------------------------------------------------------------------------*/
96 + * Kbuild is not very cooperative with respect to linking separately
97 + * compiled library objects into one module. So for now we won't use
98 + * separate compilation ... ensuring init/exit sections work to shrink
99 + * the runtime footprint, and giving us at least some parts of what
100 + * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
102 +#include "composite.c"
103 +#include "usbstring.c"
105 +#include "epautoconf.c"
107 +#include "u_serial.c"
111 +#include "f_serial.c"
112 +#include "f_phonet.c"
113 +#include "u_ether.c"
115 +/*-------------------------------------------------------------------------*/
117 +#define NOKIA_VENDOR_ID 0x0421 /* Nokia */
118 +#define NOKIA_PRODUCT_ID 0x01c8 /* Nokia Gadget */
120 +/* string IDs are assigned dynamically */
122 +#define STRING_MANUFACTURER_IDX 0
123 +#define STRING_PRODUCT_IDX 1
124 +#define STRING_DESCRIPTION_IDX 2
126 +static char manufacturer_nokia[] = "Nokia";
127 +static const char product_nokia[] = NOKIA_LONG_NAME;
128 +static const char description_nokia[] = "PC-Suite Configuration";
130 +static struct usb_string strings_dev[] = {
131 + [STRING_MANUFACTURER_IDX].s = manufacturer_nokia,
132 + [STRING_PRODUCT_IDX].s = NOKIA_LONG_NAME,
133 + [STRING_DESCRIPTION_IDX].s = description_nokia,
134 + { } /* end of list */
137 +static struct usb_gadget_strings stringtab_dev = {
138 + .language = 0x0409, /* en-us */
139 + .strings = strings_dev,
142 +static struct usb_gadget_strings *dev_strings[] = {
147 +static struct usb_device_descriptor device_desc = {
148 + .bLength = USB_DT_DEVICE_SIZE,
149 + .bDescriptorType = USB_DT_DEVICE,
150 + .bcdUSB = __constant_cpu_to_le16(0x0200),
151 + .bDeviceClass = USB_CLASS_COMM,
152 + .idVendor = __constant_cpu_to_le16(NOKIA_VENDOR_ID),
153 + .idProduct = __constant_cpu_to_le16(NOKIA_PRODUCT_ID),
154 + /* .iManufacturer = DYNAMIC */
155 + /* .iProduct = DYNAMIC */
156 + .bNumConfigurations = 1,
159 +/*-------------------------------------------------------------------------*/
162 +MODULE_DESCRIPTION("Nokia composite gadget driver for N900");
163 +MODULE_AUTHOR("Felipe Balbi");
164 +MODULE_LICENSE("GPL");
166 +/*-------------------------------------------------------------------------*/
168 +static u8 hostaddr[ETH_ALEN];
170 +static int __init nokia_bind_config(struct usb_configuration *c)
174 + status = phonet_bind_config(c);
176 + printk(KERN_DEBUG "could not bind phonet config\n");
178 + status = obex_bind_config(c, 0);
180 + printk(KERN_DEBUG "could not bind obex config %d\n", 0);
182 + status = obex_bind_config(c, 1);
184 + printk(KERN_DEBUG "could not bind obex config %d\n", 0);
186 + status = acm_bind_config(c, 2);
188 + printk(KERN_DEBUG "could not bind acm config\n");
190 + status = ecm_bind_config(c, hostaddr);
192 + printk(KERN_DEBUG "could not bind ecm config\n");
197 +static struct usb_configuration nokia_config_500ma_driver = {
198 + .label = "Bus Powered",
199 + .bind = nokia_bind_config,
200 + .bConfigurationValue = 1,
201 + /* .iConfiguration = DYNAMIC */
202 + .bmAttributes = USB_CONFIG_ATT_ONE,
203 + .bMaxPower = 250, /* 500mA */
206 +static struct usb_configuration nokia_config_100ma_driver = {
207 + .label = "Self Powered",
208 + .bind = nokia_bind_config,
209 + .bConfigurationValue = 2,
210 + /* .iConfiguration = DYNAMIC */
211 + .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
212 + .bMaxPower = 50, /* 100 mA */
215 +static int __init nokia_bind(struct usb_composite_dev *cdev)
218 + struct usb_gadget *gadget = cdev->gadget;
221 + status = gphonet_setup(cdev->gadget);
225 + status = gserial_setup(cdev->gadget, 3);
229 + status = gether_setup(cdev->gadget, hostaddr);
233 + status = usb_string_id(cdev);
236 + strings_dev[STRING_MANUFACTURER_IDX].id = status;
238 + device_desc.iManufacturer = status;
240 + status = usb_string_id(cdev);
243 + strings_dev[STRING_PRODUCT_IDX].id = status;
245 + device_desc.iProduct = status;
247 + /* config description */
248 + status = usb_string_id(cdev);
251 + strings_dev[STRING_DESCRIPTION_IDX].id = status;
253 + nokia_config_500ma_driver.iConfiguration = status;
254 + nokia_config_100ma_driver.iConfiguration = status;
256 + /* set up other descriptors */
257 + gcnum = usb_gadget_controller_number(gadget);
259 + device_desc.bcdDevice = cpu_to_le16(NOKIA_VERSION_NUM);
261 + /* this should only work with hw that supports altsettings
262 + * and several endpoints, anything else, panic.
264 + pr_err("nokia_bind: controller '%s' not recognized\n",
269 + /* finaly register the configuration */
270 + status = usb_add_config(cdev, &nokia_config_500ma_driver);
274 + status = usb_add_config(cdev, &nokia_config_100ma_driver);
278 + dev_info(&gadget->dev, "%s\n", NOKIA_LONG_NAME);
292 +static int __exit nokia_unbind(struct usb_composite_dev *cdev)
301 +static struct usb_composite_driver nokia_driver = {
303 + .dev = &device_desc,
304 + .strings = dev_strings,
305 + .bind = nokia_bind,
306 + .unbind = __exit_p(nokia_unbind),
309 +static int __init nokia_init(void)
311 + return usb_composite_register(&nokia_driver);
313 +module_init(nokia_init);
315 +static void __exit nokia_cleanup(void)
317 + usb_composite_unregister(&nokia_driver);
319 +module_exit(nokia_cleanup);