Commit | Line | Data |
---|---|---|
6fa3eb70 S |
1 | /* |
2 | * Gadget Driver for Android | |
3 | * | |
4 | * Copyright (C) 2008 Google, Inc. | |
5 | * Author: Mike Lockwood <lockwood@android.com> | |
6 | * Benoit Goby <benoit@android.com> | |
7 | * | |
8 | * This software is licensed under the terms of the GNU General Public | |
9 | * License version 2, as published by the Free Software Foundation, and | |
10 | * may be copied, distributed, and modified under those terms. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | */ | |
18 | #ifdef pr_fmt | |
19 | #undef pr_fmt | |
20 | #endif | |
21 | #define pr_fmt(fmt) "["KBUILD_MODNAME"]" fmt | |
22 | ||
23 | #include <linux/init.h> | |
24 | #include <linux/module.h> | |
25 | #include <linux/fs.h> | |
26 | #include <linux/delay.h> | |
27 | #include <linux/kernel.h> | |
28 | #include <linux/utsname.h> | |
29 | #include <linux/platform_device.h> | |
30 | ||
31 | #include <linux/usb/ch9.h> | |
32 | #include <linux/usb/composite.h> | |
33 | #include <linux/usb/gadget.h> | |
34 | #include <linux/printk.h> | |
35 | ||
36 | /* Add for HW/SW connect */ | |
37 | #include <linux/musb/mtk_musb.h> | |
38 | /* Add for HW/SW connect */ | |
39 | ||
40 | #include "gadget_chips.h" | |
41 | ||
42 | #include "f_fs.c" | |
43 | #include "f_audio_source.c" | |
44 | #include "f_mass_storage.c" | |
45 | #include "f_adb.c" | |
46 | #include "f_mtp.c" | |
47 | #include "f_accessory.c" | |
48 | #define USB_ETH_RNDIS y | |
49 | #include "f_rndis.c" | |
50 | #include "rndis.c" | |
51 | #include "f_ecm.c" | |
52 | #include "f_eem.c" | |
53 | #include "u_ether.c" | |
54 | ||
55 | #ifdef CONFIG_EVDO_DT_SUPPORT | |
56 | #include <mach/viatel_rawbulk.h> | |
57 | int rawbulk_bind_config(struct usb_configuration *c, int transfer_id); | |
58 | int rawbulk_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl); | |
59 | #endif | |
60 | ||
61 | MODULE_AUTHOR("Mike Lockwood"); | |
62 | MODULE_DESCRIPTION("Android Composite USB Driver"); | |
63 | MODULE_LICENSE("GPL"); | |
64 | MODULE_VERSION("1.0"); | |
65 | ||
66 | static const char longname[] = "Gadget Android"; | |
67 | ||
68 | /* Default vendor and product IDs, overridden by userspace */ | |
69 | #define VENDOR_ID 0x0BB4 | |
70 | #define PRODUCT_ID 0x0001 | |
71 | ||
72 | /* Default manufacturer and product string , overridden by userspace */ | |
73 | #define MANUFACTURER_STRING "MediaTek" | |
74 | #define PRODUCT_STRING "MT65xx Android Phone" | |
75 | ||
76 | ||
77 | //#define USB_LOG "USB" | |
78 | ||
79 | struct android_usb_function { | |
80 | char *name; | |
81 | void *config; | |
82 | ||
83 | struct device *dev; | |
84 | char *dev_name; | |
85 | struct device_attribute **attributes; | |
86 | ||
87 | /* for android_dev.enabled_functions */ | |
88 | struct list_head enabled_list; | |
89 | ||
90 | /* Optional: initialization during gadget bind */ | |
91 | int (*init)(struct android_usb_function *, struct usb_composite_dev *); | |
92 | /* Optional: cleanup during gadget unbind */ | |
93 | void (*cleanup)(struct android_usb_function *); | |
94 | /* Optional: called when the function is added the list of | |
95 | * enabled functions */ | |
96 | void (*enable)(struct android_usb_function *); | |
97 | /* Optional: called when it is removed */ | |
98 | void (*disable)(struct android_usb_function *); | |
99 | ||
100 | int (*bind_config)(struct android_usb_function *, | |
101 | struct usb_configuration *); | |
102 | ||
103 | /* Optional: called when the configuration is removed */ | |
104 | void (*unbind_config)(struct android_usb_function *, | |
105 | struct usb_configuration *); | |
106 | /* Optional: handle ctrl requests before the device is configured */ | |
107 | int (*ctrlrequest)(struct android_usb_function *, | |
108 | struct usb_composite_dev *, | |
109 | const struct usb_ctrlrequest *); | |
110 | }; | |
111 | ||
112 | struct android_dev { | |
113 | struct android_usb_function **functions; | |
114 | struct list_head enabled_functions; | |
115 | struct usb_composite_dev *cdev; | |
116 | struct device *dev; | |
117 | ||
118 | bool enabled; | |
119 | int disable_depth; | |
120 | struct mutex mutex; | |
121 | bool connected; | |
122 | bool sw_connected; | |
123 | struct work_struct work; | |
124 | char ffs_aliases[256]; | |
125 | int rezero_cmd; | |
126 | }; | |
127 | ||
128 | static struct class *android_class; | |
129 | static struct android_dev *_android_dev; | |
130 | static int android_bind_config(struct usb_configuration *c); | |
131 | static void android_unbind_config(struct usb_configuration *c); | |
132 | static int android_setup_config(struct usb_configuration *c, const struct usb_ctrlrequest *ctrl); | |
133 | ||
134 | /* string IDs are assigned dynamically */ | |
135 | #define STRING_MANUFACTURER_IDX 0 | |
136 | #define STRING_PRODUCT_IDX 1 | |
137 | #define STRING_SERIAL_IDX 2 | |
138 | ||
139 | static char manufacturer_string[256]; | |
140 | static char product_string[256]; | |
141 | static char serial_string[256]; | |
142 | ||
143 | /* String Table */ | |
144 | static struct usb_string strings_dev[] = { | |
145 | [STRING_MANUFACTURER_IDX].s = manufacturer_string, | |
146 | [STRING_PRODUCT_IDX].s = product_string, | |
147 | [STRING_SERIAL_IDX].s = serial_string, | |
148 | { } /* end of list */ | |
149 | }; | |
150 | ||
151 | static struct usb_gadget_strings stringtab_dev = { | |
152 | .language = 0x0409, /* en-us */ | |
153 | .strings = strings_dev, | |
154 | }; | |
155 | ||
156 | static struct usb_gadget_strings *dev_strings[] = { | |
157 | &stringtab_dev, | |
158 | NULL, | |
159 | }; | |
160 | ||
161 | static struct usb_device_descriptor device_desc = { | |
162 | .bLength = sizeof(device_desc), | |
163 | .bDescriptorType = USB_DT_DEVICE, | |
164 | #ifdef CONFIG_USB_MU3D_DRV | |
165 | .bcdUSB = __constant_cpu_to_le16(0x0300), | |
166 | #else | |
167 | .bcdUSB = __constant_cpu_to_le16(0x0200), | |
168 | #endif | |
169 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | |
170 | .idVendor = __constant_cpu_to_le16(VENDOR_ID), | |
171 | .idProduct = __constant_cpu_to_le16(PRODUCT_ID), | |
172 | .bcdDevice = __constant_cpu_to_le16(0xffff), | |
173 | .bNumConfigurations = 1, | |
174 | }; | |
175 | ||
176 | static struct usb_configuration android_config_driver = { | |
177 | .label = "android", | |
178 | .unbind = android_unbind_config, | |
179 | .setup = android_setup_config, | |
180 | .bConfigurationValue = 1, | |
181 | #ifdef CONFIG_USBIF_COMPLIANCE | |
182 | // USBIF, do we need to set bus powered | |
183 | .bmAttributes = USB_CONFIG_ATT_ONE, | |
184 | //.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, | |
185 | #else | |
186 | .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, | |
187 | #endif | |
188 | #ifdef CONFIG_USB_MU3D_DRV | |
189 | .MaxPower = 192, /* Only consume 192ma for passing USB30CV Descriptor Test [USB3.0 devices]*/ | |
190 | #else | |
191 | .MaxPower = 500, /* 500ma */ | |
192 | #endif | |
193 | }; | |
194 | ||
195 | static void android_work(struct work_struct *data) | |
196 | { | |
197 | struct android_dev *dev = container_of(data, struct android_dev, work); | |
198 | struct usb_composite_dev *cdev = dev->cdev; | |
199 | char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL }; | |
200 | char *connected[2] = { "USB_STATE=CONNECTED", NULL }; | |
201 | char *configured[2] = { "USB_STATE=CONFIGURED", NULL }; | |
202 | ||
203 | /* Add for HW/SW connect */ | |
204 | char *hwdisconnected[2] = { "USB_STATE=HWDISCONNECTED", NULL }; | |
205 | // char *hwconnected[2] = { "USB_STATE=HWCONNECTED", NULL }; | |
206 | /* Add for HW/SW connect */ | |
207 | ||
208 | char *rezero_event[2] = { "USB_STATE=REZEROCMD", NULL }; | |
209 | char *showcdrom_event[2] = { "USB_STATE=SHOWCDROMCMD", NULL }; | |
210 | ||
211 | char **uevent_envp = NULL; | |
212 | char **uevent_envp_cdrom = NULL; | |
213 | unsigned long flags; | |
214 | /* Add for HW/SW connect */ | |
215 | bool is_hwconnected = true; | |
216 | ||
217 | /* patch for ALPS00345130, if the disconnect followed by hw_disconnect, then the hw_disconnect | |
218 | will not notify the UsbDeviceManager due to that musb->g.speed == USB_SPEED_UNKNOWN*/ | |
219 | if (!cdev){ | |
220 | return ; | |
221 | } | |
222 | ||
223 | if(usb_cable_connected()) | |
224 | is_hwconnected = true; | |
225 | else | |
226 | is_hwconnected = false; | |
227 | ||
228 | pr_debug("[XLOG_INFO][USB]%s: is_hwconnected=%d \n", __func__, is_hwconnected); | |
229 | /* Add for HW/SW connect */ | |
230 | ||
231 | spin_lock_irqsave(&cdev->lock, flags); | |
232 | if (cdev->config) { | |
233 | uevent_envp = configured; | |
234 | } else if (dev->connected != dev->sw_connected) { | |
235 | uevent_envp = dev->connected ? connected : disconnected; | |
236 | } | |
237 | ||
238 | dev->sw_connected = dev->connected; | |
239 | ||
240 | if (dev->rezero_cmd == 1) { | |
241 | uevent_envp_cdrom = rezero_event; | |
242 | dev->rezero_cmd = 0; | |
243 | } else if (dev->rezero_cmd == 2) { | |
244 | uevent_envp_cdrom = showcdrom_event; | |
245 | dev->rezero_cmd = 0; | |
246 | } | |
247 | ||
248 | spin_unlock_irqrestore(&cdev->lock, flags); | |
249 | ||
250 | if (uevent_envp) { | |
251 | kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE, uevent_envp); | |
252 | pr_debug("[XLOG_INFO][USB]%s: sent uevent %s\n", __func__, uevent_envp[0]); | |
253 | } else { | |
254 | pr_debug("[XLOG_INFO][USB]%s: did not send uevent (%d %d %p)\n", __func__, | |
255 | dev->connected, dev->sw_connected, cdev->config); | |
256 | } | |
257 | ||
258 | if (!is_hwconnected) { | |
259 | kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE, hwdisconnected); | |
260 | pr_debug("[XLOG_INFO][USB]%s: sent uevent %s\n", __func__, hwdisconnected[0]); | |
261 | } | |
262 | ||
263 | if (uevent_envp_cdrom) { | |
264 | kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE, uevent_envp_cdrom); | |
265 | pr_debug("[XLOG_INFO][USB]%s: sent uevent %s\n", __func__, uevent_envp_cdrom[0]); | |
266 | } else { | |
267 | pr_debug("[XLOG_INFO][USB]%s: did not send zero uevent\n", __func__); | |
268 | } | |
269 | ||
270 | } | |
271 | ||
272 | static void android_enable(struct android_dev *dev) | |
273 | { | |
274 | struct usb_composite_dev *cdev = dev->cdev; | |
275 | ||
276 | if (WARN_ON(!dev->disable_depth)) | |
277 | return; | |
278 | ||
279 | if (--dev->disable_depth == 0) { | |
280 | usb_add_config(cdev, &android_config_driver, | |
281 | android_bind_config); | |
282 | usb_gadget_connect(cdev->gadget); | |
283 | } | |
284 | } | |
285 | ||
286 | static void android_disable(struct android_dev *dev) | |
287 | { | |
288 | struct usb_composite_dev *cdev = dev->cdev; | |
289 | ||
290 | if (dev->disable_depth++ == 0) { | |
291 | usb_gadget_disconnect(cdev->gadget); | |
292 | /* Cancel pending control requests */ | |
293 | usb_ep_dequeue(cdev->gadget->ep0, cdev->req); | |
294 | usb_remove_config(cdev, &android_config_driver); | |
295 | } | |
296 | } | |
297 | ||
298 | /*-------------------------------------------------------------------------*/ | |
299 | /* Supported functions initialization */ | |
300 | ||
301 | struct functionfs_config { | |
302 | bool opened; | |
303 | bool enabled; | |
304 | struct ffs_data *data; | |
73f8fab5 | 305 | struct android_dev *dev; |
6fa3eb70 S |
306 | }; |
307 | ||
308 | static int ffs_function_init(struct android_usb_function *f, | |
309 | struct usb_composite_dev *cdev) | |
310 | { | |
311 | f->config = kzalloc(sizeof(struct functionfs_config), GFP_KERNEL); | |
312 | if (!f->config) | |
313 | return -ENOMEM; | |
314 | ||
315 | return functionfs_init(); | |
316 | } | |
317 | ||
318 | static void ffs_function_cleanup(struct android_usb_function *f) | |
319 | { | |
320 | functionfs_cleanup(); | |
321 | kfree(f->config); | |
322 | } | |
323 | ||
324 | static void ffs_function_enable(struct android_usb_function *f) | |
325 | { | |
326 | struct android_dev *dev = _android_dev; | |
327 | struct functionfs_config *config = f->config; | |
328 | ||
329 | config->enabled = true; | |
330 | ||
331 | /* Disable the gadget until the function is ready */ | |
332 | if (!config->opened) | |
333 | android_disable(dev); | |
334 | } | |
335 | ||
336 | static void ffs_function_disable(struct android_usb_function *f) | |
337 | { | |
338 | struct android_dev *dev = _android_dev; | |
339 | struct functionfs_config *config = f->config; | |
340 | ||
341 | config->enabled = false; | |
342 | ||
343 | /* Balance the disable that was called in closed_callback */ | |
344 | if (!config->opened) | |
345 | android_enable(dev); | |
346 | } | |
347 | ||
348 | static int ffs_function_bind_config(struct android_usb_function *f, | |
349 | struct usb_configuration *c) | |
350 | { | |
351 | struct functionfs_config *config = f->config; | |
352 | return functionfs_bind_config(c->cdev, c, config->data); | |
353 | } | |
354 | ||
355 | static ssize_t | |
356 | ffs_aliases_show(struct device *pdev, struct device_attribute *attr, char *buf) | |
357 | { | |
358 | struct android_dev *dev = _android_dev; | |
359 | int ret; | |
360 | ||
361 | mutex_lock(&dev->mutex); | |
362 | ret = sprintf(buf, "%s\n", dev->ffs_aliases); | |
363 | mutex_unlock(&dev->mutex); | |
364 | ||
365 | return ret; | |
366 | } | |
367 | ||
368 | static ssize_t | |
369 | ffs_aliases_store(struct device *pdev, struct device_attribute *attr, | |
370 | const char *buf, size_t size) | |
371 | { | |
372 | struct android_dev *dev = _android_dev; | |
373 | char buff[256]; | |
374 | ||
375 | mutex_lock(&dev->mutex); | |
376 | ||
377 | if (dev->enabled) { | |
378 | mutex_unlock(&dev->mutex); | |
379 | return -EBUSY; | |
380 | } | |
381 | ||
382 | strlcpy(buff, buf, sizeof(buff)); | |
383 | strlcpy(dev->ffs_aliases, strim(buff), sizeof(dev->ffs_aliases)); | |
384 | ||
385 | mutex_unlock(&dev->mutex); | |
386 | ||
387 | return size; | |
388 | } | |
389 | ||
390 | static DEVICE_ATTR(aliases, S_IRUGO | S_IWUSR, ffs_aliases_show, | |
391 | ffs_aliases_store); | |
392 | static struct device_attribute *ffs_function_attributes[] = { | |
393 | &dev_attr_aliases, | |
394 | NULL | |
395 | }; | |
396 | ||
397 | static struct android_usb_function ffs_function = { | |
398 | .name = "ffs", | |
399 | .init = ffs_function_init, | |
400 | .enable = ffs_function_enable, | |
401 | .disable = ffs_function_disable, | |
402 | .cleanup = ffs_function_cleanup, | |
403 | .bind_config = ffs_function_bind_config, | |
404 | .attributes = ffs_function_attributes, | |
405 | }; | |
406 | ||
407 | static int functionfs_ready_callback(struct ffs_data *ffs) | |
408 | { | |
409 | struct android_dev *dev = _android_dev; | |
410 | struct functionfs_config *config = ffs_function.config; | |
411 | int ret = 0; | |
412 | ||
73f8fab5 PK |
413 | /* dev is null in case ADB is not in the composition */ |
414 | if (dev) { | |
415 | mutex_lock(&dev->mutex); | |
416 | ret = functionfs_bind(ffs, dev->cdev); | |
417 | if (ret) { | |
418 | mutex_unlock(&dev->mutex); | |
419 | return ret; | |
420 | } | |
421 | } else { | |
422 | /* android ffs_func requires daemon to start only after enable*/ | |
423 | pr_debug("start adbd only in ADB composition\n"); | |
424 | return -ENODEV; | |
425 | } | |
6fa3eb70 S |
426 | |
427 | config->data = ffs; | |
428 | config->opened = true; | |
73f8fab5 PK |
429 | /* Save dev in case the adb function will get disabled */ |
430 | config->dev = dev; | |
6fa3eb70 S |
431 | |
432 | if (config->enabled) | |
433 | android_enable(dev); | |
434 | ||
6fa3eb70 | 435 | mutex_unlock(&dev->mutex); |
73f8fab5 | 436 | return 0; |
6fa3eb70 S |
437 | } |
438 | ||
439 | static void functionfs_closed_callback(struct ffs_data *ffs) | |
440 | { | |
441 | struct android_dev *dev = _android_dev; | |
442 | struct functionfs_config *config = ffs_function.config; | |
443 | ||
73f8fab5 PK |
444 | /* |
445 | * In case new composition is without ADB or ADB got disabled by the | |
446 | * time ffs_daemon was stopped then use saved one | |
447 | */ | |
448 | if (!dev) | |
449 | dev = config->dev; | |
6fa3eb70 | 450 | |
73f8fab5 PK |
451 | /* fatal-error: It should never happen */ |
452 | if (!dev) | |
453 | pr_err("adb_closed_callback: config->dev is NULL"); | |
454 | ||
455 | if (dev) | |
456 | mutex_lock(&dev->mutex); | |
457 | ||
458 | if (config->enabled && dev) | |
6fa3eb70 S |
459 | android_disable(dev); |
460 | ||
73f8fab5 PK |
461 | config->dev = NULL; |
462 | ||
6fa3eb70 S |
463 | config->opened = false; |
464 | config->data = NULL; | |
465 | ||
466 | functionfs_unbind(ffs); | |
467 | ||
73f8fab5 PK |
468 | if (dev) |
469 | mutex_unlock(&dev->mutex); | |
6fa3eb70 S |
470 | } |
471 | ||
472 | static void *functionfs_acquire_dev_callback(const char *dev_name) | |
473 | { | |
474 | return 0; | |
475 | } | |
476 | ||
477 | static void functionfs_release_dev_callback(struct ffs_data *ffs_data) | |
478 | { | |
479 | } | |
480 | ||
481 | struct adb_data { | |
482 | bool opened; | |
483 | bool enabled; | |
484 | }; | |
485 | ||
486 | static int | |
487 | adb_function_init(struct android_usb_function *f, | |
488 | struct usb_composite_dev *cdev) | |
489 | { | |
490 | f->config = kzalloc(sizeof(struct adb_data), GFP_KERNEL); | |
491 | if (!f->config) | |
492 | return -ENOMEM; | |
493 | ||
494 | return adb_setup(); | |
495 | } | |
496 | ||
497 | static void adb_function_cleanup(struct android_usb_function *f) | |
498 | { | |
499 | adb_cleanup(); | |
500 | kfree(f->config); | |
501 | } | |
502 | ||
503 | static int | |
504 | adb_function_bind_config(struct android_usb_function *f, | |
505 | struct usb_configuration *c) | |
506 | { | |
507 | return adb_bind_config(c); | |
508 | } | |
509 | ||
510 | static void adb_android_function_enable(struct android_usb_function *f) | |
511 | { | |
512 | /* This patch cause WHQL fail */ | |
513 | #if 0 | |
514 | struct android_dev *dev = _android_dev; | |
515 | struct adb_data *data = f->config; | |
516 | ||
517 | data->enabled = true; | |
518 | ||
519 | /* Disable the gadget until adbd is ready */ | |
520 | if (!data->opened) | |
521 | android_disable(dev); | |
522 | #endif | |
523 | } | |
524 | ||
525 | static void adb_android_function_disable(struct android_usb_function *f) | |
526 | { | |
527 | /* This patch cause WHQL fail */ | |
528 | #if 0 | |
529 | struct android_dev *dev = _android_dev; | |
530 | struct adb_data *data = f->config; | |
531 | ||
532 | data->enabled = false; | |
533 | ||
534 | /* Balance the disable that was called in closed_callback */ | |
535 | if (!data->opened) | |
536 | android_enable(dev); | |
537 | #endif | |
538 | } | |
539 | ||
540 | static struct android_usb_function adb_function = { | |
541 | .name = "adb", | |
542 | .enable = adb_android_function_enable, | |
543 | .disable = adb_android_function_disable, | |
544 | .init = adb_function_init, | |
545 | .cleanup = adb_function_cleanup, | |
546 | .bind_config = adb_function_bind_config, | |
547 | }; | |
548 | ||
549 | static void adb_ready_callback(void) | |
550 | { | |
551 | /* This patch cause WHQL fail */ | |
552 | #if 0 | |
553 | struct android_dev *dev = _android_dev; | |
554 | struct adb_data *data = adb_function.config; | |
555 | ||
556 | mutex_lock(&dev->mutex); | |
557 | ||
558 | data->opened = true; | |
559 | ||
560 | if (data->enabled) | |
561 | android_enable(dev); | |
562 | ||
563 | mutex_unlock(&dev->mutex); | |
564 | #endif | |
565 | } | |
566 | ||
567 | static void adb_closed_callback(void) | |
568 | { | |
569 | /* This patch cause WHQL fail */ | |
570 | #if 0 | |
571 | struct android_dev *dev = _android_dev; | |
572 | struct adb_data *data = adb_function.config; | |
573 | ||
574 | mutex_lock(&dev->mutex); | |
575 | ||
576 | data->opened = false; | |
577 | ||
578 | if (data->enabled) | |
579 | android_disable(dev); | |
580 | ||
581 | mutex_unlock(&dev->mutex); | |
582 | #endif | |
583 | } | |
584 | ||
585 | #define MAX_ACM_INSTANCES 4 | |
586 | struct acm_function_config { | |
587 | int instances; | |
588 | int instances_on; | |
589 | struct usb_function *f_acm[MAX_ACM_INSTANCES]; | |
590 | struct usb_function_instance *f_acm_inst[MAX_ACM_INSTANCES]; | |
591 | int port_index[MAX_ACM_INSTANCES]; | |
592 | int port_index_on[MAX_ACM_INSTANCES]; | |
593 | }; | |
594 | ||
595 | static int | |
596 | acm_function_init(struct android_usb_function *f, | |
597 | struct usb_composite_dev *cdev) | |
598 | { | |
599 | int i; | |
600 | int ret; | |
601 | struct acm_function_config *config; | |
602 | #ifdef CONFIG_USBIF_COMPLIANCE | |
603 | /* FIXME, USB_IF workaround */ | |
604 | return 0; | |
605 | #endif | |
606 | ||
607 | config = kzalloc(sizeof(struct acm_function_config), GFP_KERNEL); | |
608 | if (!config) | |
609 | return -ENOMEM; | |
610 | f->config = config; | |
611 | ||
612 | for (i = 0; i < MAX_ACM_INSTANCES; i++) { | |
613 | config->f_acm_inst[i] = usb_get_function_instance("acm"); | |
614 | if (IS_ERR(config->f_acm_inst[i])) { | |
615 | ret = PTR_ERR(config->f_acm_inst[i]); | |
616 | goto err_usb_get_function_instance; | |
617 | } | |
618 | config->f_acm[i] = usb_get_function(config->f_acm_inst[i]); | |
619 | if (IS_ERR(config->f_acm[i])) { | |
620 | ret = PTR_ERR(config->f_acm[i]); | |
621 | goto err_usb_get_function; | |
622 | } | |
623 | } | |
624 | return 0; | |
625 | err_usb_get_function_instance: | |
626 | pr_err("Could not usb_get_function_instance() %d\n", i); | |
627 | while (i-- > 0) { | |
628 | usb_put_function(config->f_acm[i]); | |
629 | err_usb_get_function: | |
630 | pr_err("Could not usb_get_function() %d\n", i); | |
631 | usb_put_function_instance(config->f_acm_inst[i]); | |
632 | } | |
633 | return ret; | |
634 | } | |
635 | ||
636 | static void acm_function_cleanup(struct android_usb_function *f) | |
637 | { | |
638 | int i; | |
639 | struct acm_function_config *config = f->config; | |
640 | #ifdef CONFIG_USBIF_COMPLIANCE | |
641 | /* FIXME, USB_IF workaround */ | |
642 | return 0; | |
643 | #endif | |
644 | ||
645 | for (i = 0; i < MAX_ACM_INSTANCES; i++) { | |
646 | usb_put_function(config->f_acm[i]); | |
647 | usb_put_function_instance(config->f_acm_inst[i]); | |
648 | } | |
649 | kfree(f->config); | |
650 | f->config = NULL; | |
651 | } | |
652 | ||
653 | static int | |
654 | acm_function_bind_config(struct android_usb_function *f, | |
655 | struct usb_configuration *c) | |
656 | { | |
657 | int i; | |
658 | int ret = 0; | |
659 | struct acm_function_config *config = f->config; | |
660 | ||
661 | /*1st:Modem, 2nd:Modem, 3rd:BT, 4th:MD logger*/ | |
662 | for (i = 0; i < MAX_ACM_INSTANCES; i++) { | |
663 | if(config->port_index[i] != 0) { | |
664 | ret = usb_add_function(c, config->f_acm[i]); | |
665 | if (ret) { | |
666 | pr_err("Could not bind acm%u config\n", i); | |
667 | goto err_usb_add_function; | |
668 | } | |
669 | pr_info("%s Open /dev/ttyGS%d\n", __func__, i); | |
670 | config->port_index[i] = 0; | |
671 | config->port_index_on[i] = 1; | |
672 | config->instances = 0; | |
673 | } | |
674 | } | |
675 | ||
676 | config->instances_on = config->instances; | |
677 | for (i = 0; i < config->instances_on; i++) { | |
678 | ret = usb_add_function(c, config->f_acm[i]); | |
679 | if (ret) { | |
680 | pr_err("Could not bind acm%u config\n", i); | |
681 | goto err_usb_add_function; | |
682 | } | |
683 | pr_info("%s Open /dev/ttyGS%d\n", __func__, i); | |
684 | } | |
685 | ||
686 | return 0; | |
687 | ||
688 | err_usb_add_function: | |
689 | while (i-- > 0) | |
690 | usb_remove_function(c, config->f_acm[i]); | |
691 | return ret; | |
692 | } | |
693 | ||
694 | static void acm_function_unbind_config(struct android_usb_function *f, | |
695 | struct usb_configuration *c) | |
696 | { | |
697 | ||
698 | //int i; | |
699 | //struct acm_function_config *config = f->config; | |
700 | ||
701 | /* REVISIT: | |
702 | * list_del(&f->list) and f->unbind() are called at unbind_config(). | |
703 | * f->disable() is called at enable_store. | |
704 | * So directly return this function. | |
705 | * If does NOT return, f->list is deleted twice and cuased KE. | |
706 | * ToDo: | |
707 | * What does the original kernel code look likes? | |
708 | */ | |
709 | ||
710 | return; | |
711 | ||
712 | /* | |
713 | if (config->instances_on != 0) { | |
714 | for (i = 0; i < config->instances_on; i++) { | |
715 | pr_debug("%s f_acm[%d]=%p\n", __func__, i, config->f_acm[i]); | |
716 | usb_remove_function(c, config->f_acm[i]); | |
717 | } | |
718 | } else { | |
719 | for (i = 0; i < MAX_ACM_INSTANCES; i++) | |
720 | pr_debug("%s port_index_on=%d\n", __func__, config->port_index_on[i]); | |
721 | if (config->port_index_on[i] != 0) { | |
722 | usb_remove_function(c, config->f_acm[i]); | |
723 | } | |
724 | } | |
725 | */ | |
726 | } | |
727 | ||
728 | static ssize_t acm_instances_show(struct device *dev, | |
729 | struct device_attribute *attr, char *buf) | |
730 | { | |
731 | struct android_usb_function *f = dev_get_drvdata(dev); | |
732 | struct acm_function_config *config = f->config; | |
733 | return sprintf(buf, "%d\n", config->instances); | |
734 | } | |
735 | ||
736 | static ssize_t acm_instances_store(struct device *dev, | |
737 | struct device_attribute *attr, const char *buf, size_t size) | |
738 | { | |
739 | struct android_usb_function *f = dev_get_drvdata(dev); | |
740 | struct acm_function_config *config = f->config; | |
741 | int value; | |
742 | ||
743 | sscanf(buf, "%d", &value); | |
744 | if (value > MAX_ACM_INSTANCES) | |
745 | value = MAX_ACM_INSTANCES; | |
746 | config->instances = value; | |
747 | return size; | |
748 | } | |
749 | ||
750 | static DEVICE_ATTR(instances, S_IRUGO | S_IWUSR, acm_instances_show, | |
751 | acm_instances_store); | |
752 | ||
753 | static ssize_t acm_port_index_show(struct device *dev, | |
754 | struct device_attribute *attr, char *buf) | |
755 | { | |
756 | struct android_usb_function *f = dev_get_drvdata(dev); | |
757 | struct acm_function_config *config = f->config; | |
758 | return sprintf(buf, "%d,%d,%d,%d\n", config->port_index[0], config->port_index[1], | |
759 | config->port_index[2], config->port_index[3]); | |
760 | } | |
761 | ||
762 | static ssize_t acm_port_index_store(struct device *dev, | |
763 | struct device_attribute *attr, const char *buf, size_t size) | |
764 | { | |
765 | struct android_usb_function *f = dev_get_drvdata(dev); | |
766 | struct acm_function_config *config = f->config; | |
767 | int val[MAX_ACM_INSTANCES]={0}; | |
768 | int num = 0; | |
769 | int tmp = 0; | |
770 | ||
771 | num = sscanf(buf, "%d,%d,%d,%d", &(val[0]), &(val[1]), &(val[2]), &(val[3])); | |
772 | ||
773 | pr_debug("%s [0]=%d,[1]=%d,[2]=%d,[3]=%d, num=%d\n", __func__, val[0], val[1], \ | |
774 | val[2], val[3], num); | |
775 | ||
776 | /* Set all port_index as 0*/ | |
777 | for (tmp = 0; tmp < MAX_ACM_INSTANCES; tmp ++) | |
778 | config->port_index[tmp] = 0; | |
779 | ||
780 | for (tmp = 0; tmp < num; tmp++) { | |
781 | int port = (val[tmp] > MAX_ACM_INSTANCES || val[tmp] < 1) ? 0 : val[tmp]-1; | |
782 | config->port_index[port] = 1; | |
783 | } | |
784 | ||
785 | return size; | |
786 | } | |
787 | ||
788 | static DEVICE_ATTR(port_index, S_IRUGO | S_IWUSR, acm_port_index_show, | |
789 | acm_port_index_store); | |
790 | ||
791 | static struct device_attribute *acm_function_attributes[] = { | |
792 | &dev_attr_instances, | |
793 | &dev_attr_port_index, /*Only open the specific port*/ | |
794 | NULL | |
795 | }; | |
796 | ||
797 | static struct android_usb_function acm_function = { | |
798 | .name = "acm", | |
799 | .init = acm_function_init, | |
800 | .cleanup = acm_function_cleanup, | |
801 | .bind_config = acm_function_bind_config, | |
802 | .unbind_config = acm_function_unbind_config, | |
803 | .attributes = acm_function_attributes, | |
804 | }; | |
805 | ||
806 | #ifdef CONFIG_USB_F_LOOPBACK | |
807 | ||
808 | #define MAX_LOOPBACK_INSTANCES 1 | |
809 | ||
810 | struct loopback_function_config { | |
811 | int port_num; | |
812 | struct usb_function *f_lp[MAX_LOOPBACK_INSTANCES]; | |
813 | struct usb_function_instance *f_lp_inst[MAX_LOOPBACK_INSTANCES]; | |
814 | }; | |
815 | ||
816 | static int loopback_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev) | |
817 | { | |
818 | int i; | |
819 | int ret; | |
820 | struct loopback_function_config *config; | |
821 | ||
822 | config = kzalloc(sizeof(struct loopback_function_config), GFP_KERNEL); | |
823 | if (!config) | |
824 | return -ENOMEM; | |
825 | f->config = config; | |
826 | ||
827 | for (i = 0; i < MAX_LOOPBACK_INSTANCES; i++) { | |
828 | config->f_lp_inst[i] = usb_get_function_instance("loopback"); | |
829 | if (IS_ERR(config->f_lp_inst[i])) { | |
830 | ret = PTR_ERR(config->f_lp_inst[i]); | |
831 | goto err_usb_get_function_instance; | |
832 | } | |
833 | config->f_lp[i] = usb_get_function(config->f_lp_inst[i]); | |
834 | if (IS_ERR(config->f_lp[i])) { | |
835 | ret = PTR_ERR(config->f_lp[i]); | |
836 | goto err_usb_get_function; | |
837 | } | |
838 | } | |
839 | return 0; | |
840 | err_usb_get_function_instance: | |
841 | pr_err("Could not usb_get_function_instance() %d\n", i); | |
842 | while (i-- > 0) { | |
843 | usb_put_function(config->f_lp[i]); | |
844 | err_usb_get_function: | |
845 | pr_err("Could not usb_get_function() %d\n", i); | |
846 | usb_put_function_instance(config->f_lp_inst[i]); | |
847 | } | |
848 | return ret; | |
849 | } | |
850 | ||
851 | static void loopback_function_cleanup(struct android_usb_function *f) | |
852 | { | |
853 | int i; | |
854 | struct loopback_function_config *config = f->config; | |
855 | ||
856 | for (i = 0; i < MAX_LOOPBACK_INSTANCES; i++) { | |
857 | usb_put_function(config->f_lp[i]); | |
858 | usb_put_function_instance(config->f_lp_inst[i]); | |
859 | } | |
860 | kfree(f->config); | |
861 | f->config = NULL; | |
862 | } | |
863 | ||
864 | static int | |
865 | loopback_function_bind_config(struct android_usb_function *f, struct usb_configuration *c) | |
866 | { | |
867 | int i = 0; | |
868 | int ret = 0; | |
869 | struct loopback_function_config *config = f->config; | |
870 | ||
871 | ret = usb_add_function(c, config->f_lp[config->port_num]); | |
872 | if (ret) { | |
873 | pr_err("Could not bind loopback%u config\n", config->port_num); | |
874 | goto err_usb_add_function; | |
875 | } | |
876 | pr_info("%s Open loopback\n", __func__); | |
877 | ||
878 | return 0; | |
879 | ||
880 | err_usb_add_function: | |
881 | while (i-- > 0) | |
882 | usb_remove_function(c, config->f_lp[i]); | |
883 | return ret; | |
884 | } | |
885 | ||
886 | static struct android_usb_function loopback_function = { | |
887 | .name = "loopback", | |
888 | .init = loopback_function_init, | |
889 | .cleanup = loopback_function_cleanup, | |
890 | .bind_config = loopback_function_bind_config, | |
891 | }; | |
892 | #endif | |
893 | ||
894 | #define MAX_SERIAL_INSTANCES 4 | |
895 | ||
896 | struct serial_function_config { | |
897 | int port_num; | |
898 | struct usb_function *f_ser[MAX_SERIAL_INSTANCES]; | |
899 | struct usb_function_instance *f_ser_inst[MAX_SERIAL_INSTANCES]; | |
900 | }; | |
901 | ||
902 | static int serial_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev) | |
903 | { | |
904 | int i; | |
905 | int ret; | |
906 | struct serial_function_config *config; | |
907 | #ifdef CONFIG_USBIF_COMPLIANCE | |
908 | /* FIXME, USB_IF workaround */ | |
909 | return 0; | |
910 | #endif | |
911 | ||
912 | config = kzalloc(sizeof(struct serial_function_config), GFP_KERNEL); | |
913 | if (!config) | |
914 | return -ENOMEM; | |
915 | f->config = config; | |
916 | ||
917 | for (i = 0; i < MAX_SERIAL_INSTANCES; i++) { | |
918 | config->f_ser_inst[i] = usb_get_function_instance("gser"); | |
919 | if (IS_ERR(config->f_ser_inst[i])) { | |
920 | ret = PTR_ERR(config->f_ser_inst[i]); | |
921 | goto err_usb_get_function_instance; | |
922 | } | |
923 | config->f_ser[i] = usb_get_function(config->f_ser_inst[i]); | |
924 | if (IS_ERR(config->f_ser[i])) { | |
925 | ret = PTR_ERR(config->f_ser[i]); | |
926 | goto err_usb_get_function; | |
927 | } | |
928 | } | |
929 | return 0; | |
930 | err_usb_get_function_instance: | |
931 | pr_err("Could not usb_get_function_instance() %d\n", i); | |
932 | while (i-- > 0) { | |
933 | usb_put_function(config->f_ser[i]); | |
934 | err_usb_get_function: | |
935 | pr_err("Could not usb_get_function() %d\n", i); | |
936 | usb_put_function_instance(config->f_ser_inst[i]); | |
937 | } | |
938 | return ret; | |
939 | } | |
940 | ||
941 | static void serial_function_cleanup(struct android_usb_function *f) | |
942 | { | |
943 | int i; | |
944 | struct serial_function_config *config = f->config; | |
945 | #ifdef CONFIG_USBIF_COMPLIANCE | |
946 | /* FIXME, USB_IF workaround */ | |
947 | return 0; | |
948 | #endif | |
949 | ||
950 | for (i = 0; i < MAX_SERIAL_INSTANCES; i++) { | |
951 | usb_put_function(config->f_ser[i]); | |
952 | usb_put_function_instance(config->f_ser_inst[i]); | |
953 | } | |
954 | kfree(f->config); | |
955 | f->config = NULL; | |
956 | } | |
957 | ||
958 | static int | |
959 | serial_function_bind_config(struct android_usb_function *f, struct usb_configuration *c) | |
960 | { | |
961 | int i; | |
962 | int ret = 0; | |
963 | struct serial_function_config *config = f->config; | |
964 | ||
965 | ret = usb_add_function(c, config->f_ser[config->port_num]); | |
966 | if (ret) { | |
967 | pr_err("Could not bind ser%u config\n", config->port_num); | |
968 | goto err_usb_add_function; | |
969 | } | |
970 | pr_info("%s Open /dev/ttyGS%d\n", __func__, i); | |
971 | ||
972 | return 0; | |
973 | ||
974 | err_usb_add_function: | |
975 | while (i-- > 0) | |
976 | usb_remove_function(c, config->f_ser[i]); | |
977 | return ret; | |
978 | } | |
979 | ||
980 | static ssize_t serial_port_show(struct device *dev, | |
981 | struct device_attribute *attr, char *buf) | |
982 | { | |
983 | struct android_usb_function *f = dev_get_drvdata(dev); | |
984 | struct serial_function_config *config = f->config; | |
985 | return sprintf(buf, "%d\n", config->port_num); | |
986 | } | |
987 | ||
988 | static ssize_t serial_port_store(struct device *dev, | |
989 | struct device_attribute *attr, const char *buf, size_t size) | |
990 | { | |
991 | struct android_usb_function *f = dev_get_drvdata(dev); | |
992 | struct serial_function_config *config = f->config; | |
993 | int value; | |
994 | ||
995 | sscanf(buf, "%d", &value); | |
996 | if (value > MAX_SERIAL_INSTANCES) | |
997 | value = MAX_SERIAL_INSTANCES; | |
998 | config->port_num = value; | |
999 | return size; | |
1000 | } | |
1001 | ||
1002 | static DEVICE_ATTR(port, S_IRUGO | S_IWUSR, serial_port_show, serial_port_store); | |
1003 | static struct device_attribute *serial_function_attributes[] = { &dev_attr_port, NULL }; | |
1004 | ||
1005 | static struct android_usb_function serial_function = { | |
1006 | .name = "gser", | |
1007 | .init = serial_function_init, | |
1008 | .cleanup = serial_function_cleanup, | |
1009 | .bind_config = serial_function_bind_config, | |
1010 | .attributes = serial_function_attributes, | |
1011 | }; | |
1012 | ||
1013 | static int | |
1014 | mtp_function_init(struct android_usb_function *f, | |
1015 | struct usb_composite_dev *cdev) | |
1016 | { | |
1017 | return mtp_setup(); | |
1018 | } | |
1019 | ||
1020 | static void mtp_function_cleanup(struct android_usb_function *f) | |
1021 | { | |
1022 | mtp_cleanup(); | |
1023 | } | |
1024 | ||
1025 | static int | |
1026 | mtp_function_bind_config(struct android_usb_function *f, | |
1027 | struct usb_configuration *c) | |
1028 | { | |
1029 | return mtp_bind_config(c, false); | |
1030 | } | |
1031 | ||
1032 | static int | |
1033 | ptp_function_init(struct android_usb_function *f, | |
1034 | struct usb_composite_dev *cdev) | |
1035 | { | |
1036 | /* nothing to do - initialization is handled by mtp_function_init */ | |
1037 | return 0; | |
1038 | } | |
1039 | ||
1040 | static void ptp_function_cleanup(struct android_usb_function *f) | |
1041 | { | |
1042 | /* nothing to do - cleanup is handled by mtp_function_cleanup */ | |
1043 | } | |
1044 | ||
1045 | static int | |
1046 | ptp_function_bind_config(struct android_usb_function *f, | |
1047 | struct usb_configuration *c) | |
1048 | { | |
1049 | return mtp_bind_config(c, true); | |
1050 | } | |
1051 | ||
1052 | static int mtp_function_ctrlrequest(struct android_usb_function *f, | |
1053 | struct usb_composite_dev *cdev, | |
1054 | const struct usb_ctrlrequest *c) | |
1055 | { | |
1056 | /* MTP MSFT OS Descriptor */ | |
1057 | struct android_dev *dev = _android_dev; | |
1058 | struct android_usb_function *f_count; | |
1059 | int functions_no=0; | |
1060 | char usb_function_string[32]; | |
1061 | char * buff = usb_function_string; | |
1062 | ||
1063 | list_for_each_entry(f_count, &dev->enabled_functions, enabled_list) | |
1064 | { | |
1065 | functions_no++; | |
1066 | buff += sprintf(buff, "%s,", f_count->name); | |
1067 | } | |
1068 | *(buff-1) = '\n'; | |
1069 | ||
1070 | mtp_read_usb_functions(functions_no, usb_function_string); | |
1071 | return mtp_ctrlrequest(cdev, c); | |
1072 | } | |
1073 | ||
1074 | static int ptp_function_ctrlrequest(struct android_usb_function *f, | |
1075 | struct usb_composite_dev *cdev, | |
1076 | const struct usb_ctrlrequest *c) | |
1077 | { | |
1078 | return ptp_ctrlrequest(cdev, c); | |
1079 | } | |
1080 | ||
1081 | ||
1082 | static struct android_usb_function mtp_function = { | |
1083 | .name = "mtp", | |
1084 | .init = mtp_function_init, | |
1085 | .cleanup = mtp_function_cleanup, | |
1086 | .bind_config = mtp_function_bind_config, | |
1087 | .ctrlrequest = mtp_function_ctrlrequest, | |
1088 | }; | |
1089 | ||
1090 | /* PTP function is same as MTP with slightly different interface descriptor */ | |
1091 | static struct android_usb_function ptp_function = { | |
1092 | .name = "ptp", | |
1093 | .init = ptp_function_init, | |
1094 | .cleanup = ptp_function_cleanup, | |
1095 | .bind_config = ptp_function_bind_config, | |
1096 | .ctrlrequest = ptp_function_ctrlrequest, //ALPS01832160 | |
1097 | }; | |
1098 | ||
1099 | struct ecm_function_config { | |
1100 | u8 ethaddr[ETH_ALEN]; | |
1101 | struct eth_dev *dev; | |
1102 | }; | |
1103 | ||
1104 | static int ecm_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev) | |
1105 | { | |
1106 | f->config = kzalloc(sizeof(struct ecm_function_config), GFP_KERNEL); | |
1107 | if (!f->config) | |
1108 | return -ENOMEM; | |
1109 | return 0; | |
1110 | } | |
1111 | ||
1112 | static void ecm_function_cleanup(struct android_usb_function *f) | |
1113 | { | |
1114 | kfree(f->config); | |
1115 | f->config = NULL; | |
1116 | } | |
1117 | ||
1118 | static int | |
1119 | ecm_function_bind_config(struct android_usb_function *f, | |
1120 | struct usb_configuration *c) | |
1121 | { | |
1122 | int ret; | |
1123 | struct eth_dev *dev; | |
1124 | struct ecm_function_config *ecm = f->config; | |
1125 | ||
1126 | if (!ecm) { | |
1127 | pr_err("%s: ecm_pdata\n", __func__); | |
1128 | return -1; | |
1129 | } | |
1130 | ||
1131 | ||
1132 | pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__, | |
1133 | ecm->ethaddr[0], ecm->ethaddr[1], ecm->ethaddr[2], | |
1134 | ecm->ethaddr[3], ecm->ethaddr[4], ecm->ethaddr[5]); | |
1135 | ||
1136 | dev = gether_setup_name(c->cdev->gadget, ecm->ethaddr, "rndis"); | |
1137 | if (IS_ERR(dev)) { | |
1138 | ret = PTR_ERR(dev); | |
1139 | pr_err("%s: gether_setup failed\n", __func__); | |
1140 | return ret; | |
1141 | } | |
1142 | ecm->dev = dev; | |
1143 | ||
1144 | return ecm_bind_config(c, ecm->ethaddr, ecm->dev); | |
1145 | } | |
1146 | ||
1147 | static void ecm_function_unbind_config(struct android_usb_function *f, | |
1148 | struct usb_configuration *c) | |
1149 | { | |
1150 | struct ecm_function_config *ecm = f->config; | |
1151 | gether_cleanup(ecm->dev); | |
1152 | } | |
1153 | ||
1154 | static ssize_t ecm_ethaddr_show(struct device *dev, | |
1155 | struct device_attribute *attr, char *buf) | |
1156 | { | |
1157 | struct android_usb_function *f = dev_get_drvdata(dev); | |
1158 | struct ecm_function_config *ecm = f->config; | |
1159 | return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", | |
1160 | ecm->ethaddr[0], ecm->ethaddr[1], ecm->ethaddr[2], | |
1161 | ecm->ethaddr[3], ecm->ethaddr[4], ecm->ethaddr[5]); | |
1162 | } | |
1163 | ||
1164 | static ssize_t ecm_ethaddr_store(struct device *dev, | |
1165 | struct device_attribute *attr, const char *buf, size_t size) | |
1166 | { | |
1167 | struct android_usb_function *f = dev_get_drvdata(dev); | |
1168 | struct ecm_function_config *ecm = f->config; | |
1169 | ||
1170 | if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", | |
1171 | (int *)&ecm->ethaddr[0], (int *)&ecm->ethaddr[1], | |
1172 | (int *)&ecm->ethaddr[2], (int *)&ecm->ethaddr[3], | |
1173 | (int *)&ecm->ethaddr[4], (int *)&ecm->ethaddr[5]) == 6) | |
1174 | return size; | |
1175 | return -EINVAL; | |
1176 | } | |
1177 | ||
1178 | static DEVICE_ATTR(ecm_ethaddr, S_IRUGO | S_IWUSR, ecm_ethaddr_show, | |
1179 | ecm_ethaddr_store); | |
1180 | ||
1181 | static struct device_attribute *ecm_function_attributes[] = { | |
1182 | &dev_attr_ecm_ethaddr, | |
1183 | NULL | |
1184 | }; | |
1185 | ||
1186 | static struct android_usb_function ecm_function = { | |
1187 | .name = "ecm", | |
1188 | .init = ecm_function_init, | |
1189 | .cleanup = ecm_function_cleanup, | |
1190 | .bind_config = ecm_function_bind_config, | |
1191 | .unbind_config = ecm_function_unbind_config, | |
1192 | .attributes = ecm_function_attributes, | |
1193 | }; | |
1194 | ||
1195 | struct eem_function_config { | |
1196 | u8 ethaddr[ETH_ALEN]; | |
1197 | char manufacturer[256]; | |
1198 | struct eth_dev *dev; | |
1199 | }; | |
1200 | ||
1201 | static int | |
1202 | eem_function_init(struct android_usb_function *f, | |
1203 | struct usb_composite_dev *cdev) | |
1204 | { | |
1205 | f->config = kzalloc(sizeof(struct eem_function_config), GFP_KERNEL); | |
1206 | if (!f->config) | |
1207 | return -ENOMEM; | |
1208 | return 0; | |
1209 | } | |
1210 | ||
1211 | static void eem_function_cleanup(struct android_usb_function *f) | |
1212 | { | |
1213 | kfree(f->config); | |
1214 | f->config = NULL; | |
1215 | } | |
1216 | ||
1217 | static int | |
1218 | eem_function_bind_config(struct android_usb_function *f, | |
1219 | struct usb_configuration *c) | |
1220 | { | |
1221 | int ret; | |
1222 | struct eth_dev *dev; | |
1223 | struct eem_function_config *eem = f->config; | |
1224 | ||
1225 | pr_debug("[XLOG_DEBUG][USB]%s: \n", __func__); | |
1226 | ||
1227 | if (!eem) { | |
1228 | pr_err("%s: rndis_pdata\n", __func__); | |
1229 | return -1; | |
1230 | } | |
1231 | ||
1232 | pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__, | |
1233 | eem->ethaddr[0], eem->ethaddr[1], eem->ethaddr[2], | |
1234 | eem->ethaddr[3], eem->ethaddr[4], eem->ethaddr[5]); | |
1235 | ||
1236 | dev = gether_setup_name(c->cdev->gadget, eem->ethaddr, "rndis"); | |
1237 | if (IS_ERR(dev)) { | |
1238 | ret = PTR_ERR(dev); | |
1239 | pr_err("%s: gether_setup failed\n", __func__); | |
1240 | return ret; | |
1241 | } | |
1242 | eem->dev = dev; | |
1243 | ||
1244 | return eem_bind_config(c, eem->dev); | |
1245 | } | |
1246 | ||
1247 | static void eem_function_unbind_config(struct android_usb_function *f, | |
1248 | struct usb_configuration *c) | |
1249 | { | |
1250 | struct eem_function_config *eem = f->config; | |
1251 | gether_cleanup(eem->dev); | |
1252 | } | |
1253 | ||
1254 | static ssize_t eem_ethaddr_show(struct device *dev, | |
1255 | struct device_attribute *attr, char *buf) | |
1256 | { | |
1257 | struct android_usb_function *f = dev_get_drvdata(dev); | |
1258 | struct eem_function_config *eem = f->config; | |
1259 | return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", | |
1260 | eem->ethaddr[0], eem->ethaddr[1], eem->ethaddr[2], | |
1261 | eem->ethaddr[3], eem->ethaddr[4], eem->ethaddr[5]); | |
1262 | } | |
1263 | ||
1264 | static ssize_t eem_ethaddr_store(struct device *dev, | |
1265 | struct device_attribute *attr, const char *buf, size_t size) | |
1266 | { | |
1267 | struct android_usb_function *f = dev_get_drvdata(dev); | |
1268 | struct eem_function_config *eem = f->config; | |
1269 | ||
1270 | if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", | |
1271 | (int *)&eem->ethaddr[0], (int *)&eem->ethaddr[1], | |
1272 | (int *)&eem->ethaddr[2], (int *)&eem->ethaddr[3], | |
1273 | (int *)&eem->ethaddr[4], (int *)&eem->ethaddr[5]) == 6) | |
1274 | return size; | |
1275 | return -EINVAL; | |
1276 | } | |
1277 | ||
1278 | static DEVICE_ATTR(eem_ethaddr, S_IRUGO | S_IWUSR, eem_ethaddr_show, | |
1279 | eem_ethaddr_store); | |
1280 | ||
1281 | static struct device_attribute *eem_function_attributes[] = { | |
1282 | &dev_attr_eem_ethaddr, | |
1283 | NULL | |
1284 | }; | |
1285 | ||
1286 | static struct android_usb_function eem_function = { | |
1287 | .name = "eem", | |
1288 | .init = eem_function_init, | |
1289 | .cleanup = eem_function_cleanup, | |
1290 | .bind_config = eem_function_bind_config, | |
1291 | .unbind_config = eem_function_unbind_config, | |
1292 | .attributes = eem_function_attributes, | |
1293 | }; | |
1294 | ||
1295 | struct rndis_function_config { | |
1296 | u8 ethaddr[ETH_ALEN]; | |
1297 | u32 vendorID; | |
1298 | char manufacturer[256]; | |
1299 | /* "Wireless" RNDIS; auto-detected by Windows */ | |
1300 | bool wceis; | |
1301 | struct eth_dev *dev; | |
1302 | }; | |
1303 | ||
1304 | static int | |
1305 | rndis_function_init(struct android_usb_function *f, | |
1306 | struct usb_composite_dev *cdev) | |
1307 | { | |
1308 | f->config = kzalloc(sizeof(struct rndis_function_config), GFP_KERNEL); | |
1309 | if (!f->config) | |
1310 | return -ENOMEM; | |
1311 | return 0; | |
1312 | } | |
1313 | ||
1314 | static void rndis_function_cleanup(struct android_usb_function *f) | |
1315 | { | |
1316 | kfree(f->config); | |
1317 | f->config = NULL; | |
1318 | } | |
1319 | ||
1320 | static int | |
1321 | rndis_function_bind_config(struct android_usb_function *f, | |
1322 | struct usb_configuration *c) | |
1323 | { | |
1324 | int ret; | |
1325 | struct eth_dev *dev; | |
1326 | struct rndis_function_config *rndis = f->config; | |
1327 | ||
1328 | pr_debug("[XLOG_DEBUG][USB]%s: \n", __func__); | |
1329 | ||
1330 | if (!rndis) { | |
1331 | pr_err("%s: rndis_pdata\n", __func__); | |
1332 | return -1; | |
1333 | } | |
1334 | ||
1335 | pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__, | |
1336 | rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2], | |
1337 | rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]); | |
1338 | ||
1339 | dev = gether_setup_name(c->cdev->gadget, rndis->ethaddr, "rndis"); | |
1340 | if (IS_ERR(dev)) { | |
1341 | ret = PTR_ERR(dev); | |
1342 | pr_err("%s: gether_setup failed\n", __func__); | |
1343 | return ret; | |
1344 | } | |
1345 | rndis->dev = dev; | |
1346 | ||
1347 | if (rndis->wceis) { | |
1348 | /* "Wireless" RNDIS; auto-detected by Windows */ | |
1349 | rndis_iad_descriptor.bFunctionClass = | |
1350 | USB_CLASS_WIRELESS_CONTROLLER; | |
1351 | rndis_iad_descriptor.bFunctionSubClass = 0x01; | |
1352 | rndis_iad_descriptor.bFunctionProtocol = 0x03; | |
1353 | rndis_control_intf.bInterfaceClass = | |
1354 | USB_CLASS_WIRELESS_CONTROLLER; | |
1355 | rndis_control_intf.bInterfaceSubClass = 0x01; | |
1356 | rndis_control_intf.bInterfaceProtocol = 0x03; | |
1357 | } | |
1358 | ||
1359 | return rndis_bind_config_vendor(c, rndis->ethaddr, rndis->vendorID, | |
1360 | rndis->manufacturer, rndis->dev); | |
1361 | } | |
1362 | ||
1363 | static void rndis_function_unbind_config(struct android_usb_function *f, | |
1364 | struct usb_configuration *c) | |
1365 | { | |
1366 | struct rndis_function_config *rndis = f->config; | |
1367 | gether_cleanup(rndis->dev); | |
1368 | } | |
1369 | ||
1370 | static ssize_t rndis_manufacturer_show(struct device *dev, | |
1371 | struct device_attribute *attr, char *buf) | |
1372 | { | |
1373 | struct android_usb_function *f = dev_get_drvdata(dev); | |
1374 | struct rndis_function_config *config = f->config; | |
1375 | return sprintf(buf, "%s\n", config->manufacturer); | |
1376 | } | |
1377 | ||
1378 | static ssize_t rndis_manufacturer_store(struct device *dev, | |
1379 | struct device_attribute *attr, const char *buf, size_t size) | |
1380 | { | |
1381 | struct android_usb_function *f = dev_get_drvdata(dev); | |
1382 | struct rndis_function_config *config = f->config; | |
1383 | ||
1384 | if (size >= sizeof(config->manufacturer)) | |
1385 | return -EINVAL; | |
1386 | if (sscanf(buf, "%s", config->manufacturer) == 1) | |
1387 | return size; | |
1388 | return -1; | |
1389 | } | |
1390 | ||
1391 | static DEVICE_ATTR(manufacturer, S_IRUGO | S_IWUSR, rndis_manufacturer_show, | |
1392 | rndis_manufacturer_store); | |
1393 | ||
1394 | static ssize_t rndis_wceis_show(struct device *dev, | |
1395 | struct device_attribute *attr, char *buf) | |
1396 | { | |
1397 | struct android_usb_function *f = dev_get_drvdata(dev); | |
1398 | struct rndis_function_config *config = f->config; | |
1399 | return sprintf(buf, "%d\n", config->wceis); | |
1400 | } | |
1401 | ||
1402 | static ssize_t rndis_wceis_store(struct device *dev, | |
1403 | struct device_attribute *attr, const char *buf, size_t size) | |
1404 | { | |
1405 | struct android_usb_function *f = dev_get_drvdata(dev); | |
1406 | struct rndis_function_config *config = f->config; | |
1407 | int value; | |
1408 | ||
1409 | if (sscanf(buf, "%d", &value) == 1) { | |
1410 | config->wceis = value; | |
1411 | return size; | |
1412 | } | |
1413 | return -EINVAL; | |
1414 | } | |
1415 | ||
1416 | static DEVICE_ATTR(wceis, S_IRUGO | S_IWUSR, rndis_wceis_show, | |
1417 | rndis_wceis_store); | |
1418 | ||
1419 | static ssize_t rndis_ethaddr_show(struct device *dev, | |
1420 | struct device_attribute *attr, char *buf) | |
1421 | { | |
1422 | struct android_usb_function *f = dev_get_drvdata(dev); | |
1423 | struct rndis_function_config *rndis = f->config; | |
1424 | return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", | |
1425 | rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2], | |
1426 | rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]); | |
1427 | } | |
1428 | ||
1429 | static ssize_t rndis_ethaddr_store(struct device *dev, | |
1430 | struct device_attribute *attr, const char *buf, size_t size) | |
1431 | { | |
1432 | struct android_usb_function *f = dev_get_drvdata(dev); | |
1433 | struct rndis_function_config *rndis = f->config; | |
1434 | ||
1435 | if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", | |
1436 | (int *)&rndis->ethaddr[0], (int *)&rndis->ethaddr[1], | |
1437 | (int *)&rndis->ethaddr[2], (int *)&rndis->ethaddr[3], | |
1438 | (int *)&rndis->ethaddr[4], (int *)&rndis->ethaddr[5]) == 6) | |
1439 | return size; | |
1440 | return -EINVAL; | |
1441 | } | |
1442 | ||
1443 | static DEVICE_ATTR(ethaddr, S_IRUGO | S_IWUSR, rndis_ethaddr_show, | |
1444 | rndis_ethaddr_store); | |
1445 | ||
1446 | static ssize_t rndis_vendorID_show(struct device *dev, | |
1447 | struct device_attribute *attr, char *buf) | |
1448 | { | |
1449 | struct android_usb_function *f = dev_get_drvdata(dev); | |
1450 | struct rndis_function_config *config = f->config; | |
1451 | return sprintf(buf, "%04x\n", config->vendorID); | |
1452 | } | |
1453 | ||
1454 | static ssize_t rndis_vendorID_store(struct device *dev, | |
1455 | struct device_attribute *attr, const char *buf, size_t size) | |
1456 | { | |
1457 | struct android_usb_function *f = dev_get_drvdata(dev); | |
1458 | struct rndis_function_config *config = f->config; | |
1459 | int value; | |
1460 | ||
1461 | if (sscanf(buf, "%04x", &value) == 1) { | |
1462 | config->vendorID = value; | |
1463 | return size; | |
1464 | } | |
1465 | return -EINVAL; | |
1466 | } | |
1467 | ||
1468 | static DEVICE_ATTR(vendorID, S_IRUGO | S_IWUSR, rndis_vendorID_show, | |
1469 | rndis_vendorID_store); | |
1470 | ||
1471 | static struct device_attribute *rndis_function_attributes[] = { | |
1472 | &dev_attr_manufacturer, | |
1473 | &dev_attr_wceis, | |
1474 | &dev_attr_ethaddr, | |
1475 | &dev_attr_vendorID, | |
1476 | NULL | |
1477 | }; | |
1478 | ||
1479 | static struct android_usb_function rndis_function = { | |
1480 | .name = "rndis", | |
1481 | .init = rndis_function_init, | |
1482 | .cleanup = rndis_function_cleanup, | |
1483 | .bind_config = rndis_function_bind_config, | |
1484 | .unbind_config = rndis_function_unbind_config, | |
1485 | .attributes = rndis_function_attributes, | |
1486 | }; | |
1487 | ||
1488 | ||
1489 | struct mass_storage_function_config { | |
1490 | struct fsg_config fsg; | |
1491 | struct fsg_common *common; | |
1492 | }; | |
1493 | ||
1494 | static int mass_storage_function_init(struct android_usb_function *f, | |
1495 | struct usb_composite_dev *cdev) | |
1496 | { | |
1497 | struct mass_storage_function_config *config; | |
1498 | struct fsg_common *common; | |
1499 | int err; | |
1500 | int i; | |
1501 | ||
1502 | config = kzalloc(sizeof(struct mass_storage_function_config), | |
1503 | GFP_KERNEL); | |
1504 | if (!config) | |
1505 | return -ENOMEM; | |
1506 | ||
1507 | #ifdef CONFIG_MTK_MULTI_STORAGE_SUPPORT | |
1508 | #define LUN_MULTI (1) | |
1509 | #else | |
1510 | #define LUN_MULTI (0) | |
1511 | #endif | |
1512 | ||
1513 | #ifdef CONFIG_MTK_SHARED_SDCARD | |
1514 | #define LUN_SHARED_SD (-1) | |
1515 | #else | |
1516 | #define LUN_SHARED_SD (0) | |
1517 | #endif | |
1518 | ||
1519 | #ifdef CONFIG_MTK_ICUSB_SUPPORT | |
1520 | #define LUN_ICUSB (1) | |
1521 | #else | |
1522 | #define LUN_ICUSB (0) | |
1523 | #endif | |
1524 | ||
1525 | #define LUN_NUM LUN_MULTI + LUN_SHARED_SD + LUN_ICUSB + 1 | |
1526 | ||
1527 | config->fsg.nluns = LUN_NUM; | |
1528 | ||
1529 | for(i = 0; i < config->fsg.nluns; i++) { | |
1530 | config->fsg.luns[i].removable = 1; | |
1531 | config->fsg.luns[i].nofua = 1; | |
1532 | } | |
1533 | ||
1534 | common = fsg_common_init(NULL, cdev, &config->fsg); | |
1535 | if (IS_ERR(common)) { | |
1536 | kfree(config); | |
1537 | return PTR_ERR(common); | |
1538 | } | |
1539 | ||
1540 | err = sysfs_create_link(&f->dev->kobj, | |
1541 | &common->luns[0].dev.kobj, | |
1542 | "lun"); | |
1543 | if (err) { | |
1544 | kfree(config); | |
1545 | return err; | |
1546 | } | |
1547 | ||
1548 | /* | |
1549 | * "i" starts from "1", cuz dont want to change the naming of | |
1550 | * the original path of "lun0". | |
1551 | */ | |
1552 | for(i = 1; i < config->fsg.nluns; i++) { | |
1553 | char string_lun[5]={0}; | |
1554 | ||
1555 | sprintf(string_lun, "lun%d",i); | |
1556 | ||
1557 | err = sysfs_create_link(&f->dev->kobj, | |
1558 | &common->luns[i].dev.kobj, | |
1559 | string_lun); | |
1560 | if (err) { | |
1561 | kfree(config); | |
1562 | return err; | |
1563 | } | |
1564 | } | |
1565 | ||
1566 | config->common = common; | |
1567 | f->config = config; | |
1568 | return 0; | |
1569 | } | |
1570 | ||
1571 | static void mass_storage_function_cleanup(struct android_usb_function *f) | |
1572 | { | |
1573 | kfree(f->config); | |
1574 | f->config = NULL; | |
1575 | } | |
1576 | ||
1577 | static int mass_storage_function_bind_config(struct android_usb_function *f, | |
1578 | struct usb_configuration *c) | |
1579 | { | |
1580 | struct mass_storage_function_config *config = f->config; | |
1581 | return fsg_bind_config(c->cdev, c, config->common); | |
1582 | } | |
1583 | ||
1584 | static ssize_t mass_storage_inquiry_show(struct device *dev, | |
1585 | struct device_attribute *attr, char *buf) | |
1586 | { | |
1587 | struct android_usb_function *f = dev_get_drvdata(dev); | |
1588 | struct mass_storage_function_config *config = f->config; | |
1589 | return sprintf(buf, "%s\n", config->common->inquiry_string); | |
1590 | } | |
1591 | ||
1592 | static ssize_t mass_storage_inquiry_store(struct device *dev, | |
1593 | struct device_attribute *attr, const char *buf, size_t size) | |
1594 | { | |
1595 | struct android_usb_function *f = dev_get_drvdata(dev); | |
1596 | struct mass_storage_function_config *config = f->config; | |
1597 | if (size >= sizeof(config->common->inquiry_string)) | |
1598 | return -EINVAL; | |
1599 | if (sscanf(buf, "%s", config->common->inquiry_string) != 1) | |
1600 | return -EINVAL; | |
1601 | return size; | |
1602 | } | |
1603 | ||
1604 | static DEVICE_ATTR(inquiry_string, S_IRUGO | S_IWUSR, | |
1605 | mass_storage_inquiry_show, | |
1606 | mass_storage_inquiry_store); | |
1607 | ||
1608 | #ifdef CONFIG_MTK_BICR_SUPPORT | |
1609 | ||
1610 | static ssize_t mass_storage_bicr_show(struct device *dev, | |
1611 | struct device_attribute *attr, char *buf) | |
1612 | { | |
1613 | struct android_usb_function *f = dev_get_drvdata(dev); | |
1614 | struct mass_storage_function_config *config = f->config; | |
1615 | return sprintf(buf, "%d\n", config->common->bicr); | |
1616 | } | |
1617 | ||
1618 | static ssize_t mass_storage_bicr_store(struct device *dev, | |
1619 | struct device_attribute *attr, const char *buf, size_t size) | |
1620 | { | |
1621 | struct android_usb_function *f = dev_get_drvdata(dev); | |
1622 | struct mass_storage_function_config *config = f->config; | |
1623 | if (size >= sizeof(config->common->bicr)) | |
1624 | return -EINVAL; | |
1625 | if (sscanf(buf, "%d", &config->common->bicr) != 1) | |
1626 | return -EINVAL; | |
1627 | ||
1628 | /* Set Lun[0] is a CDROM when enable bicr.*/ | |
1629 | if (!strcmp(buf, "1")) | |
1630 | config->common->luns[0].cdrom = 1; | |
1631 | else { | |
1632 | /*Reset the value. Clean the cdrom's parameters*/ | |
1633 | config->common->luns[0].cdrom = 0; | |
1634 | config->common->luns[0].blkbits = 0; | |
1635 | config->common->luns[0].blksize = 0; | |
1636 | config->common->luns[0].num_sectors = 0; | |
1637 | } | |
1638 | ||
1639 | return size; | |
1640 | } | |
1641 | ||
1642 | static DEVICE_ATTR(bicr, S_IRUGO | S_IWUSR, | |
1643 | mass_storage_bicr_show, | |
1644 | mass_storage_bicr_store); | |
1645 | ||
1646 | #endif | |
1647 | ||
1648 | static struct device_attribute *mass_storage_function_attributes[] = { | |
1649 | &dev_attr_inquiry_string, | |
1650 | #ifdef CONFIG_MTK_BICR_SUPPORT | |
1651 | &dev_attr_bicr, | |
1652 | #endif | |
1653 | NULL | |
1654 | }; | |
1655 | ||
1656 | static struct android_usb_function mass_storage_function = { | |
1657 | .name = "mass_storage", | |
1658 | .init = mass_storage_function_init, | |
1659 | .cleanup = mass_storage_function_cleanup, | |
1660 | .bind_config = mass_storage_function_bind_config, | |
1661 | .attributes = mass_storage_function_attributes, | |
1662 | }; | |
1663 | ||
1664 | ||
1665 | static int accessory_function_init(struct android_usb_function *f, | |
1666 | struct usb_composite_dev *cdev) | |
1667 | { | |
1668 | return acc_setup(); | |
1669 | } | |
1670 | ||
1671 | static void accessory_function_cleanup(struct android_usb_function *f) | |
1672 | { | |
1673 | acc_cleanup(); | |
1674 | } | |
1675 | ||
1676 | static int accessory_function_bind_config(struct android_usb_function *f, | |
1677 | struct usb_configuration *c) | |
1678 | { | |
1679 | return acc_bind_config(c); | |
1680 | } | |
1681 | ||
1682 | static int accessory_function_ctrlrequest(struct android_usb_function *f, | |
1683 | struct usb_composite_dev *cdev, | |
1684 | const struct usb_ctrlrequest *c) | |
1685 | { | |
1686 | return acc_ctrlrequest(cdev, c); | |
1687 | } | |
1688 | ||
1689 | static struct android_usb_function accessory_function = { | |
1690 | .name = "accessory", | |
1691 | .init = accessory_function_init, | |
1692 | .cleanup = accessory_function_cleanup, | |
1693 | .bind_config = accessory_function_bind_config, | |
1694 | .ctrlrequest = accessory_function_ctrlrequest, | |
1695 | }; | |
1696 | ||
1697 | static int audio_source_function_init(struct android_usb_function *f, | |
1698 | struct usb_composite_dev *cdev) | |
1699 | { | |
1700 | struct audio_source_config *config; | |
1701 | ||
1702 | config = kzalloc(sizeof(struct audio_source_config), GFP_KERNEL); | |
1703 | if (!config) | |
1704 | return -ENOMEM; | |
1705 | config->card = -1; | |
1706 | config->device = -1; | |
1707 | f->config = config; | |
1708 | return 0; | |
1709 | } | |
1710 | ||
1711 | static void audio_source_function_cleanup(struct android_usb_function *f) | |
1712 | { | |
1713 | kfree(f->config); | |
1714 | } | |
1715 | ||
1716 | static int audio_source_function_bind_config(struct android_usb_function *f, | |
1717 | struct usb_configuration *c) | |
1718 | { | |
1719 | struct audio_source_config *config = f->config; | |
1720 | ||
1721 | return audio_source_bind_config(c, config); | |
1722 | } | |
1723 | ||
1724 | static void audio_source_function_unbind_config(struct android_usb_function *f, | |
1725 | struct usb_configuration *c) | |
1726 | { | |
1727 | struct audio_source_config *config = f->config; | |
1728 | ||
1729 | config->card = -1; | |
1730 | config->device = -1; | |
1731 | } | |
1732 | ||
1733 | static ssize_t audio_source_pcm_show(struct device *dev, | |
1734 | struct device_attribute *attr, char *buf) | |
1735 | { | |
1736 | struct android_usb_function *f = dev_get_drvdata(dev); | |
1737 | struct audio_source_config *config = f->config; | |
1738 | ||
1739 | /* print PCM card and device numbers */ | |
1740 | return sprintf(buf, "%d %d\n", config->card, config->device); | |
1741 | } | |
1742 | ||
1743 | static DEVICE_ATTR(pcm, S_IRUGO, audio_source_pcm_show, NULL); | |
1744 | ||
1745 | static struct device_attribute *audio_source_function_attributes[] = { | |
1746 | &dev_attr_pcm, | |
1747 | NULL | |
1748 | }; | |
1749 | ||
1750 | #ifdef CONFIG_EVDO_DT_SUPPORT | |
1751 | static int rawbulk_function_init(struct android_usb_function *f, | |
1752 | struct usb_composite_dev *cdev) | |
1753 | { | |
1754 | return 0; | |
1755 | } | |
1756 | ||
1757 | static void rawbulk_function_cleanup(struct android_usb_function *f) | |
1758 | { | |
1759 | ; | |
1760 | } | |
1761 | ||
1762 | static int rawbulk_function_bind_config(struct android_usb_function *f, | |
1763 | struct usb_configuration *c) | |
1764 | { | |
1765 | char *i = f->name + strlen("via_"); | |
1766 | if (!strncmp(i, "modem", 5)) | |
1767 | return rawbulk_bind_config(c, RAWBULK_TID_MODEM); | |
1768 | else if (!strncmp(i, "ets", 3)) | |
1769 | return rawbulk_bind_config(c, RAWBULK_TID_ETS); | |
1770 | else if (!strncmp(i, "atc", 3)) | |
1771 | return rawbulk_bind_config(c, RAWBULK_TID_AT); | |
1772 | else if (!strncmp(i, "pcv", 3)) | |
1773 | return rawbulk_bind_config(c, RAWBULK_TID_PCV); | |
1774 | else if (!strncmp(i, "gps", 3)) | |
1775 | return rawbulk_bind_config(c, RAWBULK_TID_GPS); | |
1776 | return -EINVAL; | |
1777 | } | |
1778 | ||
1779 | static int rawbulk_function_modem_ctrlrequest(struct android_usb_function *f, | |
1780 | struct usb_composite_dev *cdev, | |
1781 | const struct usb_ctrlrequest *c) | |
1782 | { | |
1783 | if ((c->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE && | |
1784 | (c->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR) { | |
1785 | struct rawbulk_function *fn = rawbulk_lookup_function(RAWBULK_TID_MODEM); | |
1786 | return rawbulk_function_setup(&fn->function, c); | |
1787 | } | |
1788 | return -1; | |
1789 | } | |
1790 | ||
1791 | static struct android_usb_function rawbulk_modem_function = { | |
1792 | .name = "via_modem", | |
1793 | .init = rawbulk_function_init, | |
1794 | .cleanup = rawbulk_function_cleanup, | |
1795 | .bind_config = rawbulk_function_bind_config, | |
1796 | .ctrlrequest = rawbulk_function_modem_ctrlrequest, | |
1797 | }; | |
1798 | ||
1799 | static struct android_usb_function rawbulk_ets_function = { | |
1800 | .name = "via_ets", | |
1801 | .init = rawbulk_function_init, | |
1802 | .cleanup = rawbulk_function_cleanup, | |
1803 | .bind_config = rawbulk_function_bind_config, | |
1804 | }; | |
1805 | ||
1806 | static struct android_usb_function rawbulk_atc_function = { | |
1807 | .name = "via_atc", | |
1808 | .init = rawbulk_function_init, | |
1809 | .cleanup = rawbulk_function_cleanup, | |
1810 | .bind_config = rawbulk_function_bind_config, | |
1811 | }; | |
1812 | ||
1813 | static struct android_usb_function rawbulk_pcv_function = { | |
1814 | .name = "via_pcv", | |
1815 | .init = rawbulk_function_init, | |
1816 | .cleanup = rawbulk_function_cleanup, | |
1817 | .bind_config = rawbulk_function_bind_config, | |
1818 | }; | |
1819 | ||
1820 | static struct android_usb_function rawbulk_gps_function = { | |
1821 | .name = "via_gps", | |
1822 | .init = rawbulk_function_init, | |
1823 | .cleanup = rawbulk_function_cleanup, | |
1824 | .bind_config = rawbulk_function_bind_config, | |
1825 | }; | |
1826 | #endif | |
1827 | ||
1828 | static struct android_usb_function audio_source_function = { | |
1829 | .name = "audio_source", | |
1830 | .init = audio_source_function_init, | |
1831 | .cleanup = audio_source_function_cleanup, | |
1832 | .bind_config = audio_source_function_bind_config, | |
1833 | .unbind_config = audio_source_function_unbind_config, | |
1834 | .attributes = audio_source_function_attributes, | |
1835 | }; | |
1836 | ||
1837 | static struct android_usb_function *supported_functions[] = { | |
1838 | &ffs_function, | |
1839 | &adb_function, | |
1840 | &acm_function, | |
1841 | &mtp_function, | |
1842 | &ptp_function, | |
1843 | #ifndef CONFIG_USBIF_COMPLIANCE | |
1844 | &ecm_function, | |
1845 | &eem_function, | |
1846 | #endif | |
1847 | &serial_function, | |
1848 | &rndis_function, | |
1849 | &mass_storage_function, | |
1850 | &accessory_function, | |
1851 | &audio_source_function, | |
1852 | #ifdef CONFIG_EVDO_DT_SUPPORT | |
1853 | &rawbulk_modem_function, | |
1854 | &rawbulk_ets_function, | |
1855 | &rawbulk_atc_function, | |
1856 | &rawbulk_pcv_function, | |
1857 | &rawbulk_gps_function, | |
1858 | #endif | |
1859 | #ifdef CONFIG_USB_F_LOOPBACK | |
1860 | &loopback_function, | |
1861 | #endif | |
1862 | NULL | |
1863 | }; | |
1864 | ||
1865 | ||
1866 | static int android_init_functions(struct android_usb_function **functions, | |
1867 | struct usb_composite_dev *cdev) | |
1868 | { | |
1869 | struct android_dev *dev = _android_dev; | |
1870 | struct android_usb_function *f; | |
1871 | struct device_attribute **attrs; | |
1872 | struct device_attribute *attr; | |
1873 | int err; | |
1874 | ||
1875 | #ifdef CONFIG_USBIF_COMPLIANCE | |
1876 | int index = 1; | |
1877 | #else | |
1878 | int index = 0; | |
1879 | #endif | |
1880 | ||
1881 | for (; (f = *functions++); index++) { | |
1882 | f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name); | |
1883 | /* Added for USB Develpment debug, more log for more debuging help */ | |
1884 | pr_debug("[XLOG_INFO][USB]%s: f->dev_name = %s, f->name = %s\n", __func__, f->dev_name, f->name); | |
1885 | /* Added for USB Develpment debug, more log for more debuging help */ | |
1886 | f->dev = device_create(android_class, dev->dev, | |
1887 | MKDEV(0, index), f, f->dev_name); | |
1888 | if (IS_ERR(f->dev)) { | |
1889 | pr_err("%s: Failed to create dev %s", __func__, | |
1890 | f->dev_name); | |
1891 | err = PTR_ERR(f->dev); | |
1892 | goto err_create; | |
1893 | } | |
1894 | ||
1895 | if (f->init) { | |
1896 | err = f->init(f, cdev); | |
1897 | if (err) { | |
1898 | pr_err("%s: Failed to init %s", __func__, | |
1899 | f->name); | |
1900 | goto err_out; | |
1901 | } else { | |
1902 | pr_debug("[XLOG_INFO][USB]%s: init %s success!!\n", __func__, f->name); | |
1903 | } | |
1904 | } | |
1905 | ||
1906 | attrs = f->attributes; | |
1907 | if (attrs) { | |
1908 | while ((attr = *attrs++) && !err) | |
1909 | err = device_create_file(f->dev, attr); | |
1910 | } | |
1911 | if (err) { | |
1912 | pr_err("%s: Failed to create function %s attributes", | |
1913 | __func__, f->name); | |
1914 | goto err_out; | |
1915 | } | |
1916 | } | |
1917 | return 0; | |
1918 | ||
1919 | err_out: | |
1920 | device_destroy(android_class, f->dev->devt); | |
1921 | err_create: | |
1922 | kfree(f->dev_name); | |
1923 | return err; | |
1924 | } | |
1925 | ||
1926 | static void android_cleanup_functions(struct android_usb_function **functions) | |
1927 | { | |
1928 | struct android_usb_function *f; | |
1929 | ||
1930 | while (*functions) { | |
1931 | f = *functions++; | |
1932 | ||
1933 | if (f->dev) { | |
1934 | device_destroy(android_class, f->dev->devt); | |
1935 | kfree(f->dev_name); | |
1936 | } | |
1937 | ||
1938 | if (f->cleanup) | |
1939 | f->cleanup(f); | |
1940 | } | |
1941 | } | |
1942 | ||
1943 | static int | |
1944 | android_bind_enabled_functions(struct android_dev *dev, | |
1945 | struct usb_configuration *c) | |
1946 | { | |
1947 | struct android_usb_function *f; | |
1948 | int ret; | |
1949 | ||
1950 | /* Added for USB Develpment debug, more log for more debuging help */ | |
1951 | pr_debug("[XLOG_INFO][USB]%s: ", __func__); | |
1952 | /* Added for USB Develpment debug, more log for more debuging help */ | |
1953 | ||
1954 | list_for_each_entry(f, &dev->enabled_functions, enabled_list) { | |
1955 | pr_debug("[XLOG_INFO][USB]bind_config function '%s'/%p\n", f->name, f); | |
1956 | ret = f->bind_config(f, c); | |
1957 | if (ret) { | |
1958 | pr_err("%s: %s failed", __func__, f->name); | |
1959 | return ret; | |
1960 | } | |
1961 | } | |
1962 | return 0; | |
1963 | } | |
1964 | ||
1965 | static void | |
1966 | android_unbind_enabled_functions(struct android_dev *dev, | |
1967 | struct usb_configuration *c) | |
1968 | { | |
1969 | struct android_usb_function *f; | |
1970 | ||
1971 | list_for_each_entry(f, &dev->enabled_functions, enabled_list) { | |
1972 | pr_debug("[XLOG_INFO][USB]unbind_config function '%s'/%p\n", f->name, f); | |
1973 | if (f->unbind_config) | |
1974 | f->unbind_config(f, c); | |
1975 | } | |
1976 | } | |
1977 | ||
1978 | static int android_enable_function(struct android_dev *dev, char *name) | |
1979 | { | |
1980 | struct android_usb_function **functions = dev->functions; | |
1981 | struct android_usb_function *f; | |
1982 | while ((f = *functions++)) { | |
1983 | ||
1984 | /* Added for USB Develpment debug, more log for more debuging help */ | |
1985 | pr_debug("[XLOG_INFO][USB]%s: name = %s, f->name=%s \n", __func__, name, f->name); | |
1986 | /* Added for USB Develpment debug, more log for more debuging help */ | |
1987 | if (!strcmp(name, f->name)) { | |
1988 | list_add_tail(&f->enabled_list, | |
1989 | &dev->enabled_functions); | |
1990 | return 0; | |
1991 | } | |
1992 | } | |
1993 | return -EINVAL; | |
1994 | } | |
1995 | ||
1996 | /*-------------------------------------------------------------------------*/ | |
1997 | /* /sys/class/android_usb/android%d/ interface */ | |
1998 | ||
1999 | static ssize_t | |
2000 | functions_show(struct device *pdev, struct device_attribute *attr, char *buf) | |
2001 | { | |
2002 | struct android_dev *dev = dev_get_drvdata(pdev); | |
2003 | struct android_usb_function *f; | |
2004 | char *buff = buf; | |
2005 | ||
2006 | /* Added for USB Develpment debug, more log for more debuging help */ | |
2007 | pr_debug("[XLOG_INFO][USB]%s: ", __func__); | |
2008 | /* Added for USB Develpment debug, more log for more debuging help */ | |
2009 | ||
2010 | mutex_lock(&dev->mutex); | |
2011 | ||
2012 | list_for_each_entry(f, &dev->enabled_functions, enabled_list) | |
2013 | buff += sprintf(buff, "%s,", f->name); | |
2014 | ||
2015 | mutex_unlock(&dev->mutex); | |
2016 | ||
2017 | if (buff != buf) | |
2018 | *(buff-1) = '\n'; | |
2019 | return buff - buf; | |
2020 | } | |
2021 | ||
2022 | static ssize_t | |
2023 | functions_store(struct device *pdev, struct device_attribute *attr, | |
2024 | const char *buff, size_t size) | |
2025 | { | |
2026 | struct android_dev *dev = dev_get_drvdata(pdev); | |
2027 | char *name; | |
2028 | char buf[256], *b; | |
2029 | char aliases[256], *a; | |
2030 | int err; | |
2031 | int is_ffs; | |
2032 | int ffs_enabled = 0; | |
2033 | ||
2034 | mutex_lock(&dev->mutex); | |
2035 | ||
2036 | if (dev->enabled) { | |
2037 | mutex_unlock(&dev->mutex); | |
2038 | return -EBUSY; | |
2039 | } | |
2040 | ||
2041 | INIT_LIST_HEAD(&dev->enabled_functions); | |
2042 | ||
2043 | /* Added for USB Develpment debug, more log for more debuging help */ | |
2044 | pr_debug("[XLOG_INFO][USB]%s: \n", __func__); | |
2045 | /* Added for USB Develpment debug, more log for more debuging help */ | |
2046 | ||
2047 | strlcpy(buf, buff, sizeof(buf)); | |
2048 | b = strim(buf); | |
2049 | ||
2050 | while (b) { | |
2051 | name = strsep(&b, ","); | |
2052 | ||
2053 | /* Added for USB Develpment debug, more log for more debuging help */ | |
2054 | pr_debug("[XLOG_INFO][USB]%s: name = %s \n", __func__, name); | |
2055 | /* Added for USB Develpment debug, more log for more debuging help */ | |
2056 | ||
2057 | if (!name) | |
2058 | continue; | |
2059 | ||
2060 | is_ffs = 0; | |
2061 | strlcpy(aliases, dev->ffs_aliases, sizeof(aliases)); | |
2062 | a = aliases; | |
2063 | ||
2064 | while (a) { | |
2065 | char *alias = strsep(&a, ","); | |
2066 | if (alias && !strcmp(name, alias)) { | |
2067 | is_ffs = 1; | |
2068 | break; | |
2069 | } | |
2070 | } | |
2071 | ||
2072 | if (is_ffs) { | |
2073 | if (ffs_enabled) | |
2074 | continue; | |
2075 | err = android_enable_function(dev, "ffs"); | |
2076 | if (err) | |
2077 | pr_err("android_usb: Cannot enable ffs (%d)", | |
2078 | err); | |
2079 | else | |
2080 | ffs_enabled = 1; | |
2081 | continue; | |
2082 | } | |
2083 | ||
2084 | err = android_enable_function(dev, name); | |
2085 | if (err) | |
2086 | pr_err("android_usb: Cannot enable '%s' (%d)", | |
2087 | name, err); | |
2088 | } | |
2089 | ||
2090 | mutex_unlock(&dev->mutex); | |
2091 | ||
2092 | return size; | |
2093 | } | |
2094 | ||
2095 | static ssize_t enable_show(struct device *pdev, struct device_attribute *attr, | |
2096 | char *buf) | |
2097 | { | |
2098 | struct android_dev *dev = dev_get_drvdata(pdev); | |
2099 | return sprintf(buf, "%d\n", dev->enabled); | |
2100 | } | |
2101 | ||
2102 | static ssize_t enable_store(struct device *pdev, struct device_attribute *attr, | |
2103 | const char *buff, size_t size) | |
2104 | { | |
2105 | struct android_dev *dev = dev_get_drvdata(pdev); | |
2106 | struct usb_composite_dev *cdev = dev->cdev; | |
2107 | struct android_usb_function *f; | |
2108 | int enabled = 0; | |
2109 | ||
2110 | ||
2111 | if (!cdev) | |
2112 | return -ENODEV; | |
2113 | ||
2114 | mutex_lock(&dev->mutex); | |
2115 | ||
2116 | /* Added for USB Develpment debug, more log for more debuging help */ | |
2117 | pr_debug("[XLOG_INFO][USB]%s: device_attr->attr.name: %s\n", __func__, attr->attr.name); | |
2118 | /* Added for USB Develpment debug, more log for more debuging help */ | |
2119 | ||
2120 | sscanf(buff, "%d", &enabled); | |
2121 | if (enabled && !dev->enabled) { | |
2122 | /* ALPS01770952 | |
2123 | * Reset next_string_id to 0 before enabling the gadget driver. | |
2124 | * Otherwise, after a large number of enable/disable cycles, | |
2125 | * function bind will fail because we cannot allocate new string ids. | |
2126 | * String ids cannot be larger than 254 per USB spec. | |
2127 | * 0~15 are reserved for usb device descriptor | |
2128 | * 16~254 are for functions. | |
2129 | */ | |
2130 | cdev->next_string_id = 0x10; | |
2131 | ||
2132 | /* | |
2133 | * Update values in composite driver's copy of | |
2134 | * device descriptor. | |
2135 | */ | |
2136 | cdev->desc.idVendor = device_desc.idVendor; | |
2137 | cdev->desc.idProduct = device_desc.idProduct; | |
2138 | cdev->desc.bcdDevice = device_desc.bcdDevice; | |
2139 | cdev->desc.bDeviceClass = device_desc.bDeviceClass; | |
2140 | cdev->desc.bDeviceSubClass = device_desc.bDeviceSubClass; | |
2141 | cdev->desc.bDeviceProtocol = device_desc.bDeviceProtocol; | |
2142 | ||
2143 | /* special case for meta mode */ | |
2144 | if (serial_string[0] == 0x0) { | |
2145 | cdev->desc.iSerialNumber = 0; | |
2146 | } else { | |
2147 | cdev->desc.iSerialNumber = device_desc.iSerialNumber; | |
2148 | } | |
2149 | ||
2150 | list_for_each_entry(f, &dev->enabled_functions, enabled_list) { | |
2151 | pr_debug("[XLOG_INFO][USB]enable function '%s'/%p\n", f->name, f); | |
2152 | if (f->enable) | |
2153 | f->enable(f); | |
2154 | } | |
2155 | android_enable(dev); | |
2156 | dev->enabled = true; | |
2157 | ||
2158 | /* Added for USB Develpment debug, more log for more debuging help */ | |
2159 | pr_debug("[XLOG_INFO][USB]%s: enable 0->1 case, device_desc.idVendor = 0x%x, device_desc.idProduct = 0x%x\n", __func__, device_desc.idVendor, device_desc.idProduct); | |
2160 | /* Added for USB Develpment debug, more log for more debuging help */ | |
2161 | ||
2162 | } else if (!enabled && dev->enabled) { | |
2163 | ||
2164 | /* Added for USB Develpment debug, more log for more debuging help */ | |
2165 | pr_debug("[XLOG_INFO][USB]%s: enable 1->0 case, device_desc.idVendor = 0x%x, device_desc.idProduct = 0x%x\n", __func__, device_desc.idVendor, device_desc.idProduct); | |
2166 | /* Added for USB Develpment debug, more log for more debuging help */ | |
2167 | ||
2168 | android_disable(dev); | |
2169 | list_for_each_entry(f, &dev->enabled_functions, enabled_list) { | |
2170 | pr_debug("[XLOG_INFO][USB]disable function '%s'/%p\n", f->name, f); | |
2171 | if (f->disable) { | |
2172 | f->disable(f); | |
2173 | } | |
2174 | } | |
2175 | dev->enabled = false; | |
2176 | } else { | |
2177 | pr_err("android_usb: already %s\n", | |
2178 | dev->enabled ? "enabled" : "disabled"); | |
2179 | /* Add for HW/SW connect */ | |
2180 | if (!usb_cable_connected()) { | |
2181 | schedule_work(&dev->work); | |
2182 | pr_debug("[XLOG_VERBOSE][USB]%s: enable 0->0 case - no usb cable", __func__); | |
2183 | } | |
2184 | /* Add for HW/SW connect */ | |
2185 | } | |
2186 | ||
2187 | mutex_unlock(&dev->mutex); | |
2188 | return size; | |
2189 | } | |
2190 | ||
2191 | static ssize_t state_show(struct device *pdev, struct device_attribute *attr, | |
2192 | char *buf) | |
2193 | { | |
2194 | struct android_dev *dev = dev_get_drvdata(pdev); | |
2195 | struct usb_composite_dev *cdev = dev->cdev; | |
2196 | char *state = "DISCONNECTED"; | |
2197 | unsigned long flags; | |
2198 | ||
2199 | if (!cdev) | |
2200 | goto out; | |
2201 | ||
2202 | spin_lock_irqsave(&cdev->lock, flags); | |
2203 | if (cdev->config) | |
2204 | state = "CONFIGURED"; | |
2205 | else if (dev->connected) | |
2206 | state = "CONNECTED"; | |
2207 | spin_unlock_irqrestore(&cdev->lock, flags); | |
2208 | out: | |
2209 | return sprintf(buf, "%s\n", state); | |
2210 | } | |
2211 | ||
2212 | #define DESCRIPTOR_ATTR(field, format_string) \ | |
2213 | static ssize_t \ | |
2214 | field ## _show(struct device *dev, struct device_attribute *attr, \ | |
2215 | char *buf) \ | |
2216 | { \ | |
2217 | return sprintf(buf, format_string, device_desc.field); \ | |
2218 | } \ | |
2219 | static ssize_t \ | |
2220 | field ## _store(struct device *dev, struct device_attribute *attr, \ | |
2221 | const char *buf, size_t size) \ | |
2222 | { \ | |
2223 | int value; \ | |
2224 | if (sscanf(buf, format_string, &value) == 1) { \ | |
2225 | device_desc.field = value; \ | |
2226 | return size; \ | |
2227 | } \ | |
2228 | return -1; \ | |
2229 | } \ | |
2230 | static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store); | |
2231 | ||
2232 | #define DESCRIPTOR_STRING_ATTR(field, buffer) \ | |
2233 | static ssize_t \ | |
2234 | field ## _show(struct device *dev, struct device_attribute *attr, \ | |
2235 | char *buf) \ | |
2236 | { \ | |
2237 | return sprintf(buf, "%s", buffer); \ | |
2238 | } \ | |
2239 | static ssize_t \ | |
2240 | field ## _store(struct device *dev, struct device_attribute *attr, \ | |
2241 | const char *buf, size_t size) \ | |
2242 | { \ | |
2243 | if (size >= sizeof(buffer)) \ | |
2244 | return -EINVAL; \ | |
2245 | if (sscanf(buf, "%s", buffer) == 1) { \ | |
2246 | return size; \ | |
2247 | } \ | |
2248 | return -1; \ | |
2249 | } \ | |
2250 | static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store); | |
2251 | ||
2252 | ||
2253 | DESCRIPTOR_ATTR(idVendor, "%04x\n") | |
2254 | DESCRIPTOR_ATTR(idProduct, "%04x\n") | |
2255 | DESCRIPTOR_ATTR(bcdDevice, "%04x\n") | |
2256 | DESCRIPTOR_ATTR(bDeviceClass, "%d\n") | |
2257 | DESCRIPTOR_ATTR(bDeviceSubClass, "%d\n") | |
2258 | DESCRIPTOR_ATTR(bDeviceProtocol, "%d\n") | |
2259 | DESCRIPTOR_STRING_ATTR(iManufacturer, manufacturer_string) | |
2260 | DESCRIPTOR_STRING_ATTR(iProduct, product_string) | |
2261 | DESCRIPTOR_STRING_ATTR(iSerial, serial_string) | |
2262 | ||
2263 | static DEVICE_ATTR(functions, S_IRUGO | S_IWUSR, functions_show, | |
2264 | functions_store); | |
2265 | static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store); | |
2266 | static DEVICE_ATTR(state, S_IRUGO, state_show, NULL); | |
2267 | ||
2268 | static struct device_attribute *android_usb_attributes[] = { | |
2269 | &dev_attr_idVendor, | |
2270 | &dev_attr_idProduct, | |
2271 | &dev_attr_bcdDevice, | |
2272 | &dev_attr_bDeviceClass, | |
2273 | &dev_attr_bDeviceSubClass, | |
2274 | &dev_attr_bDeviceProtocol, | |
2275 | &dev_attr_iManufacturer, | |
2276 | &dev_attr_iProduct, | |
2277 | &dev_attr_iSerial, | |
2278 | &dev_attr_functions, | |
2279 | &dev_attr_enable, | |
2280 | &dev_attr_state, | |
2281 | NULL | |
2282 | }; | |
2283 | ||
2284 | /*-------------------------------------------------------------------------*/ | |
2285 | /* Composite driver */ | |
2286 | ||
2287 | static int android_bind_config(struct usb_configuration *c) | |
2288 | { | |
2289 | struct android_dev *dev = _android_dev; | |
2290 | int ret = 0; | |
2291 | ||
2292 | ret = android_bind_enabled_functions(dev, c); | |
2293 | if (ret) | |
2294 | return ret; | |
2295 | ||
2296 | return 0; | |
2297 | } | |
2298 | ||
2299 | static void android_unbind_config(struct usb_configuration *c) | |
2300 | { | |
2301 | struct android_dev *dev = _android_dev; | |
2302 | ||
2303 | android_unbind_enabled_functions(dev, c); | |
2304 | } | |
2305 | ||
2306 | static int android_setup_config(struct usb_configuration *c, const struct usb_ctrlrequest *ctrl) | |
2307 | { | |
2308 | int handled = -EINVAL; | |
2309 | const u8 recip = ctrl->bRequestType & USB_RECIP_MASK; | |
2310 | ||
2311 | pr_debug("%s bRequestType=%x, bRequest=%x, recip=%x\n", __func__, ctrl->bRequestType, ctrl->bRequest, recip); | |
2312 | ||
2313 | if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { | |
2314 | switch (ctrl->bRequest) | |
2315 | { | |
2316 | case USB_REQ_CLEAR_FEATURE: | |
2317 | switch (recip) | |
2318 | { | |
2319 | case USB_RECIP_DEVICE: | |
2320 | switch (ctrl->wValue) | |
2321 | { | |
2322 | case USB_DEVICE_U1_ENABLE: | |
2323 | handled = 1; | |
2324 | pr_debug("Clear Feature->U1 Enable\n"); | |
2325 | break; | |
2326 | ||
2327 | case USB_DEVICE_U2_ENABLE: | |
2328 | handled = 1; | |
2329 | pr_debug("Clear Feature->U2 Enable\n"); | |
2330 | break; | |
2331 | ||
2332 | default: | |
2333 | handled = -EINVAL; | |
2334 | break; | |
2335 | } | |
2336 | break; | |
2337 | default: | |
2338 | handled = -EINVAL; | |
2339 | break; | |
2340 | } | |
2341 | break; | |
2342 | ||
2343 | case USB_REQ_SET_FEATURE: | |
2344 | switch (recip) | |
2345 | { | |
2346 | case USB_RECIP_DEVICE: | |
2347 | switch (ctrl->wValue) | |
2348 | { | |
2349 | case USB_DEVICE_U1_ENABLE: | |
2350 | pr_debug("Set Feature->U1 Enable\n"); | |
2351 | handled = 1; | |
2352 | break; | |
2353 | case USB_DEVICE_U2_ENABLE: | |
2354 | pr_debug("Set Feature->U2 Enable\n"); | |
2355 | handled = 1; | |
2356 | break; | |
2357 | default: | |
2358 | handled = -EINVAL; | |
2359 | break; | |
2360 | } | |
2361 | break; | |
2362 | ||
2363 | default: | |
2364 | handled = -EINVAL; | |
2365 | break; | |
2366 | } | |
2367 | break; | |
2368 | ||
2369 | default: | |
2370 | handled = -EINVAL; | |
2371 | break; | |
2372 | } | |
2373 | } | |
2374 | ||
2375 | return handled; | |
2376 | } | |
2377 | ||
2378 | static int android_bind(struct usb_composite_dev *cdev) | |
2379 | { | |
2380 | struct android_dev *dev = _android_dev; | |
2381 | struct usb_gadget *gadget = cdev->gadget; | |
2382 | int id, ret; | |
2383 | ||
2384 | /* | |
2385 | * Start disconnected. Userspace will connect the gadget once | |
2386 | * it is done configuring the functions. | |
2387 | */ | |
2388 | usb_gadget_disconnect(gadget); | |
2389 | ||
2390 | ret = android_init_functions(dev->functions, cdev); | |
2391 | if (ret) | |
2392 | return ret; | |
2393 | ||
2394 | /* Allocate string descriptor numbers ... note that string | |
2395 | * contents can be overridden by the composite_dev glue. | |
2396 | */ | |
2397 | id = usb_string_id(cdev); | |
2398 | if (id < 0) | |
2399 | return id; | |
2400 | strings_dev[STRING_MANUFACTURER_IDX].id = id; | |
2401 | device_desc.iManufacturer = id; | |
2402 | ||
2403 | id = usb_string_id(cdev); | |
2404 | if (id < 0) | |
2405 | return id; | |
2406 | strings_dev[STRING_PRODUCT_IDX].id = id; | |
2407 | device_desc.iProduct = id; | |
2408 | ||
2409 | /* Default strings - should be updated by userspace */ | |
2410 | strncpy(manufacturer_string, MANUFACTURER_STRING, sizeof(manufacturer_string) - 1); | |
2411 | strncpy(product_string, PRODUCT_STRING, sizeof(product_string) - 1); | |
2412 | strncpy(serial_string, "0123456789ABCDEF", sizeof(serial_string) - 1); | |
2413 | ||
2414 | id = usb_string_id(cdev); | |
2415 | if (id < 0) | |
2416 | return id; | |
2417 | strings_dev[STRING_SERIAL_IDX].id = id; | |
2418 | device_desc.iSerialNumber = id; | |
2419 | ||
2420 | #ifdef CONFIG_USBIF_COMPLIANCE | |
2421 | usb_gadget_clear_selfpowered(gadget); | |
2422 | #else | |
2423 | usb_gadget_set_selfpowered(gadget); | |
2424 | #endif | |
2425 | dev->cdev = cdev; | |
2426 | ||
2427 | return 0; | |
2428 | } | |
2429 | ||
2430 | static int android_usb_unbind(struct usb_composite_dev *cdev) | |
2431 | { | |
2432 | struct android_dev *dev = _android_dev; | |
2433 | ||
2434 | cancel_work_sync(&dev->work); | |
2435 | android_cleanup_functions(dev->functions); | |
2436 | return 0; | |
2437 | } | |
2438 | ||
2439 | /* HACK: android needs to override setup for accessory to work */ | |
2440 | static int (*composite_setup_func)(struct usb_gadget *gadget, const struct usb_ctrlrequest *c); | |
2441 | extern void composite_setup_complete(struct usb_ep *ep, struct usb_request *req); | |
2442 | ||
2443 | static int | |
2444 | android_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *c) | |
2445 | { | |
2446 | struct android_dev *dev = _android_dev; | |
2447 | struct usb_composite_dev *cdev = get_gadget_data(gadget); | |
2448 | struct usb_request *req = cdev->req; | |
2449 | struct android_usb_function *f; | |
2450 | int value = -EOPNOTSUPP; | |
2451 | unsigned long flags; | |
2452 | ||
2453 | pr_debug("[XLOG_VERBOSE][USB]%s\n", __func__); | |
2454 | ||
2455 | req->zero = 0; | |
2456 | req->complete = composite_setup_complete; | |
2457 | req->length = 0; | |
2458 | gadget->ep0->driver_data = cdev; | |
2459 | ||
2460 | list_for_each_entry(f, &dev->enabled_functions, enabled_list) { | |
2461 | if (f->ctrlrequest) { | |
2462 | value = f->ctrlrequest(f, cdev, c); | |
2463 | if (value >= 0) | |
2464 | break; | |
2465 | } | |
2466 | } | |
2467 | ||
2468 | /* Special case the accessory function. | |
2469 | * It needs to handle control requests before it is enabled. | |
2470 | */ | |
2471 | if (value < 0) | |
2472 | value = acc_ctrlrequest(cdev, c); | |
2473 | ||
2474 | if (value < 0) | |
2475 | value = composite_setup_func(gadget, c); | |
2476 | ||
2477 | spin_lock_irqsave(&cdev->lock, flags); | |
2478 | if (!dev->connected) { | |
2479 | dev->connected = 1; | |
2480 | schedule_work(&dev->work); | |
2481 | } else if (c->bRequest == USB_REQ_SET_CONFIGURATION && | |
2482 | cdev->config) { | |
2483 | schedule_work(&dev->work); | |
2484 | } | |
2485 | spin_unlock_irqrestore(&cdev->lock, flags); | |
2486 | ||
2487 | return value; | |
2488 | } | |
2489 | ||
2490 | static void android_disconnect(struct usb_composite_dev *cdev) | |
2491 | { | |
2492 | struct android_dev *dev = _android_dev; | |
2493 | ||
2494 | /* Added for USB Develpment debug, more log for more debuging help */ | |
2495 | pr_debug("[XLOG_VERBOSE][USB]%s: \n", __func__); | |
2496 | /* Added for USB Develpment debug, more log for more debuging help */ | |
2497 | ||
2498 | /* accessory HID support can be active while the | |
2499 | accessory function is not actually enabled, | |
2500 | so we need to inform it when we are disconnected. | |
2501 | */ | |
2502 | acc_disconnect(); | |
2503 | ||
2504 | dev->connected = 0; | |
2505 | schedule_work(&dev->work); | |
2506 | ||
2507 | /* Added for USB Develpment debug, more log for more debuging help */ | |
2508 | pr_debug("[XLOG_VERBOSE][USB]%s: dev->connected = %d \n", __func__, dev->connected); | |
2509 | /* Added for USB Develpment debug, more log for more debuging help */ | |
2510 | } | |
2511 | ||
2512 | static struct usb_composite_driver android_usb_driver = { | |
2513 | .name = "android_usb", | |
2514 | .dev = &device_desc, | |
2515 | .strings = dev_strings, | |
2516 | .bind = android_bind, | |
2517 | .unbind = android_usb_unbind, | |
2518 | .disconnect = android_disconnect, | |
2519 | #ifdef CONFIG_USB_MU3D_DRV | |
2520 | .max_speed = USB_SPEED_SUPER | |
2521 | #else | |
2522 | .max_speed = USB_SPEED_HIGH | |
2523 | #endif | |
2524 | }; | |
2525 | ||
2526 | static int android_create_device(struct android_dev *dev) | |
2527 | { | |
2528 | struct device_attribute **attrs = android_usb_attributes; | |
2529 | struct device_attribute *attr; | |
2530 | int err; | |
2531 | ||
2532 | dev->dev = device_create(android_class, NULL, | |
2533 | MKDEV(0, 0), NULL, "android0"); | |
2534 | if (IS_ERR(dev->dev)) | |
2535 | return PTR_ERR(dev->dev); | |
2536 | ||
2537 | dev_set_drvdata(dev->dev, dev); | |
2538 | ||
2539 | while ((attr = *attrs++)) { | |
2540 | err = device_create_file(dev->dev, attr); | |
2541 | if (err) { | |
2542 | device_destroy(android_class, dev->dev->devt); | |
2543 | return err; | |
2544 | } | |
2545 | } | |
2546 | return 0; | |
2547 | } | |
2548 | ||
2549 | #ifdef CONFIG_USBIF_COMPLIANCE | |
2550 | ||
2551 | #include <linux/proc_fs.h> | |
2552 | #include <asm/uaccess.h> | |
2553 | #include <linux/seq_file.h> | |
2554 | ||
2555 | ||
2556 | static int andoid_usbif_driver_on = 0 ; | |
2557 | ||
2558 | ||
2559 | static int android_start(void) | |
2560 | { | |
2561 | struct android_dev *dev; | |
2562 | int err; | |
2563 | ||
2564 | pr_debug("android_start ===> \n"); | |
2565 | ||
2566 | err = usb_composite_probe(&android_usb_driver); | |
2567 | if (err) { | |
2568 | pr_err("%s: failed to probe driver %d", __func__, err); | |
2569 | } | |
2570 | ||
2571 | /* HACK: exchange composite's setup with ours */ | |
2572 | composite_setup_func = android_usb_driver.gadget_driver.setup; | |
2573 | android_usb_driver.gadget_driver.setup = android_setup; | |
2574 | ||
2575 | pr_debug("android_start <=== \n"); | |
2576 | ||
2577 | return err; | |
2578 | } | |
2579 | ||
2580 | static int android_stop(void) | |
2581 | { | |
2582 | pr_debug("android_stop ===> \n"); | |
2583 | ||
2584 | usb_composite_unregister(&android_usb_driver); | |
2585 | ||
2586 | pr_debug("android_stop <=== \n"); | |
2587 | } | |
2588 | ||
2589 | static int andoid_usbif_proc_show(struct seq_file *seq, void *v) | |
2590 | { | |
2591 | seq_printf(seq, "andoid_usbif_proc_show, andoid_usbif_driver_on is %d (on:1, off:0)\n", andoid_usbif_driver_on); | |
2592 | return 0; | |
2593 | } | |
2594 | ||
2595 | static int andoid_usbif_proc_open(struct inode *inode, struct file *file) | |
2596 | { | |
2597 | return single_open(file, andoid_usbif_proc_show, inode->i_private); | |
2598 | } | |
2599 | ||
2600 | static ssize_t andoid_usbif_proc_write(struct file *file, const char __user *buf, size_t length, loff_t *ppos) | |
2601 | { | |
2602 | int ret ; | |
2603 | char msg[32] ; | |
2604 | int result; | |
2605 | int status; | |
2606 | struct device *dev ; | |
2607 | int irq ; | |
2608 | struct resource *iomem; | |
2609 | void __iomem *base; | |
2610 | struct musb *musb ; | |
2611 | void __iomem *ctrl_base; | |
2612 | ||
2613 | if (length >= sizeof(msg)) { | |
2614 | pr_debug("andoid_usbif_proc_write length error, the error len is %d\n", (unsigned int)length); | |
2615 | return -EINVAL; | |
2616 | } | |
2617 | if (copy_from_user(msg, buf, length)) | |
2618 | return -EFAULT; | |
2619 | ||
2620 | msg[length] = 0 ; | |
2621 | ||
2622 | pr_debug("andoid_usbif_proc_write: %s, current driver on/off: %d\n", msg, andoid_usbif_driver_on); | |
2623 | ||
2624 | if ((msg[0] == '1') && (andoid_usbif_driver_on == 0)){ | |
2625 | pr_debug("start usb android driver ===> \n"); | |
2626 | printk("start usb android driver ===> \n"); | |
2627 | android_start() ; | |
2628 | andoid_usbif_driver_on = 1 ; | |
2629 | pr_debug("start usb android driver <=== \n"); | |
2630 | }else if ((msg[0] == '0') && (andoid_usbif_driver_on == 1)){ | |
2631 | pr_debug("stop usb android driver ===> \n"); | |
2632 | printk("stop usb android driver ===> \n"); | |
2633 | andoid_usbif_driver_on = 0 ; | |
2634 | android_stop() ; | |
2635 | ||
2636 | pr_debug("stop usb android driver <=== \n"); | |
2637 | } | |
2638 | ||
2639 | return length; | |
2640 | } | |
2641 | ||
2642 | static const struct file_operations andoid_usbif_proc_fops = { | |
2643 | .owner = THIS_MODULE, | |
2644 | .open = andoid_usbif_proc_open, | |
2645 | .write = andoid_usbif_proc_write, | |
2646 | .read = seq_read, | |
2647 | .llseek = seq_lseek, | |
2648 | ||
2649 | }; | |
2650 | ||
2651 | static int __init init(void) | |
2652 | { | |
2653 | struct android_dev *dev; | |
2654 | int err; | |
2655 | struct proc_dir_entry *prEntry; | |
2656 | ||
2657 | android_class = class_create(THIS_MODULE, "android_usb"); | |
2658 | if (IS_ERR(android_class)) | |
2659 | return PTR_ERR(android_class); | |
2660 | ||
2661 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | |
2662 | if (!dev) { | |
2663 | err = -ENOMEM; | |
2664 | goto err_dev; | |
2665 | } | |
2666 | ||
2667 | dev->disable_depth = 1; | |
2668 | dev->functions = supported_functions; | |
2669 | INIT_LIST_HEAD(&dev->enabled_functions); | |
2670 | INIT_WORK(&dev->work, android_work); | |
2671 | mutex_init(&dev->mutex); | |
2672 | ||
2673 | err = android_create_device(dev); | |
2674 | if (err) { | |
2675 | pr_err("%s: failed to create android device %d", __func__, err); | |
2676 | goto err_create; | |
2677 | } | |
2678 | ||
2679 | _android_dev = dev; | |
2680 | ||
2681 | prEntry = proc_create("android_usbif_init", 0666, NULL, &andoid_usbif_proc_fops); | |
2682 | ||
2683 | if (prEntry) | |
2684 | { | |
2685 | printk("create the android_usbif_init proc OK!\n") ; | |
2686 | }else{ | |
2687 | printk("[ERROR] create the android_usbif_init proc FAIL\n") ; | |
2688 | } | |
2689 | ||
2690 | // set android up at boot up | |
2691 | android_start() ; | |
2692 | andoid_usbif_driver_on = 1 ; | |
2693 | ||
2694 | return 0; | |
2695 | ||
2696 | err_create: | |
2697 | kfree(dev); | |
2698 | err_dev: | |
2699 | class_destroy(android_class); | |
2700 | return err; | |
2701 | } | |
2702 | ||
2703 | late_initcall(init); | |
2704 | ||
2705 | ||
2706 | ||
2707 | static void __exit cleanup(void) | |
2708 | { | |
2709 | printk("[U3D] android cleanup ===> \n") ; | |
2710 | class_destroy(android_class); | |
2711 | kfree(_android_dev); | |
2712 | _android_dev = NULL; | |
2713 | printk("[U3D] android cleanup <=== \n") ; | |
2714 | } | |
2715 | module_exit(cleanup); | |
2716 | ||
2717 | #else | |
2718 | static int __init init(void) | |
2719 | { | |
2720 | struct android_dev *dev; | |
2721 | int err; | |
2722 | ||
2723 | android_class = class_create(THIS_MODULE, "android_usb"); | |
2724 | if (IS_ERR(android_class)) | |
2725 | return PTR_ERR(android_class); | |
2726 | ||
2727 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | |
2728 | if (!dev) { | |
2729 | err = -ENOMEM; | |
2730 | goto err_dev; | |
2731 | } | |
2732 | ||
2733 | dev->disable_depth = 1; | |
2734 | dev->functions = supported_functions; | |
2735 | INIT_LIST_HEAD(&dev->enabled_functions); | |
2736 | INIT_WORK(&dev->work, android_work); | |
2737 | mutex_init(&dev->mutex); | |
2738 | ||
2739 | err = android_create_device(dev); | |
2740 | if (err) { | |
2741 | pr_err("%s: failed to create android device %d", __func__, err); | |
2742 | goto err_create; | |
2743 | } | |
2744 | ||
2745 | _android_dev = dev; | |
2746 | ||
2747 | err = usb_composite_probe(&android_usb_driver); | |
2748 | if (err) { | |
2749 | pr_err("%s: failed to probe driver %d", __func__, err); | |
2750 | goto err_probe; | |
2751 | } | |
2752 | ||
2753 | /* HACK: exchange composite's setup with ours */ | |
2754 | composite_setup_func = android_usb_driver.gadget_driver.setup; | |
2755 | android_usb_driver.gadget_driver.setup = android_setup; | |
2756 | ||
2757 | return 0; | |
2758 | ||
2759 | err_probe: | |
2760 | device_destroy(android_class, dev->dev->devt); | |
2761 | err_create: | |
2762 | kfree(dev); | |
2763 | err_dev: | |
2764 | class_destroy(android_class); | |
2765 | return err; | |
2766 | } | |
2767 | late_initcall(init); | |
2768 | ||
2769 | static void __exit cleanup(void) | |
2770 | { | |
2771 | usb_composite_unregister(&android_usb_driver); | |
2772 | class_destroy(android_class); | |
2773 | kfree(_android_dev); | |
2774 | _android_dev = NULL; | |
2775 | } | |
2776 | module_exit(cleanup); | |
2777 | #endif |