2 * nokia.c -- Nokia Composite Gadget Driver
4 * Copyright (C) 2008-2010 Nokia Corporation
5 * Contact: Felipe Balbi <felipe.balbi@nokia.com>
7 * This gadget driver borrows from serial.c which is:
9 * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
10 * Copyright (C) 2008 by David Brownell
11 * Copyright (C) 2008 by Nokia Corporation
13 * This software is distributed under the terms of the GNU General
14 * Public License ("GPL") as published by the Free Software Foundation,
15 * version 2 of that License.
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/device.h>
26 #include "gadget_chips.h"
27 #include "f_mass_storage.h"
31 #define NOKIA_VERSION_NUM 0x0211
32 #define NOKIA_LONG_NAME "N900 (PC-Suite Mode)"
34 USB_GADGET_COMPOSITE_OPTIONS();
36 USB_ETHERNET_MODULE_PARAMETERS();
38 static struct fsg_module_parameters fsg_mod_data = {
42 .removable = { 1, 1, },
45 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
47 static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
52 * Number of buffers we will use.
53 * 2 is usually enough for good buffering pipeline
55 #define fsg_num_buffers CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
57 #endif /* CONFIG_USB_DEBUG */
59 FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
61 #define NOKIA_VENDOR_ID 0x0421 /* Nokia */
62 #define NOKIA_PRODUCT_ID 0x01c8 /* Nokia Gadget */
64 /* string IDs are assigned dynamically */
66 #define STRING_DESCRIPTION_IDX USB_GADGET_FIRST_AVAIL_IDX
68 static char manufacturer_nokia[] = "Nokia";
69 static const char product_nokia[] = NOKIA_LONG_NAME;
70 static const char description_nokia[] = "PC-Suite Configuration";
72 static struct usb_string strings_dev[] = {
73 [USB_GADGET_MANUFACTURER_IDX].s = manufacturer_nokia,
74 [USB_GADGET_PRODUCT_IDX].s = NOKIA_LONG_NAME,
75 [USB_GADGET_SERIAL_IDX].s = "",
76 [STRING_DESCRIPTION_IDX].s = description_nokia,
80 static struct usb_gadget_strings stringtab_dev = {
81 .language = 0x0409, /* en-us */
82 .strings = strings_dev,
85 static struct usb_gadget_strings *dev_strings[] = {
90 static struct usb_device_descriptor device_desc = {
91 .bLength = USB_DT_DEVICE_SIZE,
92 .bDescriptorType = USB_DT_DEVICE,
93 .bcdUSB = cpu_to_le16(0x0200),
94 .bDeviceClass = USB_CLASS_COMM,
95 .idVendor = cpu_to_le16(NOKIA_VENDOR_ID),
96 .idProduct = cpu_to_le16(NOKIA_PRODUCT_ID),
97 .bcdDevice = cpu_to_le16(NOKIA_VERSION_NUM),
98 /* .iManufacturer = DYNAMIC */
99 /* .iProduct = DYNAMIC */
100 .bNumConfigurations = 1,
103 /*-------------------------------------------------------------------------*/
106 MODULE_DESCRIPTION("Nokia composite gadget driver for N900");
107 MODULE_AUTHOR("Felipe Balbi");
108 MODULE_LICENSE("GPL");
110 /*-------------------------------------------------------------------------*/
111 static struct usb_function *f_acm_cfg1;
112 static struct usb_function *f_acm_cfg2;
113 static struct usb_function *f_ecm_cfg1;
114 static struct usb_function *f_ecm_cfg2;
115 static struct usb_function *f_obex1_cfg1;
116 static struct usb_function *f_obex2_cfg1;
117 static struct usb_function *f_obex1_cfg2;
118 static struct usb_function *f_obex2_cfg2;
119 static struct usb_function *f_phonet_cfg1;
120 static struct usb_function *f_phonet_cfg2;
121 static struct usb_function *f_msg_cfg1;
122 static struct usb_function *f_msg_cfg2;
125 static struct usb_configuration nokia_config_500ma_driver = {
126 .label = "Bus Powered",
127 .bConfigurationValue = 1,
128 /* .iConfiguration = DYNAMIC */
129 .bmAttributes = USB_CONFIG_ATT_ONE,
133 static struct usb_configuration nokia_config_100ma_driver = {
134 .label = "Self Powered",
135 .bConfigurationValue = 2,
136 /* .iConfiguration = DYNAMIC */
137 .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
141 static struct usb_function_instance *fi_acm;
142 static struct usb_function_instance *fi_ecm;
143 static struct usb_function_instance *fi_obex1;
144 static struct usb_function_instance *fi_obex2;
145 static struct usb_function_instance *fi_phonet;
146 static struct usb_function_instance *fi_msg;
148 static int nokia_bind_config(struct usb_configuration *c)
150 struct usb_function *f_acm;
151 struct usb_function *f_phonet = NULL;
152 struct usb_function *f_obex1 = NULL;
153 struct usb_function *f_ecm;
154 struct usb_function *f_obex2 = NULL;
155 struct usb_function *f_msg;
156 struct fsg_opts *fsg_opts;
160 int phonet_stat = -1;
162 if (!IS_ERR(fi_phonet)) {
163 f_phonet = usb_get_function(fi_phonet);
164 if (IS_ERR(f_phonet))
165 pr_debug("could not get phonet function\n");
168 if (!IS_ERR(fi_obex1)) {
169 f_obex1 = usb_get_function(fi_obex1);
171 pr_debug("could not get obex function 0\n");
174 if (!IS_ERR(fi_obex2)) {
175 f_obex2 = usb_get_function(fi_obex2);
177 pr_debug("could not get obex function 1\n");
180 f_acm = usb_get_function(fi_acm);
182 status = PTR_ERR(f_acm);
186 f_ecm = usb_get_function(fi_ecm);
188 status = PTR_ERR(f_ecm);
192 f_msg = usb_get_function(fi_msg);
194 status = PTR_ERR(f_msg);
198 if (!IS_ERR_OR_NULL(f_phonet)) {
199 phonet_stat = usb_add_function(c, f_phonet);
201 pr_debug("could not add phonet function\n");
204 if (!IS_ERR_OR_NULL(f_obex1)) {
205 obex1_stat = usb_add_function(c, f_obex1);
207 pr_debug("could not add obex function 0\n");
210 if (!IS_ERR_OR_NULL(f_obex2)) {
211 obex2_stat = usb_add_function(c, f_obex2);
213 pr_debug("could not add obex function 1\n");
216 status = usb_add_function(c, f_acm);
220 status = usb_add_function(c, f_ecm);
222 pr_debug("could not bind ecm config %d\n", status);
226 fsg_opts = fsg_opts_from_func_inst(fi_msg);
228 status = fsg_common_run_thread(fsg_opts->common);
232 status = usb_add_function(c, f_msg);
236 if (c == &nokia_config_500ma_driver) {
239 f_phonet_cfg1 = f_phonet;
240 f_obex1_cfg1 = f_obex1;
241 f_obex2_cfg1 = f_obex2;
246 f_phonet_cfg2 = f_phonet;
247 f_obex1_cfg2 = f_obex1;
248 f_obex2_cfg2 = f_obex2;
254 usb_remove_function(c, f_ecm);
256 usb_remove_function(c, f_acm);
259 usb_remove_function(c, f_obex2);
261 usb_remove_function(c, f_obex1);
263 usb_remove_function(c, f_phonet);
264 usb_put_function(f_msg);
266 usb_put_function(f_ecm);
268 usb_put_function(f_acm);
270 if (!IS_ERR_OR_NULL(f_obex2))
271 usb_put_function(f_obex2);
272 if (!IS_ERR_OR_NULL(f_obex1))
273 usb_put_function(f_obex1);
274 if (!IS_ERR_OR_NULL(f_phonet))
275 usb_put_function(f_phonet);
279 static int nokia_bind(struct usb_composite_dev *cdev)
281 struct usb_gadget *gadget = cdev->gadget;
282 struct fsg_opts *fsg_opts;
283 struct fsg_config fsg_config;
286 status = usb_string_ids_tab(cdev, strings_dev);
289 device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id;
290 device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
291 status = strings_dev[STRING_DESCRIPTION_IDX].id;
292 nokia_config_500ma_driver.iConfiguration = status;
293 nokia_config_100ma_driver.iConfiguration = status;
295 if (!gadget_supports_altsettings(gadget)) {
300 fi_phonet = usb_get_function_instance("phonet");
301 if (IS_ERR(fi_phonet))
302 pr_debug("could not find phonet function\n");
304 fi_obex1 = usb_get_function_instance("obex");
305 if (IS_ERR(fi_obex1))
306 pr_debug("could not find obex function 1\n");
308 fi_obex2 = usb_get_function_instance("obex");
309 if (IS_ERR(fi_obex2))
310 pr_debug("could not find obex function 2\n");
312 fi_acm = usb_get_function_instance("acm");
313 if (IS_ERR(fi_acm)) {
314 status = PTR_ERR(fi_acm);
318 fi_ecm = usb_get_function_instance("ecm");
319 if (IS_ERR(fi_ecm)) {
320 status = PTR_ERR(fi_ecm);
324 fi_msg = usb_get_function_instance("mass_storage");
325 if (IS_ERR(fi_msg)) {
326 status = PTR_ERR(fi_msg);
330 /* set up mass storage function */
331 fsg_config_from_params(&fsg_config, &fsg_mod_data, fsg_num_buffers);
332 fsg_config.vendor_name = "Nokia";
333 fsg_config.product_name = "N900";
335 fsg_opts = fsg_opts_from_func_inst(fi_msg);
336 fsg_opts->no_configfs = true;
338 status = fsg_common_set_num_buffers(fsg_opts->common, fsg_num_buffers);
342 status = fsg_common_set_nluns(fsg_opts->common, fsg_config.nluns);
346 status = fsg_common_set_cdev(fsg_opts->common, cdev, fsg_config.can_stall);
348 goto err_msg_set_nluns;
350 fsg_common_set_sysfs(fsg_opts->common, true);
352 status = fsg_common_create_luns(fsg_opts->common, &fsg_config);
354 goto err_msg_set_nluns;
356 fsg_common_set_inquiry_string(fsg_opts->common, fsg_config.vendor_name,
357 fsg_config.product_name);
359 /* finally register the configuration */
360 status = usb_add_config(cdev, &nokia_config_500ma_driver,
363 goto err_msg_set_cdev;
365 status = usb_add_config(cdev, &nokia_config_100ma_driver,
370 usb_composite_overwrite_options(cdev, &coverwrite);
371 dev_info(&gadget->dev, "%s\n", NOKIA_LONG_NAME);
376 usb_put_function(f_acm_cfg1);
377 if (!IS_ERR_OR_NULL(f_obex1_cfg1))
378 usb_put_function(f_obex1_cfg1);
379 if (!IS_ERR_OR_NULL(f_obex2_cfg1))
380 usb_put_function(f_obex2_cfg1);
381 if (!IS_ERR_OR_NULL(f_phonet_cfg1))
382 usb_put_function(f_phonet_cfg1);
383 usb_put_function(f_ecm_cfg1);
385 fsg_common_remove_luns(fsg_opts->common);
387 fsg_common_free_luns(fsg_opts->common);
389 fsg_common_free_buffers(fsg_opts->common);
391 usb_put_function_instance(fi_msg);
393 usb_put_function_instance(fi_ecm);
395 usb_put_function_instance(fi_acm);
397 if (!IS_ERR(fi_obex2))
398 usb_put_function_instance(fi_obex2);
399 if (!IS_ERR(fi_obex1))
400 usb_put_function_instance(fi_obex1);
401 if (!IS_ERR(fi_phonet))
402 usb_put_function_instance(fi_phonet);
407 static int nokia_unbind(struct usb_composite_dev *cdev)
409 if (!IS_ERR_OR_NULL(f_obex1_cfg2))
410 usb_put_function(f_obex1_cfg2);
411 if (!IS_ERR_OR_NULL(f_obex2_cfg2))
412 usb_put_function(f_obex2_cfg2);
413 if (!IS_ERR_OR_NULL(f_obex1_cfg1))
414 usb_put_function(f_obex1_cfg1);
415 if (!IS_ERR_OR_NULL(f_obex2_cfg1))
416 usb_put_function(f_obex2_cfg1);
417 if (!IS_ERR_OR_NULL(f_phonet_cfg1))
418 usb_put_function(f_phonet_cfg1);
419 if (!IS_ERR_OR_NULL(f_phonet_cfg2))
420 usb_put_function(f_phonet_cfg2);
421 usb_put_function(f_acm_cfg1);
422 usb_put_function(f_acm_cfg2);
423 usb_put_function(f_ecm_cfg1);
424 usb_put_function(f_ecm_cfg2);
425 usb_put_function(f_msg_cfg1);
426 usb_put_function(f_msg_cfg2);
428 usb_put_function_instance(fi_msg);
429 usb_put_function_instance(fi_ecm);
430 if (!IS_ERR(fi_obex2))
431 usb_put_function_instance(fi_obex2);
432 if (!IS_ERR(fi_obex1))
433 usb_put_function_instance(fi_obex1);
434 if (!IS_ERR(fi_phonet))
435 usb_put_function_instance(fi_phonet);
436 usb_put_function_instance(fi_acm);
441 static struct usb_composite_driver nokia_driver = {
444 .strings = dev_strings,
445 .max_speed = USB_SPEED_HIGH,
447 .unbind = nokia_unbind,
450 module_usb_composite_driver(nokia_driver);