]> git.ipfire.org Git - thirdparty/openembedded/openembedded-core-contrib.git/blob
14b4bfbc02a384b3a9729b1dd0fd068cfd6aa8b0
[thirdparty/openembedded/openembedded-core-contrib.git] /
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
5
6 Patch-mainline: 2.6.34
7 Git-commit: f358f5b40af67caf28b627889d007294614170b2
8
9 g_nokia is the gadget driver implementing
10 WMCDC Wireless Handset Control Model for the N900
11 device.
12
13 Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>
14 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
15 ---
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
21
22 --- a/drivers/usb/gadget/Kconfig
23 +++ b/drivers/usb/gadget/Kconfig
24 @@ -828,6 +828,16 @@
25 Say "y" to link the driver statically, or "m" to build a
26 dynamically linked module.
27
28 +config USB_G_NOKIA
29 + tristate "Nokia composite gadget"
30 + depends on PHONET
31 + help
32 + The Nokia composite gadget provides support for acm, obex
33 + and phonet in only one composite gadget driver.
34 +
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.
37 +
38 config USB_G_MULTI
39 tristate "Multifunction Composite Gadget (EXPERIMENTAL)"
40 depends on BLOCK && NET
41 --- a/drivers/usb/gadget/Makefile
42 +++ b/drivers/usb/gadget/Makefile
43 @@ -44,6 +44,7 @@
44 g_cdc-objs := cdc2.o
45 g_multi-objs := multi.o
46 g_still_image-objs := still_image.o
47 +g_nokia-objs := nokia.o
48
49 obj-$(CONFIG_USB_ZERO) += g_zero.o
50 obj-$(CONFIG_USB_AUDIO) += g_audio.o
51 @@ -57,6 +58,7 @@
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
56
57 ifeq ($(CONFIG_USB_GADGET_DEBUG),y)
58 EXTRA_CFLAGS += -DDMA_PPB_MODE
59 --- /dev/null
60 +++ b/drivers/usb/gadget/nokia.c
61 @@ -0,0 +1,259 @@
62 +/*
63 + * nokia.c -- Nokia Composite Gadget Driver
64 + *
65 + * Copyright (C) 2008-2010 Nokia Corporation
66 + * Contact: Felipe Balbi <felipe.balbi@nokia.com>
67 + *
68 + * This gadget driver borrows from serial.c which is:
69 + *
70 + * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
71 + * Copyright (C) 2008 by David Brownell
72 + * Copyright (C) 2008 by Nokia Corporation
73 + *
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.
77 + */
78 +
79 +#include <linux/kernel.h>
80 +#include <linux/utsname.h>
81 +#include <linux/device.h>
82 +
83 +#include "u_serial.h"
84 +#include "u_ether.h"
85 +#include "u_phonet.h"
86 +#include "gadget_chips.h"
87 +
88 +/* Defines */
89 +
90 +#define NOKIA_VERSION_NUM 0x0211
91 +#define NOKIA_LONG_NAME "N900 (PC-Suite Mode)"
92 +
93 +/*-------------------------------------------------------------------------*/
94 +
95 +/*
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.
101 + */
102 +#include "composite.c"
103 +#include "usbstring.c"
104 +#include "config.c"
105 +#include "epautoconf.c"
106 +
107 +#include "u_serial.c"
108 +#include "f_acm.c"
109 +#include "f_ecm.c"
110 +#include "f_obex.c"
111 +#include "f_serial.c"
112 +#include "f_phonet.c"
113 +#include "u_ether.c"
114 +
115 +/*-------------------------------------------------------------------------*/
116 +
117 +#define NOKIA_VENDOR_ID 0x0421 /* Nokia */
118 +#define NOKIA_PRODUCT_ID 0x01c8 /* Nokia Gadget */
119 +
120 +/* string IDs are assigned dynamically */
121 +
122 +#define STRING_MANUFACTURER_IDX 0
123 +#define STRING_PRODUCT_IDX 1
124 +#define STRING_DESCRIPTION_IDX 2
125 +
126 +static char manufacturer_nokia[] = "Nokia";
127 +static const char product_nokia[] = NOKIA_LONG_NAME;
128 +static const char description_nokia[] = "PC-Suite Configuration";
129 +
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 */
135 +};
136 +
137 +static struct usb_gadget_strings stringtab_dev = {
138 + .language = 0x0409, /* en-us */
139 + .strings = strings_dev,
140 +};
141 +
142 +static struct usb_gadget_strings *dev_strings[] = {
143 + &stringtab_dev,
144 + NULL,
145 +};
146 +
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,
157 +};
158 +
159 +/*-------------------------------------------------------------------------*/
160 +
161 +/* Module */
162 +MODULE_DESCRIPTION("Nokia composite gadget driver for N900");
163 +MODULE_AUTHOR("Felipe Balbi");
164 +MODULE_LICENSE("GPL");
165 +
166 +/*-------------------------------------------------------------------------*/
167 +
168 +static u8 hostaddr[ETH_ALEN];
169 +
170 +static int __init nokia_bind_config(struct usb_configuration *c)
171 +{
172 + int status = 0;
173 +
174 + status = phonet_bind_config(c);
175 + if (status)
176 + printk(KERN_DEBUG "could not bind phonet config\n");
177 +
178 + status = obex_bind_config(c, 0);
179 + if (status)
180 + printk(KERN_DEBUG "could not bind obex config %d\n", 0);
181 +
182 + status = obex_bind_config(c, 1);
183 + if (status)
184 + printk(KERN_DEBUG "could not bind obex config %d\n", 0);
185 +
186 + status = acm_bind_config(c, 2);
187 + if (status)
188 + printk(KERN_DEBUG "could not bind acm config\n");
189 +
190 + status = ecm_bind_config(c, hostaddr);
191 + if (status)
192 + printk(KERN_DEBUG "could not bind ecm config\n");
193 +
194 + return status;
195 +}
196 +
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 */
204 +};
205 +
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 */
213 +};
214 +
215 +static int __init nokia_bind(struct usb_composite_dev *cdev)
216 +{
217 + int gcnum;
218 + struct usb_gadget *gadget = cdev->gadget;
219 + int status;
220 +
221 + status = gphonet_setup(cdev->gadget);
222 + if (status < 0)
223 + goto err_phonet;
224 +
225 + status = gserial_setup(cdev->gadget, 3);
226 + if (status < 0)
227 + goto err_serial;
228 +
229 + status = gether_setup(cdev->gadget, hostaddr);
230 + if (status < 0)
231 + goto err_ether;
232 +
233 + status = usb_string_id(cdev);
234 + if (status < 0)
235 + goto err_usb;
236 + strings_dev[STRING_MANUFACTURER_IDX].id = status;
237 +
238 + device_desc.iManufacturer = status;
239 +
240 + status = usb_string_id(cdev);
241 + if (status < 0)
242 + goto err_usb;
243 + strings_dev[STRING_PRODUCT_IDX].id = status;
244 +
245 + device_desc.iProduct = status;
246 +
247 + /* config description */
248 + status = usb_string_id(cdev);
249 + if (status < 0)
250 + goto err_usb;
251 + strings_dev[STRING_DESCRIPTION_IDX].id = status;
252 +
253 + nokia_config_500ma_driver.iConfiguration = status;
254 + nokia_config_100ma_driver.iConfiguration = status;
255 +
256 + /* set up other descriptors */
257 + gcnum = usb_gadget_controller_number(gadget);
258 + if (gcnum >= 0)
259 + device_desc.bcdDevice = cpu_to_le16(NOKIA_VERSION_NUM);
260 + else {
261 + /* this should only work with hw that supports altsettings
262 + * and several endpoints, anything else, panic.
263 + */
264 + pr_err("nokia_bind: controller '%s' not recognized\n",
265 + gadget->name);
266 + goto err_usb;
267 + }
268 +
269 + /* finaly register the configuration */
270 + status = usb_add_config(cdev, &nokia_config_500ma_driver);
271 + if (status < 0)
272 + goto err_usb;
273 +
274 + status = usb_add_config(cdev, &nokia_config_100ma_driver);
275 + if (status < 0)
276 + goto err_usb;
277 +
278 + dev_info(&gadget->dev, "%s\n", NOKIA_LONG_NAME);
279 +
280 + return 0;
281 +
282 +err_usb:
283 + gether_cleanup();
284 +err_ether:
285 + gserial_cleanup();
286 +err_serial:
287 + gphonet_cleanup();
288 +err_phonet:
289 + return status;
290 +}
291 +
292 +static int __exit nokia_unbind(struct usb_composite_dev *cdev)
293 +{
294 + gphonet_cleanup();
295 + gserial_cleanup();
296 + gether_cleanup();
297 +
298 + return 0;
299 +}
300 +
301 +static struct usb_composite_driver nokia_driver = {
302 + .name = "g_nokia",
303 + .dev = &device_desc,
304 + .strings = dev_strings,
305 + .bind = nokia_bind,
306 + .unbind = __exit_p(nokia_unbind),
307 +};
308 +
309 +static int __init nokia_init(void)
310 +{
311 + return usb_composite_register(&nokia_driver);
312 +}
313 +module_init(nokia_init);
314 +
315 +static void __exit nokia_cleanup(void)
316 +{
317 + usb_composite_unregister(&nokia_driver);
318 +}
319 +module_exit(nokia_cleanup);
320 +