aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/gadget/Kconfig10
-rw-r--r--drivers/usb/gadget/Makefile2
-rw-r--r--drivers/usb/gadget/nokia.c259
3 files changed, 271 insertions, 0 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index ee411206c699..7460cd797f45 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -812,6 +812,16 @@ config USB_CDC_COMPOSITE
812 Say "y" to link the driver statically, or "m" to build a 812 Say "y" to link the driver statically, or "m" to build a
813 dynamically linked module. 813 dynamically linked module.
814 814
815config USB_G_NOKIA
816 tristate "Nokia composite gadget"
817 depends on PHONET
818 help
819 The Nokia composite gadget provides support for acm, obex
820 and phonet in only one composite gadget driver.
821
822 It's only really useful for N900 hardware. If you're building
823 a kernel for N900, say Y or M here. If unsure, say N.
824
815config USB_G_MULTI 825config USB_G_MULTI
816 tristate "Multifunction Composite Gadget (EXPERIMENTAL)" 826 tristate "Multifunction Composite Gadget (EXPERIMENTAL)"
817 depends on BLOCK && NET 827 depends on BLOCK && NET
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 2e2c047262b7..43b51da8d727 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -43,6 +43,7 @@ g_mass_storage-objs := mass_storage.o
43g_printer-objs := printer.o 43g_printer-objs := printer.o
44g_cdc-objs := cdc2.o 44g_cdc-objs := cdc2.o
45g_multi-objs := multi.o 45g_multi-objs := multi.o
46g_nokia-objs := nokia.o
46 47
47obj-$(CONFIG_USB_ZERO) += g_zero.o 48obj-$(CONFIG_USB_ZERO) += g_zero.o
48obj-$(CONFIG_USB_AUDIO) += g_audio.o 49obj-$(CONFIG_USB_AUDIO) += g_audio.o
@@ -55,4 +56,5 @@ obj-$(CONFIG_USB_G_PRINTER) += g_printer.o
55obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o 56obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o
56obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o 57obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o
57obj-$(CONFIG_USB_G_MULTI) += g_multi.o 58obj-$(CONFIG_USB_G_MULTI) += g_multi.o
59obj-$(CONFIG_USB_G_NOKIA) += g_nokia.o
58 60
diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c
new file mode 100644
index 000000000000..7d6b66a85724
--- /dev/null
+++ b/drivers/usb/gadget/nokia.c
@@ -0,0 +1,259 @@
1/*
2 * nokia.c -- Nokia Composite Gadget Driver
3 *
4 * Copyright (C) 2008-2010 Nokia Corporation
5 * Contact: Felipe Balbi <felipe.balbi@nokia.com>
6 *
7 * This gadget driver borrows from serial.c which is:
8 *
9 * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
10 * Copyright (C) 2008 by David Brownell
11 * Copyright (C) 2008 by Nokia Corporation
12 *
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.
16 */
17
18#include <linux/kernel.h>
19#include <linux/utsname.h>
20#include <linux/device.h>
21
22#include "u_serial.h"
23#include "u_ether.h"
24#include "u_phonet.h"
25#include "gadget_chips.h"
26
27/* Defines */
28
29#define NOKIA_VERSION_NUM 0x0211
30#define NOKIA_LONG_NAME "N900 (PC-Suite Mode)"
31
32/*-------------------------------------------------------------------------*/
33
34/*
35 * Kbuild is not very cooperative with respect to linking separately
36 * compiled library objects into one module. So for now we won't use
37 * separate compilation ... ensuring init/exit sections work to shrink
38 * the runtime footprint, and giving us at least some parts of what
39 * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
40 */
41#include "composite.c"
42#include "usbstring.c"
43#include "config.c"
44#include "epautoconf.c"
45
46#include "u_serial.c"
47#include "f_acm.c"
48#include "f_ecm.c"
49#include "f_obex.c"
50#include "f_serial.c"
51#include "f_phonet.c"
52#include "u_ether.c"
53
54/*-------------------------------------------------------------------------*/
55
56#define NOKIA_VENDOR_ID 0x0421 /* Nokia */
57#define NOKIA_PRODUCT_ID 0x01c8 /* Nokia Gadget */
58
59/* string IDs are assigned dynamically */
60
61#define STRING_MANUFACTURER_IDX 0
62#define STRING_PRODUCT_IDX 1
63#define STRING_DESCRIPTION_IDX 2
64
65static char manufacturer_nokia[] = "Nokia";
66static const char product_nokia[] = NOKIA_LONG_NAME;
67static const char description_nokia[] = "PC-Suite Configuration";
68
69static struct usb_string strings_dev[] = {
70 [STRING_MANUFACTURER_IDX].s = manufacturer_nokia,
71 [STRING_PRODUCT_IDX].s = NOKIA_LONG_NAME,
72 [STRING_DESCRIPTION_IDX].s = description_nokia,
73 { } /* end of list */
74};
75
76static struct usb_gadget_strings stringtab_dev = {
77 .language = 0x0409, /* en-us */
78 .strings = strings_dev,
79};
80
81static struct usb_gadget_strings *dev_strings[] = {
82 &stringtab_dev,
83 NULL,
84};
85
86static struct usb_device_descriptor device_desc = {
87 .bLength = USB_DT_DEVICE_SIZE,
88 .bDescriptorType = USB_DT_DEVICE,
89 .bcdUSB = __constant_cpu_to_le16(0x0200),
90 .bDeviceClass = USB_CLASS_COMM,
91 .idVendor = __constant_cpu_to_le16(NOKIA_VENDOR_ID),
92 .idProduct = __constant_cpu_to_le16(NOKIA_PRODUCT_ID),
93 /* .iManufacturer = DYNAMIC */
94 /* .iProduct = DYNAMIC */
95 .bNumConfigurations = 1,
96};
97
98/*-------------------------------------------------------------------------*/
99
100/* Module */
101MODULE_DESCRIPTION("Nokia composite gadget driver for N900");
102MODULE_AUTHOR("Felipe Balbi");
103MODULE_LICENSE("GPL");
104
105/*-------------------------------------------------------------------------*/
106
107static u8 hostaddr[ETH_ALEN];
108
109static int __init nokia_bind_config(struct usb_configuration *c)
110{
111 int status = 0;
112
113 status = phonet_bind_config(c);
114 if (status)
115 printk(KERN_DEBUG "could not bind phonet config\n");
116
117 status = obex_bind_config(c, 0);
118 if (status)
119 printk(KERN_DEBUG "could not bind obex config %d\n", 0);
120
121 status = obex_bind_config(c, 1);
122 if (status)
123 printk(KERN_DEBUG "could not bind obex config %d\n", 0);
124
125 status = acm_bind_config(c, 2);
126 if (status)
127 printk(KERN_DEBUG "could not bind acm config\n");
128
129 status = ecm_bind_config(c, hostaddr);
130 if (status)
131 printk(KERN_DEBUG "could not bind ecm config\n");
132
133 return status;
134}
135
136static struct usb_configuration nokia_config_500ma_driver = {
137 .label = "Bus Powered",
138 .bind = nokia_bind_config,
139 .bConfigurationValue = 1,
140 /* .iConfiguration = DYNAMIC */
141 .bmAttributes = USB_CONFIG_ATT_ONE,
142 .bMaxPower = 250, /* 500mA */
143};
144
145static struct usb_configuration nokia_config_100ma_driver = {
146 .label = "Self Powered",
147 .bind = nokia_bind_config,
148 .bConfigurationValue = 2,
149 /* .iConfiguration = DYNAMIC */
150 .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
151 .bMaxPower = 50, /* 100 mA */
152};
153
154static int __init nokia_bind(struct usb_composite_dev *cdev)
155{
156 int gcnum;
157 struct usb_gadget *gadget = cdev->gadget;
158 int status;
159
160 status = gphonet_setup(cdev->gadget);
161 if (status < 0)
162 goto err_phonet;
163
164 status = gserial_setup(cdev->gadget, 3);
165 if (status < 0)
166 goto err_serial;
167
168 status = gether_setup(cdev->gadget, hostaddr);
169 if (status < 0)
170 goto err_ether;
171
172 status = usb_string_id(cdev);
173 if (status < 0)
174 goto err_usb;
175 strings_dev[STRING_MANUFACTURER_IDX].id = status;
176
177 device_desc.iManufacturer = status;
178
179 status = usb_string_id(cdev);
180 if (status < 0)
181 goto err_usb;
182 strings_dev[STRING_PRODUCT_IDX].id = status;
183
184 device_desc.iProduct = status;
185
186 /* config description */
187 status = usb_string_id(cdev);
188 if (status < 0)
189 goto err_usb;
190 strings_dev[STRING_DESCRIPTION_IDX].id = status;
191
192 nokia_config_500ma_driver.iConfiguration = status;
193 nokia_config_100ma_driver.iConfiguration = status;
194
195 /* set up other descriptors */
196 gcnum = usb_gadget_controller_number(gadget);
197 if (gcnum >= 0)
198 device_desc.bcdDevice = cpu_to_le16(NOKIA_VERSION_NUM);
199 else {
200 /* this should only work with hw that supports altsettings
201 * and several endpoints, anything else, panic.
202 */
203 pr_err("nokia_bind: controller '%s' not recognized\n",
204 gadget->name);
205 goto err_usb;
206 }
207
208 /* finaly register the configuration */
209 status = usb_add_config(cdev, &nokia_config_500ma_driver);
210 if (status < 0)
211 goto err_usb;
212
213 status = usb_add_config(cdev, &nokia_config_100ma_driver);
214 if (status < 0)
215 goto err_usb;
216
217 dev_info(&gadget->dev, "%s\n", NOKIA_LONG_NAME);
218
219 return 0;
220
221err_usb:
222 gether_cleanup();
223err_ether:
224 gserial_cleanup();
225err_serial:
226 gphonet_cleanup();
227err_phonet:
228 return status;
229}
230
231static int __exit nokia_unbind(struct usb_composite_dev *cdev)
232{
233 gphonet_cleanup();
234 gserial_cleanup();
235 gether_cleanup();
236
237 return 0;
238}
239
240static struct usb_composite_driver nokia_driver = {
241 .name = "g_nokia",
242 .dev = &device_desc,
243 .strings = dev_strings,
244 .bind = nokia_bind,
245 .unbind = __exit_p(nokia_unbind),
246};
247
248static int __init nokia_init(void)
249{
250 return usb_composite_register(&nokia_driver);
251}
252module_init(nokia_init);
253
254static void __exit nokia_cleanup(void)
255{
256 usb_composite_unregister(&nokia_driver);
257}
258module_exit(nokia_cleanup);
259