GNU Linux-libre 4.19.304-gnu1
[releases.git] / drivers / usb / gadget / legacy / nokia.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * nokia.c -- Nokia Composite Gadget Driver
4  *
5  * Copyright (C) 2008-2010 Nokia Corporation
6  * Contact: Felipe Balbi <felipe.balbi@nokia.com>
7  *
8  * This gadget driver borrows from serial.c which is:
9  *
10  * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
11  * Copyright (C) 2008 by David Brownell
12  * Copyright (C) 2008 by Nokia Corporation
13  */
14
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/device.h>
18
19 #include "u_serial.h"
20 #include "u_ether.h"
21 #include "u_phonet.h"
22 #include "u_ecm.h"
23 #include "f_mass_storage.h"
24
25 /* Defines */
26
27 #define NOKIA_VERSION_NUM               0x0211
28 #define NOKIA_LONG_NAME                 "N900 (PC-Suite Mode)"
29
30 USB_GADGET_COMPOSITE_OPTIONS();
31
32 USB_ETHERNET_MODULE_PARAMETERS();
33
34 static struct fsg_module_parameters fsg_mod_data = {
35         .stall = 0,
36         .luns = 2,
37         .removable_count = 2,
38         .removable = { 1, 1, },
39 };
40
41 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
42
43 static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
44
45 #else
46
47 /*
48  * Number of buffers we will use.
49  * 2 is usually enough for good buffering pipeline
50  */
51 #define fsg_num_buffers CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
52
53 #endif /* CONFIG_USB_DEBUG */
54
55 FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
56
57 #define NOKIA_VENDOR_ID                 0x0421  /* Nokia */
58 #define NOKIA_PRODUCT_ID                0x01c8  /* Nokia Gadget */
59
60 /* string IDs are assigned dynamically */
61
62 #define STRING_DESCRIPTION_IDX          USB_GADGET_FIRST_AVAIL_IDX
63
64 static char manufacturer_nokia[] = "Nokia";
65 static const char product_nokia[] = NOKIA_LONG_NAME;
66 static const char description_nokia[] = "PC-Suite Configuration";
67
68 static struct usb_string strings_dev[] = {
69         [USB_GADGET_MANUFACTURER_IDX].s = manufacturer_nokia,
70         [USB_GADGET_PRODUCT_IDX].s = NOKIA_LONG_NAME,
71         [USB_GADGET_SERIAL_IDX].s = "",
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 = DYNAMIC */
90         .bDeviceClass           = USB_CLASS_COMM,
91         .idVendor               = cpu_to_le16(NOKIA_VENDOR_ID),
92         .idProduct              = cpu_to_le16(NOKIA_PRODUCT_ID),
93         .bcdDevice              = cpu_to_le16(NOKIA_VERSION_NUM),
94         /* .iManufacturer = DYNAMIC */
95         /* .iProduct = DYNAMIC */
96         .bNumConfigurations =   1,
97 };
98
99 /*-------------------------------------------------------------------------*/
100
101 /* Module */
102 MODULE_DESCRIPTION("Nokia composite gadget driver for N900");
103 MODULE_AUTHOR("Felipe Balbi");
104 MODULE_LICENSE("GPL");
105
106 /*-------------------------------------------------------------------------*/
107 static struct usb_function *f_acm_cfg1;
108 static struct usb_function *f_acm_cfg2;
109 static struct usb_function *f_ecm_cfg1;
110 static struct usb_function *f_ecm_cfg2;
111 static struct usb_function *f_obex1_cfg1;
112 static struct usb_function *f_obex2_cfg1;
113 static struct usb_function *f_obex1_cfg2;
114 static struct usb_function *f_obex2_cfg2;
115 static struct usb_function *f_phonet_cfg1;
116 static struct usb_function *f_phonet_cfg2;
117 static struct usb_function *f_msg_cfg1;
118 static struct usb_function *f_msg_cfg2;
119
120
121 static struct usb_configuration nokia_config_500ma_driver = {
122         .label          = "Bus Powered",
123         .bConfigurationValue = 1,
124         /* .iConfiguration = DYNAMIC */
125         .bmAttributes   = USB_CONFIG_ATT_ONE,
126         .MaxPower       = 500,
127 };
128
129 static struct usb_configuration nokia_config_100ma_driver = {
130         .label          = "Self Powered",
131         .bConfigurationValue = 2,
132         /* .iConfiguration = DYNAMIC */
133         .bmAttributes   = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
134         .MaxPower       = 100,
135 };
136
137 static struct usb_function_instance *fi_acm;
138 static struct usb_function_instance *fi_ecm;
139 static struct usb_function_instance *fi_obex1;
140 static struct usb_function_instance *fi_obex2;
141 static struct usb_function_instance *fi_phonet;
142 static struct usb_function_instance *fi_msg;
143
144 static int nokia_bind_config(struct usb_configuration *c)
145 {
146         struct usb_function *f_acm;
147         struct usb_function *f_phonet = NULL;
148         struct usb_function *f_obex1 = NULL;
149         struct usb_function *f_ecm;
150         struct usb_function *f_obex2 = NULL;
151         struct usb_function *f_msg;
152         int status = 0;
153         int obex1_stat = -1;
154         int obex2_stat = -1;
155         int phonet_stat = -1;
156
157         if (!IS_ERR(fi_phonet)) {
158                 f_phonet = usb_get_function(fi_phonet);
159                 if (IS_ERR(f_phonet))
160                         pr_debug("could not get phonet function\n");
161         }
162
163         if (!IS_ERR(fi_obex1)) {
164                 f_obex1 = usb_get_function(fi_obex1);
165                 if (IS_ERR(f_obex1))
166                         pr_debug("could not get obex function 0\n");
167         }
168
169         if (!IS_ERR(fi_obex2)) {
170                 f_obex2 = usb_get_function(fi_obex2);
171                 if (IS_ERR(f_obex2))
172                         pr_debug("could not get obex function 1\n");
173         }
174
175         f_acm = usb_get_function(fi_acm);
176         if (IS_ERR(f_acm)) {
177                 status = PTR_ERR(f_acm);
178                 goto err_get_acm;
179         }
180
181         f_ecm = usb_get_function(fi_ecm);
182         if (IS_ERR(f_ecm)) {
183                 status = PTR_ERR(f_ecm);
184                 goto err_get_ecm;
185         }
186
187         f_msg = usb_get_function(fi_msg);
188         if (IS_ERR(f_msg)) {
189                 status = PTR_ERR(f_msg);
190                 goto err_get_msg;
191         }
192
193         if (!IS_ERR_OR_NULL(f_phonet)) {
194                 phonet_stat = usb_add_function(c, f_phonet);
195                 if (phonet_stat)
196                         pr_debug("could not add phonet function\n");
197         }
198
199         if (!IS_ERR_OR_NULL(f_obex1)) {
200                 obex1_stat = usb_add_function(c, f_obex1);
201                 if (obex1_stat)
202                         pr_debug("could not add obex function 0\n");
203         }
204
205         if (!IS_ERR_OR_NULL(f_obex2)) {
206                 obex2_stat = usb_add_function(c, f_obex2);
207                 if (obex2_stat)
208                         pr_debug("could not add obex function 1\n");
209         }
210
211         status = usb_add_function(c, f_acm);
212         if (status)
213                 goto err_conf;
214
215         status = usb_add_function(c, f_ecm);
216         if (status) {
217                 pr_debug("could not bind ecm config %d\n", status);
218                 goto err_ecm;
219         }
220
221         status = usb_add_function(c, f_msg);
222         if (status)
223                 goto err_msg;
224
225         if (c == &nokia_config_500ma_driver) {
226                 f_acm_cfg1 = f_acm;
227                 f_ecm_cfg1 = f_ecm;
228                 f_phonet_cfg1 = f_phonet;
229                 f_obex1_cfg1 = f_obex1;
230                 f_obex2_cfg1 = f_obex2;
231                 f_msg_cfg1 = f_msg;
232         } else {
233                 f_acm_cfg2 = f_acm;
234                 f_ecm_cfg2 = f_ecm;
235                 f_phonet_cfg2 = f_phonet;
236                 f_obex1_cfg2 = f_obex1;
237                 f_obex2_cfg2 = f_obex2;
238                 f_msg_cfg2 = f_msg;
239         }
240
241         return status;
242 err_msg:
243         usb_remove_function(c, f_ecm);
244 err_ecm:
245         usb_remove_function(c, f_acm);
246 err_conf:
247         if (!obex2_stat)
248                 usb_remove_function(c, f_obex2);
249         if (!obex1_stat)
250                 usb_remove_function(c, f_obex1);
251         if (!phonet_stat)
252                 usb_remove_function(c, f_phonet);
253         usb_put_function(f_msg);
254 err_get_msg:
255         usb_put_function(f_ecm);
256 err_get_ecm:
257         usb_put_function(f_acm);
258 err_get_acm:
259         if (!IS_ERR_OR_NULL(f_obex2))
260                 usb_put_function(f_obex2);
261         if (!IS_ERR_OR_NULL(f_obex1))
262                 usb_put_function(f_obex1);
263         if (!IS_ERR_OR_NULL(f_phonet))
264                 usb_put_function(f_phonet);
265         return status;
266 }
267
268 static int nokia_bind(struct usb_composite_dev *cdev)
269 {
270         struct usb_gadget       *gadget = cdev->gadget;
271         struct fsg_opts         *fsg_opts;
272         struct fsg_config       fsg_config;
273         int                     status;
274
275         status = usb_string_ids_tab(cdev, strings_dev);
276         if (status < 0)
277                 goto err_usb;
278         device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id;
279         device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
280         status = strings_dev[STRING_DESCRIPTION_IDX].id;
281         nokia_config_500ma_driver.iConfiguration = status;
282         nokia_config_100ma_driver.iConfiguration = status;
283
284         if (!gadget_is_altset_supported(gadget)) {
285                 status = -ENODEV;
286                 goto err_usb;
287         }
288
289         fi_phonet = usb_get_function_instance("phonet");
290         if (IS_ERR(fi_phonet))
291                 pr_debug("could not find phonet function\n");
292
293         fi_obex1 = usb_get_function_instance("obex");
294         if (IS_ERR(fi_obex1))
295                 pr_debug("could not find obex function 1\n");
296
297         fi_obex2 = usb_get_function_instance("obex");
298         if (IS_ERR(fi_obex2))
299                 pr_debug("could not find obex function 2\n");
300
301         fi_acm = usb_get_function_instance("acm");
302         if (IS_ERR(fi_acm)) {
303                 status = PTR_ERR(fi_acm);
304                 goto err_obex2_inst;
305         }
306
307         fi_ecm = usb_get_function_instance("ecm");
308         if (IS_ERR(fi_ecm)) {
309                 status = PTR_ERR(fi_ecm);
310                 goto err_acm_inst;
311         }
312
313         fi_msg = usb_get_function_instance("mass_storage");
314         if (IS_ERR(fi_msg)) {
315                 status = PTR_ERR(fi_msg);
316                 goto err_ecm_inst;
317         }
318
319         /* set up mass storage function */
320         fsg_config_from_params(&fsg_config, &fsg_mod_data, fsg_num_buffers);
321         fsg_config.vendor_name = "Nokia";
322         fsg_config.product_name = "N900";
323
324         fsg_opts = fsg_opts_from_func_inst(fi_msg);
325         fsg_opts->no_configfs = true;
326
327         status = fsg_common_set_num_buffers(fsg_opts->common, fsg_num_buffers);
328         if (status)
329                 goto err_msg_inst;
330
331         status = fsg_common_set_cdev(fsg_opts->common, cdev, fsg_config.can_stall);
332         if (status)
333                 goto err_msg_buf;
334
335         fsg_common_set_sysfs(fsg_opts->common, true);
336
337         status = fsg_common_create_luns(fsg_opts->common, &fsg_config);
338         if (status)
339                 goto err_msg_buf;
340
341         fsg_common_set_inquiry_string(fsg_opts->common, fsg_config.vendor_name,
342                                       fsg_config.product_name);
343
344         /* finally register the configuration */
345         status = usb_add_config(cdev, &nokia_config_500ma_driver,
346                         nokia_bind_config);
347         if (status < 0)
348                 goto err_msg_luns;
349
350         status = usb_add_config(cdev, &nokia_config_100ma_driver,
351                         nokia_bind_config);
352         if (status < 0)
353                 goto err_put_cfg1;
354
355         usb_composite_overwrite_options(cdev, &coverwrite);
356         dev_info(&gadget->dev, "%s\n", NOKIA_LONG_NAME);
357
358         return 0;
359
360 err_put_cfg1:
361         usb_put_function(f_acm_cfg1);
362         if (!IS_ERR_OR_NULL(f_obex1_cfg1))
363                 usb_put_function(f_obex1_cfg1);
364         if (!IS_ERR_OR_NULL(f_obex2_cfg1))
365                 usb_put_function(f_obex2_cfg1);
366         if (!IS_ERR_OR_NULL(f_phonet_cfg1))
367                 usb_put_function(f_phonet_cfg1);
368         usb_put_function(f_ecm_cfg1);
369 err_msg_luns:
370         fsg_common_remove_luns(fsg_opts->common);
371 err_msg_buf:
372         fsg_common_free_buffers(fsg_opts->common);
373 err_msg_inst:
374         usb_put_function_instance(fi_msg);
375 err_ecm_inst:
376         usb_put_function_instance(fi_ecm);
377 err_acm_inst:
378         usb_put_function_instance(fi_acm);
379 err_obex2_inst:
380         if (!IS_ERR(fi_obex2))
381                 usb_put_function_instance(fi_obex2);
382         if (!IS_ERR(fi_obex1))
383                 usb_put_function_instance(fi_obex1);
384         if (!IS_ERR(fi_phonet))
385                 usb_put_function_instance(fi_phonet);
386 err_usb:
387         return status;
388 }
389
390 static int nokia_unbind(struct usb_composite_dev *cdev)
391 {
392         if (!IS_ERR_OR_NULL(f_obex1_cfg2))
393                 usb_put_function(f_obex1_cfg2);
394         if (!IS_ERR_OR_NULL(f_obex2_cfg2))
395                 usb_put_function(f_obex2_cfg2);
396         if (!IS_ERR_OR_NULL(f_obex1_cfg1))
397                 usb_put_function(f_obex1_cfg1);
398         if (!IS_ERR_OR_NULL(f_obex2_cfg1))
399                 usb_put_function(f_obex2_cfg1);
400         if (!IS_ERR_OR_NULL(f_phonet_cfg1))
401                 usb_put_function(f_phonet_cfg1);
402         if (!IS_ERR_OR_NULL(f_phonet_cfg2))
403                 usb_put_function(f_phonet_cfg2);
404         usb_put_function(f_acm_cfg1);
405         usb_put_function(f_acm_cfg2);
406         usb_put_function(f_ecm_cfg1);
407         usb_put_function(f_ecm_cfg2);
408         usb_put_function(f_msg_cfg1);
409         usb_put_function(f_msg_cfg2);
410
411         usb_put_function_instance(fi_msg);
412         usb_put_function_instance(fi_ecm);
413         if (!IS_ERR(fi_obex2))
414                 usb_put_function_instance(fi_obex2);
415         if (!IS_ERR(fi_obex1))
416                 usb_put_function_instance(fi_obex1);
417         if (!IS_ERR(fi_phonet))
418                 usb_put_function_instance(fi_phonet);
419         usb_put_function_instance(fi_acm);
420
421         return 0;
422 }
423
424 static struct usb_composite_driver nokia_driver = {
425         .name           = "g_nokia",
426         .dev            = &device_desc,
427         .strings        = dev_strings,
428         .max_speed      = USB_SPEED_HIGH,
429         .bind           = nokia_bind,
430         .unbind         = nokia_unbind,
431 };
432
433 module_usb_composite_driver(nokia_driver);