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 
65 static char manufacturer_nokia[] = "Nokia";
66 static const char product_nokia[] = NOKIA_LONG_NAME;
67 static const char description_nokia[] = "PC-Suite Configuration";
68 
69 static 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 
76 static struct usb_gadget_strings stringtab_dev = {
77 	.language	= 0x0409,	/* en-us */
78 	.strings	= strings_dev,
79 };
80 
81 static struct usb_gadget_strings *dev_strings[] = {
82 	&stringtab_dev,
83 	NULL,
84 };
85 
86 static 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 */
101 MODULE_DESCRIPTION("Nokia composite gadget driver for N900");
102 MODULE_AUTHOR("Felipe Balbi");
103 MODULE_LICENSE("GPL");
104 
105 /*-------------------------------------------------------------------------*/
106 
107 static u8 hostaddr[ETH_ALEN];
108 
nokia_bind_config(struct usb_configuration * c)109 static 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 
136 static struct usb_configuration nokia_config_500ma_driver = {
137 	.label		= "Bus Powered",
138 	.bConfigurationValue = 1,
139 	/* .iConfiguration = DYNAMIC */
140 	.bmAttributes	= USB_CONFIG_ATT_ONE,
141 	.bMaxPower	= 250, /* 500mA */
142 };
143 
144 static struct usb_configuration nokia_config_100ma_driver = {
145 	.label		= "Self Powered",
146 	.bConfigurationValue = 2,
147 	/* .iConfiguration = DYNAMIC */
148 	.bmAttributes	= USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
149 	.bMaxPower	= 50, /* 100 mA */
150 };
151 
nokia_bind(struct usb_composite_dev * cdev)152 static int __init nokia_bind(struct usb_composite_dev *cdev)
153 {
154 	int			gcnum;
155 	struct usb_gadget	*gadget = cdev->gadget;
156 	int			status;
157 
158 	status = gphonet_setup(cdev->gadget);
159 	if (status < 0)
160 		goto err_phonet;
161 
162 	status = gserial_setup(cdev->gadget, 3);
163 	if (status < 0)
164 		goto err_serial;
165 
166 	status = gether_setup(cdev->gadget, hostaddr);
167 	if (status < 0)
168 		goto err_ether;
169 
170 	status = usb_string_id(cdev);
171 	if (status < 0)
172 		goto err_usb;
173 	strings_dev[STRING_MANUFACTURER_IDX].id = status;
174 
175 	device_desc.iManufacturer = status;
176 
177 	status = usb_string_id(cdev);
178 	if (status < 0)
179 		goto err_usb;
180 	strings_dev[STRING_PRODUCT_IDX].id = status;
181 
182 	device_desc.iProduct = status;
183 
184 	/* config description */
185 	status = usb_string_id(cdev);
186 	if (status < 0)
187 		goto err_usb;
188 	strings_dev[STRING_DESCRIPTION_IDX].id = status;
189 
190 	nokia_config_500ma_driver.iConfiguration = status;
191 	nokia_config_100ma_driver.iConfiguration = status;
192 
193 	/* set up other descriptors */
194 	gcnum = usb_gadget_controller_number(gadget);
195 	if (gcnum >= 0)
196 		device_desc.bcdDevice = cpu_to_le16(NOKIA_VERSION_NUM);
197 	else {
198 		/* this should only work with hw that supports altsettings
199 		 * and several endpoints, anything else, panic.
200 		 */
201 		pr_err("nokia_bind: controller '%s' not recognized\n",
202 			gadget->name);
203 		goto err_usb;
204 	}
205 
206 	/* finally register the configuration */
207 	status = usb_add_config(cdev, &nokia_config_500ma_driver,
208 			nokia_bind_config);
209 	if (status < 0)
210 		goto err_usb;
211 
212 	status = usb_add_config(cdev, &nokia_config_100ma_driver,
213 			nokia_bind_config);
214 	if (status < 0)
215 		goto err_usb;
216 
217 	dev_info(&gadget->dev, "%s\n", NOKIA_LONG_NAME);
218 
219 	return 0;
220 
221 err_usb:
222 	gether_cleanup();
223 err_ether:
224 	gserial_cleanup();
225 err_serial:
226 	gphonet_cleanup();
227 err_phonet:
228 	return status;
229 }
230 
nokia_unbind(struct usb_composite_dev * cdev)231 static 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 
240 static struct usb_composite_driver nokia_driver = {
241 	.name		= "g_nokia",
242 	.dev		= &device_desc,
243 	.strings	= dev_strings,
244 	.unbind		= __exit_p(nokia_unbind),
245 };
246 
nokia_init(void)247 static int __init nokia_init(void)
248 {
249 	return usb_composite_probe(&nokia_driver, nokia_bind);
250 }
251 module_init(nokia_init);
252 
nokia_cleanup(void)253 static void __exit nokia_cleanup(void)
254 {
255 	usb_composite_unregister(&nokia_driver);
256 }
257 module_exit(nokia_cleanup);
258 
259