blob: 9dd9c400e30eb86513c2121ee4b09f83027de293 [file] [log] [blame]
Benoit Goby1e8ce152011-12-12 13:01:23 -08001/*
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
19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/fs.h>
22#include <linux/delay.h>
23#include <linux/kernel.h>
24#include <linux/utsname.h>
25#include <linux/platform_device.h>
Steve Mucklef132c6c2012-06-06 18:30:57 -070026#include <linux/pm_qos.h>
Vijayavardhan Vennapusa8ceade82012-11-01 15:11:21 +053027#include <linux/of.h>
Benoit Goby1e8ce152011-12-12 13:01:23 -080028
29#include <linux/usb/ch9.h>
30#include <linux/usb/composite.h>
31#include <linux/usb/gadget.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070032#include <linux/usb/android.h>
Benoit Goby1e8ce152011-12-12 13:01:23 -080033
Manu Gautam43c61a12012-08-22 17:09:37 -070034#include <mach/diag_dload.h>
35
Benoit Goby1e8ce152011-12-12 13:01:23 -080036#include "gadget_chips.h"
37
38/*
39 * Kbuild is not very cooperative with respect to linking separately
40 * compiled library objects into one module. So for now we won't use
41 * separate compilation ... ensuring init/exit sections work to shrink
42 * the runtime footprint, and giving us at least some parts of what
43 * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
44 */
45#include "usbstring.c"
46#include "config.c"
47#include "epautoconf.c"
48#include "composite.c"
49
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070050#include "f_diag.c"
Shimrit Malichia00d7322012-08-05 13:56:28 +030051#include "f_qdss.c"
Manu Gautam1c8ffd72011-09-02 16:00:49 +053052#include "f_rmnet_smd.c"
Manu Gautam8e0719b2011-09-26 14:47:55 +053053#include "f_rmnet_sdio.c"
54#include "f_rmnet_smd_sdio.c"
Manu Gautam2b0234a2011-09-07 16:47:52 +053055#include "f_rmnet.c"
Anna Perel3ee23dd2013-02-26 16:06:40 +020056#ifdef CONFIG_SND_PCM
Mike Lockwood11874822012-08-27 16:43:53 +053057#include "f_audio_source.c"
Anna Perel3ee23dd2013-02-26 16:06:40 +020058#endif
Benoit Goby1e8ce152011-12-12 13:01:23 -080059#include "f_mass_storage.c"
60#include "u_serial.c"
Manu Gautama4d993f2011-08-30 18:25:55 +053061#include "u_sdio.c"
62#include "u_smd.c"
63#include "u_bam.c"
Manu Gautam2b0234a2011-09-07 16:47:52 +053064#include "u_rmnet_ctrl_smd.c"
Bar Weiner0dae81b2013-02-14 13:53:54 +020065#include "u_rmnet_ctrl_qti.c"
Jack Pham427f6922011-11-23 19:42:00 -080066#include "u_ctrl_hsic.c"
67#include "u_data_hsic.c"
Vijayavardhan Vennapusaeb8d2392012-04-03 18:58:49 +053068#include "u_ctrl_hsuart.c"
69#include "u_data_hsuart.c"
Manu Gautama4d993f2011-08-30 18:25:55 +053070#include "f_serial.c"
Benoit Goby1e8ce152011-12-12 13:01:23 -080071#include "f_acm.c"
Benoit Goby2b6862d2011-12-19 14:38:41 -080072#include "f_adb.c"
Chiranjeevi Velempatie130fd02011-11-29 05:06:13 +053073#include "f_ccid.c"
Benoit Gobyf0fbc482011-12-19 14:37:50 -080074#include "f_mtp.c"
Benoit Gobycf3fc062011-12-19 14:39:37 -080075#include "f_accessory.c"
Benoit Goby1e8ce152011-12-12 13:01:23 -080076#define USB_ETH_RNDIS y
77#include "f_rndis.c"
78#include "rndis.c"
Amit Blayf9b352b2013-03-04 15:01:40 +020079#include "f_qc_ecm.c"
Anna Perela8c991d2012-04-09 16:44:46 +030080#include "u_bam_data.c"
81#include "f_mbim.c"
Anna Perelf9d01552012-11-20 15:56:32 +020082#include "f_ecm.c"
Ofir Cohenaef90b72012-07-31 12:37:04 +020083#include "f_qc_rndis.c"
Jack Pham0ad82e62012-09-27 17:31:08 -070084#include "u_ether.c"
Ofir Cohen7b155422012-07-31 13:02:49 +030085#include "u_qc_ether.c"
Pavankumar Kondeti8f6ca4f2012-06-26 09:44:36 +053086#ifdef CONFIG_TARGET_CORE
87#include "f_tcm.c"
88#endif
Jack Pham2ec5fdc2012-09-26 10:13:48 -070089#ifdef CONFIG_SND_PCM
Anna Perel432367a2012-09-20 10:55:32 +030090#include "u_uac1.c"
91#include "f_uac1.c"
Jack Pham2ec5fdc2012-09-26 10:13:48 -070092#endif
Benoit Goby1e8ce152011-12-12 13:01:23 -080093
94MODULE_AUTHOR("Mike Lockwood");
95MODULE_DESCRIPTION("Android Composite USB Driver");
96MODULE_LICENSE("GPL");
97MODULE_VERSION("1.0");
98
99static const char longname[] = "Gadget Android";
100
101/* Default vendor and product IDs, overridden by userspace */
102#define VENDOR_ID 0x18D1
103#define PRODUCT_ID 0x0001
104
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300105#define ANDROID_DEVICE_NODE_NAME_LENGTH 11
106
Benoit Goby1e8ce152011-12-12 13:01:23 -0800107struct android_usb_function {
108 char *name;
109 void *config;
110
111 struct device *dev;
112 char *dev_name;
113 struct device_attribute **attributes;
114
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300115 struct android_dev *android_dev;
116
Benoit Goby1e8ce152011-12-12 13:01:23 -0800117 /* Optional: initialization during gadget bind */
118 int (*init)(struct android_usb_function *, struct usb_composite_dev *);
119 /* Optional: cleanup during gadget unbind */
120 void (*cleanup)(struct android_usb_function *);
Benoit Goby80ba14d2012-03-19 18:56:52 -0700121 /* Optional: called when the function is added the list of
122 * enabled functions */
123 void (*enable)(struct android_usb_function *);
124 /* Optional: called when it is removed */
125 void (*disable)(struct android_usb_function *);
Benoit Goby1e8ce152011-12-12 13:01:23 -0800126
127 int (*bind_config)(struct android_usb_function *,
128 struct usb_configuration *);
129
130 /* Optional: called when the configuration is removed */
131 void (*unbind_config)(struct android_usb_function *,
132 struct usb_configuration *);
133 /* Optional: handle ctrl requests before the device is configured */
134 int (*ctrlrequest)(struct android_usb_function *,
135 struct usb_composite_dev *,
136 const struct usb_ctrlrequest *);
137};
138
Ido Shayevitz68557e32012-11-06 12:40:37 +0200139struct android_usb_function_holder {
140
141 struct android_usb_function *f;
142
143 /* for android_conf.enabled_functions */
144 struct list_head enabled_list;
145};
146
Ido Shayevitzfb5edfe2012-12-26 14:26:37 +0200147/**
148* struct android_dev - represents android USB gadget device
149* @name: device name.
150* @functions: an array of all the supported USB function
151* drivers that this gadget support but not necessarily
152* added to one of the gadget configurations.
153* @cdev: The internal composite device. Android gadget device
154* is a composite device, such that it can support configurations
155* with more than one function driver.
156* @dev: The kernel device that represents this android device.
157* @enabled: True if the android gadget is enabled, means all
158* the configurations were set and all function drivers were
159* bind and ready for USB enumeration.
160* @disable_depth: Number of times the device was disabled, after
161* symmetrical number of enables the device willl be enabled.
162* Used for controlling ADB userspace disable/enable requests.
163* @mutex: Internal mutex for protecting device member fields.
164* @pdata: Platform data fetched from the kernel device platfrom data.
165* @connected: True if got connect notification from the gadget UDC.
166* False if got disconnect notification from the gadget UDC.
167* @sw_connected: Equal to 'connected' only after the connect
168* notification was handled by the android gadget work function.
169* @suspended: True if got suspend notification from the gadget UDC.
170* False if got resume notification from the gadget UDC.
171* @sw_suspended: Equal to 'suspended' only after the susped
172* notification was handled by the android gadget work function.
173* @pm_qos: An attribute string that can be set by user space in order to
174* determine pm_qos policy. Set to 'high' for always demand pm_qos
175* when USB bus is connected and resumed. Set to 'low' for disable
176* any setting of pm_qos by this driver. Default = 'high'.
177* @work: workqueue used for handling notifications from the gadget UDC.
178* @configs: List of configurations currently configured into the device.
179* The android gadget supports more than one configuration. The host
180* may choose one configuration from the suggested.
181* @configs_num: Number of configurations currently configured and existing
182* in the configs list.
183* @list_item: This driver supports more than one android gadget device (for
184* example in order to support multiple USB cores), therefore this is
185* a item in a linked list of android devices.
186*/
Benoit Goby1e8ce152011-12-12 13:01:23 -0800187struct android_dev {
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300188 const char *name;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800189 struct android_usb_function **functions;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800190 struct usb_composite_dev *cdev;
191 struct device *dev;
192
193 bool enabled;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700194 int disable_depth;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800195 struct mutex mutex;
Steve Mucklef132c6c2012-06-06 18:30:57 -0700196 struct android_usb_platform_data *pdata;
197
Benoit Goby1e8ce152011-12-12 13:01:23 -0800198 bool connected;
199 bool sw_connected;
Ido Shayevitzfb5edfe2012-12-26 14:26:37 +0200200 bool suspended;
201 bool sw_suspended;
Ofir Cohen94213a72012-05-03 14:26:32 +0300202 char pm_qos[5];
Steve Mucklef132c6c2012-06-06 18:30:57 -0700203 struct pm_qos_request pm_qos_req_dma;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800204 struct work_struct work;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300205
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300206 /* A list of struct android_configuration */
207 struct list_head configs;
208 int configs_num;
209
210 /* A list node inside the android_dev_list */
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300211 struct list_head list_item;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300212};
213
214struct android_configuration {
215 struct usb_configuration usb_config;
216
217 /* A list of the functions supported by this config */
218 struct list_head enabled_functions;
219
220 /* A list node inside the struct android_dev.configs list */
221 struct list_head list_item;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800222};
223
Manu Gautam43c61a12012-08-22 17:09:37 -0700224struct dload_struct __iomem *diag_dload;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800225static struct class *android_class;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300226static struct list_head android_dev_list;
227static int android_dev_count;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800228static int android_bind_config(struct usb_configuration *c);
229static void android_unbind_config(struct usb_configuration *c);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300230static struct android_dev *cdev_to_android_dev(struct usb_composite_dev *cdev);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300231static struct android_configuration *alloc_android_config
232 (struct android_dev *dev);
233static void free_android_config(struct android_dev *dev,
234 struct android_configuration *conf);
Manu Gautam43c61a12012-08-22 17:09:37 -0700235static int usb_diag_update_pid_and_serial_num(uint32_t pid, const char *snum);
Benoit Goby1e8ce152011-12-12 13:01:23 -0800236
237/* string IDs are assigned dynamically */
238#define STRING_MANUFACTURER_IDX 0
239#define STRING_PRODUCT_IDX 1
240#define STRING_SERIAL_IDX 2
241
242static char manufacturer_string[256];
243static char product_string[256];
244static char serial_string[256];
245
246/* String Table */
247static struct usb_string strings_dev[] = {
248 [STRING_MANUFACTURER_IDX].s = manufacturer_string,
249 [STRING_PRODUCT_IDX].s = product_string,
250 [STRING_SERIAL_IDX].s = serial_string,
251 { } /* end of list */
252};
253
254static struct usb_gadget_strings stringtab_dev = {
255 .language = 0x0409, /* en-us */
256 .strings = strings_dev,
257};
258
259static struct usb_gadget_strings *dev_strings[] = {
260 &stringtab_dev,
261 NULL,
262};
263
264static struct usb_device_descriptor device_desc = {
265 .bLength = sizeof(device_desc),
266 .bDescriptorType = USB_DT_DEVICE,
267 .bcdUSB = __constant_cpu_to_le16(0x0200),
268 .bDeviceClass = USB_CLASS_PER_INTERFACE,
269 .idVendor = __constant_cpu_to_le16(VENDOR_ID),
270 .idProduct = __constant_cpu_to_le16(PRODUCT_ID),
271 .bcdDevice = __constant_cpu_to_le16(0xffff),
272 .bNumConfigurations = 1,
273};
274
Vijayavardhan Vennapusa56e60522012-02-16 15:40:16 +0530275static struct usb_otg_descriptor otg_descriptor = {
276 .bLength = sizeof otg_descriptor,
277 .bDescriptorType = USB_DT_OTG,
278 .bmAttributes = USB_OTG_SRP | USB_OTG_HNP,
279 .bcdOTG = __constant_cpu_to_le16(0x0200),
280};
281
282static const struct usb_descriptor_header *otg_desc[] = {
283 (struct usb_descriptor_header *) &otg_descriptor,
284 NULL,
285};
286
Manu Gautama2b54142012-04-03 14:34:32 +0530287enum android_device_state {
288 USB_DISCONNECTED,
289 USB_CONNECTED,
290 USB_CONFIGURED,
Ido Shayevitzfb5edfe2012-12-26 14:26:37 +0200291 USB_SUSPENDED,
292 USB_RESUMED
Manu Gautama2b54142012-04-03 14:34:32 +0530293};
294
Ofir Cohen94213a72012-05-03 14:26:32 +0300295static void android_pm_qos_update_latency(struct android_dev *dev, int vote)
296{
297 struct android_usb_platform_data *pdata = dev->pdata;
298 u32 swfi_latency = 0;
299 static int last_vote = -1;
300
Ofir Cohen56eb7072012-05-20 11:41:39 +0300301 if (!pdata || vote == last_vote
302 || !pdata->swfi_latency)
Ofir Cohen94213a72012-05-03 14:26:32 +0300303 return;
304
305 swfi_latency = pdata->swfi_latency + 1;
306 if (vote)
307 pm_qos_update_request(&dev->pm_qos_req_dma,
308 swfi_latency);
309 else
310 pm_qos_update_request(&dev->pm_qos_req_dma,
311 PM_QOS_DEFAULT_VALUE);
312 last_vote = vote;
313}
314
Benoit Goby1e8ce152011-12-12 13:01:23 -0800315static void android_work(struct work_struct *data)
316{
317 struct android_dev *dev = container_of(data, struct android_dev, work);
318 struct usb_composite_dev *cdev = dev->cdev;
319 char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL };
320 char *connected[2] = { "USB_STATE=CONNECTED", NULL };
321 char *configured[2] = { "USB_STATE=CONFIGURED", NULL };
Ido Shayevitzfb5edfe2012-12-26 14:26:37 +0200322 char *suspended[2] = { "USB_STATE=SUSPENDED", NULL };
323 char *resumed[2] = { "USB_STATE=RESUMED", NULL };
Benoit Goby1e8ce152011-12-12 13:01:23 -0800324 char **uevent_envp = NULL;
Manu Gautama2b54142012-04-03 14:34:32 +0530325 static enum android_device_state last_uevent, next_state;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800326 unsigned long flags;
Ofir Cohenbcbb1a72012-05-20 16:28:15 +0300327 int pm_qos_vote = -1;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800328
329 spin_lock_irqsave(&cdev->lock, flags);
Ido Shayevitzfb5edfe2012-12-26 14:26:37 +0200330 if (dev->suspended != dev->sw_suspended && cdev->config) {
331 if (strncmp(dev->pm_qos, "low", 3))
332 pm_qos_vote = dev->suspended ? 0 : 1;
333 next_state = dev->suspended ? USB_SUSPENDED : USB_RESUMED;
334 uevent_envp = dev->suspended ? suspended : resumed;
335 } else if (cdev->config) {
Benoit Goby1e8ce152011-12-12 13:01:23 -0800336 uevent_envp = configured;
Manu Gautama2b54142012-04-03 14:34:32 +0530337 next_state = USB_CONFIGURED;
338 } else if (dev->connected != dev->sw_connected) {
Benoit Goby1e8ce152011-12-12 13:01:23 -0800339 uevent_envp = dev->connected ? connected : disconnected;
Manu Gautama2b54142012-04-03 14:34:32 +0530340 next_state = dev->connected ? USB_CONNECTED : USB_DISCONNECTED;
Ofir Cohen94213a72012-05-03 14:26:32 +0300341 if (dev->connected && strncmp(dev->pm_qos, "low", 3))
Ofir Cohenbcbb1a72012-05-20 16:28:15 +0300342 pm_qos_vote = 1;
Ofir Cohen94213a72012-05-03 14:26:32 +0300343 else if (!dev->connected || !strncmp(dev->pm_qos, "low", 3))
Ofir Cohenbcbb1a72012-05-20 16:28:15 +0300344 pm_qos_vote = 0;
Manu Gautama2b54142012-04-03 14:34:32 +0530345 }
Benoit Goby1e8ce152011-12-12 13:01:23 -0800346 dev->sw_connected = dev->connected;
Ido Shayevitzfb5edfe2012-12-26 14:26:37 +0200347 dev->sw_suspended = dev->suspended;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800348 spin_unlock_irqrestore(&cdev->lock, flags);
349
Ofir Cohenbcbb1a72012-05-20 16:28:15 +0300350 if (pm_qos_vote != -1)
351 android_pm_qos_update_latency(dev, pm_qos_vote);
352
Benoit Goby1e8ce152011-12-12 13:01:23 -0800353 if (uevent_envp) {
Manu Gautama2b54142012-04-03 14:34:32 +0530354 /*
355 * Some userspace modules, e.g. MTP, work correctly only if
356 * CONFIGURED uevent is preceded by DISCONNECT uevent.
357 * Check if we missed sending out a DISCONNECT uevent. This can
358 * happen if host PC resets and configures device really quick.
359 */
360 if (((uevent_envp == connected) &&
361 (last_uevent != USB_DISCONNECTED)) ||
362 ((uevent_envp == configured) &&
363 (last_uevent == USB_CONFIGURED))) {
364 pr_info("%s: sent missed DISCONNECT event\n", __func__);
365 kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE,
366 disconnected);
367 msleep(20);
368 }
369 /*
370 * Before sending out CONFIGURED uevent give function drivers
371 * a chance to wakeup userspace threads and notify disconnect
372 */
373 if (uevent_envp == configured)
374 msleep(50);
375
Ido Shayevitzfb5edfe2012-12-26 14:26:37 +0200376 /* Do not notify on suspend / resume */
377 if (next_state != USB_SUSPENDED && next_state != USB_RESUMED) {
378 kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE,
379 uevent_envp);
380 last_uevent = next_state;
381 }
Benoit Goby1e8ce152011-12-12 13:01:23 -0800382 pr_info("%s: sent uevent %s\n", __func__, uevent_envp[0]);
383 } else {
384 pr_info("%s: did not send uevent (%d %d %p)\n", __func__,
385 dev->connected, dev->sw_connected, cdev->config);
386 }
387}
388
Benoit Goby80ba14d2012-03-19 18:56:52 -0700389static void android_enable(struct android_dev *dev)
390{
391 struct usb_composite_dev *cdev = dev->cdev;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300392 struct android_configuration *conf;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700393
394 if (WARN_ON(!dev->disable_depth))
395 return;
396
397 if (--dev->disable_depth == 0) {
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300398
399 list_for_each_entry(conf, &dev->configs, list_item)
400 usb_add_config(cdev, &conf->usb_config,
401 android_bind_config);
402
Benoit Goby80ba14d2012-03-19 18:56:52 -0700403 usb_gadget_connect(cdev->gadget);
404 }
405}
406
407static void android_disable(struct android_dev *dev)
408{
409 struct usb_composite_dev *cdev = dev->cdev;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300410 struct android_configuration *conf;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700411
412 if (dev->disable_depth++ == 0) {
413 usb_gadget_disconnect(cdev->gadget);
414 /* Cancel pending control requests */
415 usb_ep_dequeue(cdev->gadget->ep0, cdev->req);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300416
417 list_for_each_entry(conf, &dev->configs, list_item)
418 usb_remove_config(cdev, &conf->usb_config);
Benoit Goby80ba14d2012-03-19 18:56:52 -0700419 }
420}
Benoit Goby1e8ce152011-12-12 13:01:23 -0800421
422/*-------------------------------------------------------------------------*/
423/* Supported functions initialization */
424
Benoit Goby80ba14d2012-03-19 18:56:52 -0700425struct adb_data {
426 bool opened;
427 bool enabled;
428};
429
Benoit Goby2b6862d2011-12-19 14:38:41 -0800430static int
431adb_function_init(struct android_usb_function *f,
432 struct usb_composite_dev *cdev)
433{
Benoit Goby80ba14d2012-03-19 18:56:52 -0700434 f->config = kzalloc(sizeof(struct adb_data), GFP_KERNEL);
435 if (!f->config)
436 return -ENOMEM;
437
Benoit Goby2b6862d2011-12-19 14:38:41 -0800438 return adb_setup();
439}
440
441static void adb_function_cleanup(struct android_usb_function *f)
442{
443 adb_cleanup();
Benoit Goby80ba14d2012-03-19 18:56:52 -0700444 kfree(f->config);
Benoit Goby2b6862d2011-12-19 14:38:41 -0800445}
446
447static int
448adb_function_bind_config(struct android_usb_function *f,
449 struct usb_configuration *c)
450{
451 return adb_bind_config(c);
452}
453
Benoit Goby80ba14d2012-03-19 18:56:52 -0700454static void adb_android_function_enable(struct android_usb_function *f)
455{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300456 struct android_dev *dev = f->android_dev;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700457 struct adb_data *data = f->config;
458
459 data->enabled = true;
460
461 /* Disable the gadget until adbd is ready */
462 if (!data->opened)
463 android_disable(dev);
464}
465
466static void adb_android_function_disable(struct android_usb_function *f)
467{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300468 struct android_dev *dev = f->android_dev;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700469 struct adb_data *data = f->config;
470
471 data->enabled = false;
472
473 /* Balance the disable that was called in closed_callback */
474 if (!data->opened)
475 android_enable(dev);
476}
477
Benoit Goby2b6862d2011-12-19 14:38:41 -0800478static struct android_usb_function adb_function = {
479 .name = "adb",
Benoit Goby80ba14d2012-03-19 18:56:52 -0700480 .enable = adb_android_function_enable,
481 .disable = adb_android_function_disable,
Benoit Goby2b6862d2011-12-19 14:38:41 -0800482 .init = adb_function_init,
483 .cleanup = adb_function_cleanup,
484 .bind_config = adb_function_bind_config,
485};
486
Benoit Goby80ba14d2012-03-19 18:56:52 -0700487static void adb_ready_callback(void)
488{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300489 struct android_dev *dev = adb_function.android_dev;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700490 struct adb_data *data = adb_function.config;
491
Benoit Goby80ba14d2012-03-19 18:56:52 -0700492 data->opened = true;
493
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300494 if (data->enabled && dev) {
495 mutex_lock(&dev->mutex);
Benoit Goby80ba14d2012-03-19 18:56:52 -0700496 android_enable(dev);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300497 mutex_unlock(&dev->mutex);
498 }
Benoit Goby80ba14d2012-03-19 18:56:52 -0700499}
500
501static void adb_closed_callback(void)
502{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300503 struct android_dev *dev = adb_function.android_dev;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700504 struct adb_data *data = adb_function.config;
505
Benoit Goby80ba14d2012-03-19 18:56:52 -0700506 data->opened = false;
507
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300508 if (data->enabled) {
509 mutex_lock(&dev->mutex);
Benoit Goby80ba14d2012-03-19 18:56:52 -0700510 android_disable(dev);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300511 mutex_unlock(&dev->mutex);
512 }
Benoit Goby80ba14d2012-03-19 18:56:52 -0700513}
514
Benoit Goby2b6862d2011-12-19 14:38:41 -0800515
Benoit Gobyaab96812011-04-19 20:37:33 -0700516/*-------------------------------------------------------------------------*/
517/* Supported functions initialization */
518
Manu Gautam8e0719b2011-09-26 14:47:55 +0530519/* RMNET_SMD */
Manu Gautam1c8ffd72011-09-02 16:00:49 +0530520static int rmnet_smd_function_bind_config(struct android_usb_function *f,
521 struct usb_configuration *c)
522{
523 return rmnet_smd_bind_config(c);
524}
525
526static struct android_usb_function rmnet_smd_function = {
527 .name = "rmnet_smd",
528 .bind_config = rmnet_smd_function_bind_config,
Benoit Goby1e8ce152011-12-12 13:01:23 -0800529};
530
Manu Gautam8e0719b2011-09-26 14:47:55 +0530531/* RMNET_SDIO */
532static int rmnet_sdio_function_bind_config(struct android_usb_function *f,
533 struct usb_configuration *c)
Benoit Goby1e8ce152011-12-12 13:01:23 -0800534{
Manu Gautam8e0719b2011-09-26 14:47:55 +0530535 return rmnet_sdio_function_add(c);
Benoit Goby1e8ce152011-12-12 13:01:23 -0800536}
537
Manu Gautam8e0719b2011-09-26 14:47:55 +0530538static struct android_usb_function rmnet_sdio_function = {
539 .name = "rmnet_sdio",
540 .bind_config = rmnet_sdio_function_bind_config,
541};
542
543/* RMNET_SMD_SDIO */
544static int rmnet_smd_sdio_function_init(struct android_usb_function *f,
545 struct usb_composite_dev *cdev)
546{
547 return rmnet_smd_sdio_init();
548}
549
550static void rmnet_smd_sdio_function_cleanup(struct android_usb_function *f)
551{
552 rmnet_smd_sdio_cleanup();
553}
554
555static int rmnet_smd_sdio_bind_config(struct android_usb_function *f,
556 struct usb_configuration *c)
557{
558 return rmnet_smd_sdio_function_add(c);
559}
560
561static struct device_attribute *rmnet_smd_sdio_attributes[] = {
562 &dev_attr_transport, NULL };
563
564static struct android_usb_function rmnet_smd_sdio_function = {
565 .name = "rmnet_smd_sdio",
566 .init = rmnet_smd_sdio_function_init,
567 .cleanup = rmnet_smd_sdio_function_cleanup,
568 .bind_config = rmnet_smd_sdio_bind_config,
569 .attributes = rmnet_smd_sdio_attributes,
570};
571
Hemant Kumar1b820d52011-11-03 15:08:28 -0700572/*rmnet transport string format(per port):"ctrl0,data0,ctrl1,data1..." */
573#define MAX_XPORT_STR_LEN 50
574static char rmnet_transports[MAX_XPORT_STR_LEN];
Manu Gautam1c8ffd72011-09-02 16:00:49 +0530575
Manu Gautame3e897c2011-09-12 17:18:46 +0530576static void rmnet_function_cleanup(struct android_usb_function *f)
577{
578 frmnet_cleanup();
579}
580
Manu Gautam2b0234a2011-09-07 16:47:52 +0530581static int rmnet_function_bind_config(struct android_usb_function *f,
582 struct usb_configuration *c)
583{
584 int i;
Hemant Kumar1b820d52011-11-03 15:08:28 -0700585 int err = 0;
586 char *ctrl_name;
587 char *data_name;
588 char buf[MAX_XPORT_STR_LEN], *b;
589 static int rmnet_initialized, ports;
Manu Gautam2b0234a2011-09-07 16:47:52 +0530590
Hemant Kumar1b820d52011-11-03 15:08:28 -0700591 if (!rmnet_initialized) {
592 rmnet_initialized = 1;
593 strlcpy(buf, rmnet_transports, sizeof(buf));
594 b = strim(buf);
595 while (b) {
596 ctrl_name = strsep(&b, ",");
597 data_name = strsep(&b, ",");
598 if (ctrl_name && data_name) {
599 err = frmnet_init_port(ctrl_name, data_name);
600 if (err) {
601 pr_err("rmnet: Cannot open ctrl port:"
602 "'%s' data port:'%s'\n",
603 ctrl_name, data_name);
604 goto out;
605 }
606 ports++;
607 }
608 }
609
610 err = rmnet_gport_setup();
611 if (err) {
612 pr_err("rmnet: Cannot setup transports");
613 goto out;
614 }
615 }
616
617 for (i = 0; i < ports; i++) {
618 err = frmnet_bind_config(c, i);
619 if (err) {
Manu Gautam2b0234a2011-09-07 16:47:52 +0530620 pr_err("Could not bind rmnet%u config\n", i);
621 break;
622 }
623 }
Hemant Kumar1b820d52011-11-03 15:08:28 -0700624out:
625 return err;
Manu Gautam2b0234a2011-09-07 16:47:52 +0530626}
627
Hemant Kumar1b820d52011-11-03 15:08:28 -0700628static ssize_t rmnet_transports_show(struct device *dev,
Manu Gautam2b0234a2011-09-07 16:47:52 +0530629 struct device_attribute *attr, char *buf)
630{
Hemant Kumar1b820d52011-11-03 15:08:28 -0700631 return snprintf(buf, PAGE_SIZE, "%s\n", rmnet_transports);
Manu Gautam2b0234a2011-09-07 16:47:52 +0530632}
633
Hemant Kumar1b820d52011-11-03 15:08:28 -0700634static ssize_t rmnet_transports_store(
635 struct device *device, struct device_attribute *attr,
636 const char *buff, size_t size)
Manu Gautam2b0234a2011-09-07 16:47:52 +0530637{
Hemant Kumar1b820d52011-11-03 15:08:28 -0700638 strlcpy(rmnet_transports, buff, sizeof(rmnet_transports));
Manu Gautam2b0234a2011-09-07 16:47:52 +0530639
Manu Gautam2b0234a2011-09-07 16:47:52 +0530640 return size;
641}
642
Hemant Kumar1b820d52011-11-03 15:08:28 -0700643static struct device_attribute dev_attr_rmnet_transports =
644 __ATTR(transports, S_IRUGO | S_IWUSR,
645 rmnet_transports_show,
646 rmnet_transports_store);
Manu Gautam2b0234a2011-09-07 16:47:52 +0530647static struct device_attribute *rmnet_function_attributes[] = {
Hemant Kumar1b820d52011-11-03 15:08:28 -0700648 &dev_attr_rmnet_transports,
649 NULL };
Manu Gautam2b0234a2011-09-07 16:47:52 +0530650
651static struct android_usb_function rmnet_function = {
652 .name = "rmnet",
Manu Gautame3e897c2011-09-12 17:18:46 +0530653 .cleanup = rmnet_function_cleanup,
Manu Gautam2b0234a2011-09-07 16:47:52 +0530654 .bind_config = rmnet_function_bind_config,
655 .attributes = rmnet_function_attributes,
656};
657
Amit Blayf9b352b2013-03-04 15:01:40 +0200658/* ecm transport string */
659static char ecm_transports[MAX_XPORT_STR_LEN];
660
Ofir Cohen7b155422012-07-31 13:02:49 +0300661struct ecm_function_config {
662 u8 ethaddr[ETH_ALEN];
663};
664
665static int ecm_function_init(struct android_usb_function *f,
666 struct usb_composite_dev *cdev)
667{
668 f->config = kzalloc(sizeof(struct ecm_function_config), GFP_KERNEL);
669 if (!f->config)
670 return -ENOMEM;
671 return 0;
672}
673
674static void ecm_function_cleanup(struct android_usb_function *f)
675{
676 kfree(f->config);
677 f->config = NULL;
678}
679
680static int ecm_qc_function_bind_config(struct android_usb_function *f,
681 struct usb_configuration *c)
682{
683 int ret;
Amit Blayf9b352b2013-03-04 15:01:40 +0200684 char *trans;
Ofir Cohen7b155422012-07-31 13:02:49 +0300685 struct ecm_function_config *ecm = f->config;
686
687 if (!ecm) {
688 pr_err("%s: ecm_pdata\n", __func__);
689 return -EINVAL;
690 }
691
692 pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
693 ecm->ethaddr[0], ecm->ethaddr[1], ecm->ethaddr[2],
694 ecm->ethaddr[3], ecm->ethaddr[4], ecm->ethaddr[5]);
695
Amit Blayf9b352b2013-03-04 15:01:40 +0200696 pr_debug("%s: ecm_transport is %s", __func__, ecm_transports);
697
698 trans = strim(ecm_transports);
699 if (strcmp("BAM2BAM_IPA", trans)) {
700 ret = gether_qc_setup_name(c->cdev->gadget,
701 ecm->ethaddr, "ecm");
702 if (ret) {
703 pr_err("%s: gether_setup failed\n", __func__);
704 return ret;
705 }
Ofir Cohen7b155422012-07-31 13:02:49 +0300706 }
707
Amit Blayf9b352b2013-03-04 15:01:40 +0200708 return ecm_qc_bind_config(c, ecm->ethaddr, trans);
Ofir Cohen7b155422012-07-31 13:02:49 +0300709}
710
711static void ecm_qc_function_unbind_config(struct android_usb_function *f,
712 struct usb_configuration *c)
713{
Amit Blayf9b352b2013-03-04 15:01:40 +0200714 char *trans = strim(ecm_transports);
715
716 if (strcmp("BAM2BAM_IPA", trans))
717 gether_qc_cleanup_name("ecm0");
Ofir Cohen7b155422012-07-31 13:02:49 +0300718}
719
720static ssize_t ecm_ethaddr_show(struct device *dev,
721 struct device_attribute *attr, char *buf)
722{
723 struct android_usb_function *f = dev_get_drvdata(dev);
724 struct ecm_function_config *ecm = f->config;
725 return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n",
726 ecm->ethaddr[0], ecm->ethaddr[1], ecm->ethaddr[2],
727 ecm->ethaddr[3], ecm->ethaddr[4], ecm->ethaddr[5]);
728}
729
730static ssize_t ecm_ethaddr_store(struct device *dev,
731 struct device_attribute *attr, const char *buf, size_t size)
732{
733 struct android_usb_function *f = dev_get_drvdata(dev);
734 struct ecm_function_config *ecm = f->config;
735
736 if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
737 (int *)&ecm->ethaddr[0], (int *)&ecm->ethaddr[1],
738 (int *)&ecm->ethaddr[2], (int *)&ecm->ethaddr[3],
739 (int *)&ecm->ethaddr[4], (int *)&ecm->ethaddr[5]) == 6)
740 return size;
741 return -EINVAL;
742}
743
744static DEVICE_ATTR(ecm_ethaddr, S_IRUGO | S_IWUSR, ecm_ethaddr_show,
745 ecm_ethaddr_store);
746
Amit Blayf9b352b2013-03-04 15:01:40 +0200747static ssize_t ecm_transports_show(struct device *dev,
748 struct device_attribute *attr, char *buf)
749{
750 return snprintf(buf, PAGE_SIZE, "%s\n", ecm_transports);
751}
752
753static ssize_t ecm_transports_store(struct device *dev,
754 struct device_attribute *attr, const char *buf, size_t size)
755{
756 strlcpy(ecm_transports, buf, sizeof(ecm_transports));
757 return size;
758}
759
760static DEVICE_ATTR(ecm_transports, S_IRUGO | S_IWUSR, ecm_transports_show,
761 ecm_transports_store);
762
Ofir Cohen7b155422012-07-31 13:02:49 +0300763static struct device_attribute *ecm_function_attributes[] = {
Amit Blayf9b352b2013-03-04 15:01:40 +0200764 &dev_attr_ecm_transports,
Ofir Cohen7b155422012-07-31 13:02:49 +0300765 &dev_attr_ecm_ethaddr,
766 NULL
767};
768
769static struct android_usb_function ecm_qc_function = {
770 .name = "ecm_qc",
771 .init = ecm_function_init,
772 .cleanup = ecm_function_cleanup,
773 .bind_config = ecm_qc_function_bind_config,
774 .unbind_config = ecm_qc_function_unbind_config,
775 .attributes = ecm_function_attributes,
776};
Anna Perela8c991d2012-04-09 16:44:46 +0300777
778/* MBIM - used with BAM */
779#define MAX_MBIM_INSTANCES 1
780
781static int mbim_function_init(struct android_usb_function *f,
782 struct usb_composite_dev *cdev)
783{
784 return mbim_init(MAX_MBIM_INSTANCES);
785}
786
787static void mbim_function_cleanup(struct android_usb_function *f)
788{
789 fmbim_cleanup();
790}
791
792static int mbim_function_bind_config(struct android_usb_function *f,
793 struct usb_configuration *c)
794{
795 return mbim_bind_config(c, 0);
796}
797
Jack Pham2df2f702012-10-11 19:08:24 -0700798static int mbim_function_ctrlrequest(struct android_usb_function *f,
799 struct usb_composite_dev *cdev,
800 const struct usb_ctrlrequest *c)
801{
802 return mbim_ctrlrequest(cdev, c);
803}
804
Anna Perela8c991d2012-04-09 16:44:46 +0300805static struct android_usb_function mbim_function = {
806 .name = "usb_mbim",
807 .cleanup = mbim_function_cleanup,
808 .bind_config = mbim_function_bind_config,
809 .init = mbim_function_init,
Jack Pham2df2f702012-10-11 19:08:24 -0700810 .ctrlrequest = mbim_function_ctrlrequest,
Anna Perela8c991d2012-04-09 16:44:46 +0300811};
812
Jack Pham2ec5fdc2012-09-26 10:13:48 -0700813#ifdef CONFIG_SND_PCM
Anna Perel432367a2012-09-20 10:55:32 +0300814/* PERIPHERAL AUDIO */
815static int audio_function_bind_config(struct android_usb_function *f,
816 struct usb_configuration *c)
817{
818 return audio_bind_config(c);
819}
820
821static struct android_usb_function audio_function = {
822 .name = "audio",
823 .bind_config = audio_function_bind_config,
824};
Jack Pham2ec5fdc2012-09-26 10:13:48 -0700825#endif
Anna Perel432367a2012-09-20 10:55:32 +0300826
Anna Perela8c991d2012-04-09 16:44:46 +0300827
Manu Gautam8e0719b2011-09-26 14:47:55 +0530828/* DIAG */
Manu Gautam2b0234a2011-09-07 16:47:52 +0530829static char diag_clients[32]; /*enabled DIAG clients- "diag[,diag_mdm]" */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700830static ssize_t clients_store(
831 struct device *device, struct device_attribute *attr,
832 const char *buff, size_t size)
833{
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +0530834 strlcpy(diag_clients, buff, sizeof(diag_clients));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700835
836 return size;
837}
838
839static DEVICE_ATTR(clients, S_IWUSR, NULL, clients_store);
840static struct device_attribute *diag_function_attributes[] =
841 { &dev_attr_clients, NULL };
842
843static int diag_function_init(struct android_usb_function *f,
844 struct usb_composite_dev *cdev)
845{
846 return diag_setup();
847}
848
849static void diag_function_cleanup(struct android_usb_function *f)
850{
851 diag_cleanup();
852}
853
854static int diag_function_bind_config(struct android_usb_function *f,
855 struct usb_configuration *c)
856{
857 char *name;
858 char buf[32], *b;
Manu Gautamc5760302011-08-25 14:30:24 +0530859 int once = 0, err = -1;
Jack Phamb830a6c2011-12-12 22:35:27 -0800860 int (*notify)(uint32_t, const char *);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300861 struct android_dev *dev = cdev_to_android_dev(c->cdev);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700862
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +0530863 strlcpy(buf, diag_clients, sizeof(buf));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700864 b = strim(buf);
865
866 while (b) {
Jack Phamb830a6c2011-12-12 22:35:27 -0800867 notify = NULL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700868 name = strsep(&b, ",");
Manu Gautamc5760302011-08-25 14:30:24 +0530869 /* Allow only first diag channel to update pid and serial no */
Manu Gautam43c61a12012-08-22 17:09:37 -0700870 if (!once++) {
871 if (dev->pdata && dev->pdata->update_pid_and_serial_num)
872 notify = dev->pdata->update_pid_and_serial_num;
873 else
874 notify = usb_diag_update_pid_and_serial_num;
875 }
Manu Gautamc5760302011-08-25 14:30:24 +0530876
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700877 if (name) {
Manu Gautamc5760302011-08-25 14:30:24 +0530878 err = diag_function_add(c, name, notify);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700879 if (err)
880 pr_err("diag: Cannot open channel '%s'", name);
881 }
882 }
883
884 return err;
885}
886
887static struct android_usb_function diag_function = {
888 .name = "diag",
889 .init = diag_function_init,
890 .cleanup = diag_function_cleanup,
891 .bind_config = diag_function_bind_config,
892 .attributes = diag_function_attributes,
893};
894
Shimrit Malichia00d7322012-08-05 13:56:28 +0300895/* DEBUG */
896static int qdss_function_init(struct android_usb_function *f,
897 struct usb_composite_dev *cdev)
898{
899 return qdss_setup();
900}
901
902static void qdss_function_cleanup(struct android_usb_function *f)
903{
904 qdss_cleanup();
905}
906
907static int qdss_function_bind_config(struct android_usb_function *f,
908 struct usb_configuration *c)
909{
910 int err = -1;
911
912 err = qdss_bind_config(c, "qdss");
913 if (err)
914 pr_err("qdss: Cannot open channel qdss");
915
916 return err;
917}
918
919static struct android_usb_function qdss_function = {
920 .name = "qdss",
921 .init = qdss_function_init,
922 .cleanup = qdss_function_cleanup,
923 .bind_config = qdss_function_bind_config,
924};
925
Manu Gautam8e0719b2011-09-26 14:47:55 +0530926/* SERIAL */
Manu Gautam2b0234a2011-09-07 16:47:52 +0530927static char serial_transports[32]; /*enabled FSERIAL ports - "tty[,sdio]"*/
Manu Gautama4d993f2011-08-30 18:25:55 +0530928static ssize_t serial_transports_store(
929 struct device *device, struct device_attribute *attr,
930 const char *buff, size_t size)
931{
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +0530932 strlcpy(serial_transports, buff, sizeof(serial_transports));
Manu Gautama4d993f2011-08-30 18:25:55 +0530933
934 return size;
935}
936
937static DEVICE_ATTR(transports, S_IWUSR, NULL, serial_transports_store);
938static struct device_attribute *serial_function_attributes[] =
939 { &dev_attr_transports, NULL };
940
941static void serial_function_cleanup(struct android_usb_function *f)
942{
943 gserial_cleanup();
944}
945
946static int serial_function_bind_config(struct android_usb_function *f,
947 struct usb_configuration *c)
948{
949 char *name;
950 char buf[32], *b;
951 int err = -1, i;
952 static int serial_initialized = 0, ports = 0;
953
954 if (serial_initialized)
955 goto bind_config;
956
957 serial_initialized = 1;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +0530958 strlcpy(buf, serial_transports, sizeof(buf));
Manu Gautama4d993f2011-08-30 18:25:55 +0530959 b = strim(buf);
960
961 while (b) {
962 name = strsep(&b, ",");
963
964 if (name) {
965 err = gserial_init_port(ports, name);
966 if (err) {
967 pr_err("serial: Cannot open port '%s'", name);
968 goto out;
969 }
970 ports++;
971 }
972 }
973 err = gport_setup(c);
974 if (err) {
975 pr_err("serial: Cannot setup transports");
976 goto out;
977 }
978
979bind_config:
Lena Salmand092f2d2012-03-12 17:27:24 +0200980 for (i = 0; i < ports; i++) {
Manu Gautama4d993f2011-08-30 18:25:55 +0530981 err = gser_bind_config(c, i);
982 if (err) {
983 pr_err("serial: bind_config failed for port %d", i);
984 goto out;
985 }
986 }
987
988out:
989 return err;
990}
991
992static struct android_usb_function serial_function = {
993 .name = "serial",
994 .cleanup = serial_function_cleanup,
995 .bind_config = serial_function_bind_config,
996 .attributes = serial_function_attributes,
997};
998
Anji jonnala92be1b42011-12-19 09:44:41 +0530999/* ACM */
1000static char acm_transports[32]; /*enabled ACM ports - "tty[,sdio]"*/
1001static ssize_t acm_transports_store(
1002 struct device *device, struct device_attribute *attr,
1003 const char *buff, size_t size)
1004{
1005 strlcpy(acm_transports, buff, sizeof(acm_transports));
1006
1007 return size;
1008}
1009
1010static DEVICE_ATTR(acm_transports, S_IWUSR, NULL, acm_transports_store);
1011static struct device_attribute *acm_function_attributes[] = {
1012 &dev_attr_acm_transports, NULL };
1013
Benoit Goby1e8ce152011-12-12 13:01:23 -08001014static void acm_function_cleanup(struct android_usb_function *f)
1015{
1016 gserial_cleanup();
Benoit Goby1e8ce152011-12-12 13:01:23 -08001017}
1018
Anji jonnala92be1b42011-12-19 09:44:41 +05301019static int acm_function_bind_config(struct android_usb_function *f,
1020 struct usb_configuration *c)
Benoit Goby1e8ce152011-12-12 13:01:23 -08001021{
Anji jonnala92be1b42011-12-19 09:44:41 +05301022 char *name;
1023 char buf[32], *b;
1024 int err = -1, i;
1025 static int acm_initialized, ports;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001026
Anji jonnala92be1b42011-12-19 09:44:41 +05301027 if (acm_initialized)
1028 goto bind_config;
1029
1030 acm_initialized = 1;
1031 strlcpy(buf, acm_transports, sizeof(buf));
1032 b = strim(buf);
1033
1034 while (b) {
1035 name = strsep(&b, ",");
1036
1037 if (name) {
1038 err = acm_init_port(ports, name);
1039 if (err) {
1040 pr_err("acm: Cannot open port '%s'", name);
1041 goto out;
1042 }
1043 ports++;
1044 }
1045 }
1046 err = acm_port_setup(c);
1047 if (err) {
1048 pr_err("acm: Cannot setup transports");
1049 goto out;
1050 }
1051
1052bind_config:
1053 for (i = 0; i < ports; i++) {
1054 err = acm_bind_config(c, i);
1055 if (err) {
1056 pr_err("acm: bind_config failed for port %d", i);
1057 goto out;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001058 }
1059 }
1060
Anji jonnala92be1b42011-12-19 09:44:41 +05301061out:
1062 return err;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001063}
Benoit Goby1e8ce152011-12-12 13:01:23 -08001064static struct android_usb_function acm_function = {
1065 .name = "acm",
Benoit Goby1e8ce152011-12-12 13:01:23 -08001066 .cleanup = acm_function_cleanup,
1067 .bind_config = acm_function_bind_config,
1068 .attributes = acm_function_attributes,
1069};
1070
Chiranjeevi Velempatie130fd02011-11-29 05:06:13 +05301071/* CCID */
1072static int ccid_function_init(struct android_usb_function *f,
1073 struct usb_composite_dev *cdev)
1074{
1075 return ccid_setup();
1076}
Benoit Goby1e8ce152011-12-12 13:01:23 -08001077
Chiranjeevi Velempatie130fd02011-11-29 05:06:13 +05301078static void ccid_function_cleanup(struct android_usb_function *f)
1079{
1080 ccid_cleanup();
1081}
1082
1083static int ccid_function_bind_config(struct android_usb_function *f,
1084 struct usb_configuration *c)
1085{
1086 return ccid_bind_config(c);
1087}
1088
1089static struct android_usb_function ccid_function = {
1090 .name = "ccid",
1091 .init = ccid_function_init,
1092 .cleanup = ccid_function_cleanup,
1093 .bind_config = ccid_function_bind_config,
1094};
1095
Steve Mucklef132c6c2012-06-06 18:30:57 -07001096static int mtp_function_init(struct android_usb_function *f,
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001097 struct usb_composite_dev *cdev)
1098{
1099 return mtp_setup();
1100}
1101
1102static void mtp_function_cleanup(struct android_usb_function *f)
1103{
1104 mtp_cleanup();
1105}
1106
Steve Mucklef132c6c2012-06-06 18:30:57 -07001107static int mtp_function_bind_config(struct android_usb_function *f,
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001108 struct usb_configuration *c)
1109{
1110 return mtp_bind_config(c, false);
1111}
1112
Mike Lockwoodcf7addf2011-06-01 22:17:36 -04001113static int ptp_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev)
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001114{
1115 /* nothing to do - initialization is handled by mtp_function_init */
1116 return 0;
1117}
1118
1119static void ptp_function_cleanup(struct android_usb_function *f)
1120{
1121 /* nothing to do - cleanup is handled by mtp_function_cleanup */
1122}
1123
Mike Lockwoodcf7addf2011-06-01 22:17:36 -04001124static int ptp_function_bind_config(struct android_usb_function *f, struct usb_configuration *c)
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001125{
1126 return mtp_bind_config(c, true);
1127}
1128
1129static int mtp_function_ctrlrequest(struct android_usb_function *f,
1130 struct usb_composite_dev *cdev,
1131 const struct usb_ctrlrequest *c)
1132{
1133 return mtp_ctrlrequest(cdev, c);
1134}
1135
1136static struct android_usb_function mtp_function = {
1137 .name = "mtp",
1138 .init = mtp_function_init,
1139 .cleanup = mtp_function_cleanup,
1140 .bind_config = mtp_function_bind_config,
1141 .ctrlrequest = mtp_function_ctrlrequest,
1142};
1143
1144/* PTP function is same as MTP with slightly different interface descriptor */
1145static struct android_usb_function ptp_function = {
1146 .name = "ptp",
1147 .init = ptp_function_init,
1148 .cleanup = ptp_function_cleanup,
1149 .bind_config = ptp_function_bind_config,
1150};
1151
1152
Benoit Goby1e8ce152011-12-12 13:01:23 -08001153struct rndis_function_config {
1154 u8 ethaddr[ETH_ALEN];
1155 u32 vendorID;
Ofir Cohenaef90b72012-07-31 12:37:04 +02001156 u8 max_pkt_per_xfer;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001157 char manufacturer[256];
1158 /* "Wireless" RNDIS; auto-detected by Windows */
1159 bool wceis;
1160};
1161
1162static int
1163rndis_function_init(struct android_usb_function *f,
1164 struct usb_composite_dev *cdev)
1165{
1166 f->config = kzalloc(sizeof(struct rndis_function_config), GFP_KERNEL);
1167 if (!f->config)
1168 return -ENOMEM;
1169 return 0;
1170}
1171
1172static void rndis_function_cleanup(struct android_usb_function *f)
1173{
1174 kfree(f->config);
1175 f->config = NULL;
1176}
1177
Ofir Cohenaef90b72012-07-31 12:37:04 +02001178static int rndis_qc_function_init(struct android_usb_function *f,
1179 struct usb_composite_dev *cdev)
1180{
1181 f->config = kzalloc(sizeof(struct rndis_function_config), GFP_KERNEL);
1182 if (!f->config)
1183 return -ENOMEM;
1184
1185 return rndis_qc_init();
1186}
1187
1188static void rndis_qc_function_cleanup(struct android_usb_function *f)
1189{
1190 rndis_qc_cleanup();
1191 kfree(f->config);
1192}
1193
Benoit Goby1e8ce152011-12-12 13:01:23 -08001194static int
1195rndis_function_bind_config(struct android_usb_function *f,
1196 struct usb_configuration *c)
1197{
1198 int ret;
1199 struct rndis_function_config *rndis = f->config;
1200
1201 if (!rndis) {
1202 pr_err("%s: rndis_pdata\n", __func__);
1203 return -1;
1204 }
1205
1206 pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
1207 rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
1208 rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
1209
1210 ret = gether_setup_name(c->cdev->gadget, rndis->ethaddr, "rndis");
1211 if (ret) {
1212 pr_err("%s: gether_setup failed\n", __func__);
1213 return ret;
1214 }
1215
1216 if (rndis->wceis) {
1217 /* "Wireless" RNDIS; auto-detected by Windows */
1218 rndis_iad_descriptor.bFunctionClass =
1219 USB_CLASS_WIRELESS_CONTROLLER;
1220 rndis_iad_descriptor.bFunctionSubClass = 0x01;
1221 rndis_iad_descriptor.bFunctionProtocol = 0x03;
1222 rndis_control_intf.bInterfaceClass =
1223 USB_CLASS_WIRELESS_CONTROLLER;
1224 rndis_control_intf.bInterfaceSubClass = 0x01;
1225 rndis_control_intf.bInterfaceProtocol = 0x03;
1226 }
1227
1228 return rndis_bind_config_vendor(c, rndis->ethaddr, rndis->vendorID,
1229 rndis->manufacturer);
1230}
1231
Ofir Cohenaef90b72012-07-31 12:37:04 +02001232static int rndis_qc_function_bind_config(struct android_usb_function *f,
1233 struct usb_configuration *c)
1234{
1235 int ret;
1236 struct rndis_function_config *rndis = f->config;
1237
1238 if (!rndis) {
1239 pr_err("%s: rndis_pdata\n", __func__);
1240 return -EINVAL;
1241 }
1242
1243 pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
1244 rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
1245 rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
1246
1247 ret = gether_qc_setup_name(c->cdev->gadget, rndis->ethaddr, "rndis");
1248 if (ret) {
1249 pr_err("%s: gether_setup failed\n", __func__);
1250 return ret;
1251 }
1252
1253 if (rndis->wceis) {
1254 /* "Wireless" RNDIS; auto-detected by Windows */
1255 rndis_qc_iad_descriptor.bFunctionClass =
1256 USB_CLASS_WIRELESS_CONTROLLER;
1257 rndis_qc_iad_descriptor.bFunctionSubClass = 0x01;
1258 rndis_qc_iad_descriptor.bFunctionProtocol = 0x03;
1259 rndis_qc_control_intf.bInterfaceClass =
1260 USB_CLASS_WIRELESS_CONTROLLER;
1261 rndis_qc_control_intf.bInterfaceSubClass = 0x01;
1262 rndis_qc_control_intf.bInterfaceProtocol = 0x03;
1263 }
1264
1265 return rndis_qc_bind_config_vendor(c, rndis->ethaddr, rndis->vendorID,
1266 rndis->manufacturer,
1267 rndis->max_pkt_per_xfer);
1268}
1269
Benoit Goby1e8ce152011-12-12 13:01:23 -08001270static void rndis_function_unbind_config(struct android_usb_function *f,
1271 struct usb_configuration *c)
1272{
1273 gether_cleanup();
1274}
1275
Ofir Cohenaef90b72012-07-31 12:37:04 +02001276static void rndis_qc_function_unbind_config(struct android_usb_function *f,
1277 struct usb_configuration *c)
1278{
Amit Blayd6d690a2012-10-16 13:37:42 +02001279 gether_qc_cleanup_name("rndis0");
Ofir Cohenaef90b72012-07-31 12:37:04 +02001280}
1281
Benoit Goby1e8ce152011-12-12 13:01:23 -08001282static ssize_t rndis_manufacturer_show(struct device *dev,
1283 struct device_attribute *attr, char *buf)
1284{
1285 struct android_usb_function *f = dev_get_drvdata(dev);
1286 struct rndis_function_config *config = f->config;
Steve Mucklef132c6c2012-06-06 18:30:57 -07001287
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301288 return snprintf(buf, PAGE_SIZE, "%s\n", config->manufacturer);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001289}
1290
1291static ssize_t rndis_manufacturer_store(struct device *dev,
1292 struct device_attribute *attr, const char *buf, size_t size)
1293{
1294 struct android_usb_function *f = dev_get_drvdata(dev);
1295 struct rndis_function_config *config = f->config;
1296
1297 if (size >= sizeof(config->manufacturer))
1298 return -EINVAL;
Steve Mucklef132c6c2012-06-06 18:30:57 -07001299
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301300 if (sscanf(buf, "%255s", config->manufacturer) == 1)
Benoit Goby1e8ce152011-12-12 13:01:23 -08001301 return size;
1302 return -1;
1303}
1304
1305static DEVICE_ATTR(manufacturer, S_IRUGO | S_IWUSR, rndis_manufacturer_show,
1306 rndis_manufacturer_store);
1307
1308static ssize_t rndis_wceis_show(struct device *dev,
1309 struct device_attribute *attr, char *buf)
1310{
1311 struct android_usb_function *f = dev_get_drvdata(dev);
1312 struct rndis_function_config *config = f->config;
Steve Mucklef132c6c2012-06-06 18:30:57 -07001313
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301314 return snprintf(buf, PAGE_SIZE, "%d\n", config->wceis);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001315}
1316
1317static ssize_t rndis_wceis_store(struct device *dev,
1318 struct device_attribute *attr, const char *buf, size_t size)
1319{
1320 struct android_usb_function *f = dev_get_drvdata(dev);
1321 struct rndis_function_config *config = f->config;
1322 int value;
1323
1324 if (sscanf(buf, "%d", &value) == 1) {
1325 config->wceis = value;
1326 return size;
1327 }
1328 return -EINVAL;
1329}
1330
1331static DEVICE_ATTR(wceis, S_IRUGO | S_IWUSR, rndis_wceis_show,
1332 rndis_wceis_store);
1333
1334static ssize_t rndis_ethaddr_show(struct device *dev,
1335 struct device_attribute *attr, char *buf)
1336{
1337 struct android_usb_function *f = dev_get_drvdata(dev);
1338 struct rndis_function_config *rndis = f->config;
Steve Mucklef132c6c2012-06-06 18:30:57 -07001339
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301340 return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n",
Benoit Goby1e8ce152011-12-12 13:01:23 -08001341 rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
1342 rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
1343}
1344
1345static ssize_t rndis_ethaddr_store(struct device *dev,
1346 struct device_attribute *attr, const char *buf, size_t size)
1347{
1348 struct android_usb_function *f = dev_get_drvdata(dev);
1349 struct rndis_function_config *rndis = f->config;
1350
1351 if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
1352 (int *)&rndis->ethaddr[0], (int *)&rndis->ethaddr[1],
1353 (int *)&rndis->ethaddr[2], (int *)&rndis->ethaddr[3],
1354 (int *)&rndis->ethaddr[4], (int *)&rndis->ethaddr[5]) == 6)
1355 return size;
1356 return -EINVAL;
1357}
1358
1359static DEVICE_ATTR(ethaddr, S_IRUGO | S_IWUSR, rndis_ethaddr_show,
1360 rndis_ethaddr_store);
1361
1362static ssize_t rndis_vendorID_show(struct device *dev,
1363 struct device_attribute *attr, char *buf)
1364{
1365 struct android_usb_function *f = dev_get_drvdata(dev);
1366 struct rndis_function_config *config = f->config;
Steve Mucklef132c6c2012-06-06 18:30:57 -07001367
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301368 return snprintf(buf, PAGE_SIZE, "%04x\n", config->vendorID);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001369}
1370
1371static ssize_t rndis_vendorID_store(struct device *dev,
1372 struct device_attribute *attr, const char *buf, size_t size)
1373{
1374 struct android_usb_function *f = dev_get_drvdata(dev);
1375 struct rndis_function_config *config = f->config;
1376 int value;
1377
1378 if (sscanf(buf, "%04x", &value) == 1) {
1379 config->vendorID = value;
1380 return size;
1381 }
1382 return -EINVAL;
1383}
1384
1385static DEVICE_ATTR(vendorID, S_IRUGO | S_IWUSR, rndis_vendorID_show,
1386 rndis_vendorID_store);
1387
Ofir Cohenaef90b72012-07-31 12:37:04 +02001388static ssize_t rndis_max_pkt_per_xfer_show(struct device *dev,
1389 struct device_attribute *attr, char *buf)
1390{
1391 struct android_usb_function *f = dev_get_drvdata(dev);
1392 struct rndis_function_config *config = f->config;
1393 return snprintf(buf, PAGE_SIZE, "%d\n", config->max_pkt_per_xfer);
1394}
1395
1396static ssize_t rndis_max_pkt_per_xfer_store(struct device *dev,
1397 struct device_attribute *attr, const char *buf, size_t size)
1398{
1399 struct android_usb_function *f = dev_get_drvdata(dev);
1400 struct rndis_function_config *config = f->config;
1401 int value;
1402
1403 if (sscanf(buf, "%d", &value) == 1) {
1404 config->max_pkt_per_xfer = value;
1405 return size;
1406 }
1407 return -EINVAL;
1408}
1409
1410static DEVICE_ATTR(max_pkt_per_xfer, S_IRUGO | S_IWUSR,
1411 rndis_max_pkt_per_xfer_show,
1412 rndis_max_pkt_per_xfer_store);
1413
Benoit Goby1e8ce152011-12-12 13:01:23 -08001414static struct device_attribute *rndis_function_attributes[] = {
1415 &dev_attr_manufacturer,
1416 &dev_attr_wceis,
1417 &dev_attr_ethaddr,
1418 &dev_attr_vendorID,
Ofir Cohenaef90b72012-07-31 12:37:04 +02001419 &dev_attr_max_pkt_per_xfer,
Benoit Goby1e8ce152011-12-12 13:01:23 -08001420 NULL
1421};
1422
1423static struct android_usb_function rndis_function = {
1424 .name = "rndis",
1425 .init = rndis_function_init,
1426 .cleanup = rndis_function_cleanup,
1427 .bind_config = rndis_function_bind_config,
1428 .unbind_config = rndis_function_unbind_config,
1429 .attributes = rndis_function_attributes,
1430};
1431
Ofir Cohenaef90b72012-07-31 12:37:04 +02001432static struct android_usb_function rndis_qc_function = {
1433 .name = "rndis_qc",
1434 .init = rndis_qc_function_init,
1435 .cleanup = rndis_qc_function_cleanup,
1436 .bind_config = rndis_qc_function_bind_config,
1437 .unbind_config = rndis_qc_function_unbind_config,
1438 .attributes = rndis_function_attributes,
1439};
Benoit Goby1e8ce152011-12-12 13:01:23 -08001440
Anna Perelf9d01552012-11-20 15:56:32 +02001441static int ecm_function_bind_config(struct android_usb_function *f,
1442 struct usb_configuration *c)
1443{
1444 int ret;
1445 struct ecm_function_config *ecm = f->config;
1446
1447 if (!ecm) {
1448 pr_err("%s: ecm_pdata\n", __func__);
1449 return -EINVAL;
1450 }
1451
1452 pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
1453 ecm->ethaddr[0], ecm->ethaddr[1], ecm->ethaddr[2],
1454 ecm->ethaddr[3], ecm->ethaddr[4], ecm->ethaddr[5]);
1455
1456 ret = gether_setup_name(c->cdev->gadget, ecm->ethaddr, "ecm");
1457 if (ret) {
1458 pr_err("%s: gether_setup failed\n", __func__);
1459 return ret;
1460 }
1461
1462 ret = ecm_bind_config(c, ecm->ethaddr);
1463 if (ret) {
1464 pr_err("%s: ecm_bind_config failed\n", __func__);
1465 gether_cleanup();
1466 }
1467 return ret;
1468}
1469
1470static void ecm_function_unbind_config(struct android_usb_function *f,
1471 struct usb_configuration *c)
1472{
1473 gether_cleanup();
1474}
1475
1476static struct android_usb_function ecm_function = {
1477 .name = "ecm",
1478 .init = ecm_function_init,
1479 .cleanup = ecm_function_cleanup,
1480 .bind_config = ecm_function_bind_config,
1481 .unbind_config = ecm_function_unbind_config,
1482 .attributes = ecm_function_attributes,
1483};
1484
Benoit Goby1e8ce152011-12-12 13:01:23 -08001485struct mass_storage_function_config {
1486 struct fsg_config fsg;
1487 struct fsg_common *common;
1488};
1489
1490static int mass_storage_function_init(struct android_usb_function *f,
1491 struct usb_composite_dev *cdev)
1492{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001493 struct android_dev *dev = cdev_to_android_dev(cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001494 struct mass_storage_function_config *config;
1495 struct fsg_common *common;
1496 int err;
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301497 int i;
1498 const char *name[2];
Benoit Goby1e8ce152011-12-12 13:01:23 -08001499
1500 config = kzalloc(sizeof(struct mass_storage_function_config),
1501 GFP_KERNEL);
1502 if (!config)
1503 return -ENOMEM;
1504
1505 config->fsg.nluns = 1;
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301506 name[0] = "lun";
Pavankumar Kondeti2043e302012-07-19 08:54:04 +05301507 if (dev->pdata && dev->pdata->cdrom) {
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301508 config->fsg.nluns = 2;
1509 config->fsg.luns[1].cdrom = 1;
1510 config->fsg.luns[1].ro = 1;
Rajkumar Raghupathy39595002012-08-24 16:34:03 +05301511 config->fsg.luns[1].removable = 0;
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301512 name[1] = "lun0";
1513 }
1514
Benoit Goby1e8ce152011-12-12 13:01:23 -08001515 config->fsg.luns[0].removable = 1;
1516
1517 common = fsg_common_init(NULL, cdev, &config->fsg);
1518 if (IS_ERR(common)) {
1519 kfree(config);
1520 return PTR_ERR(common);
1521 }
1522
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301523 for (i = 0; i < config->fsg.nluns; i++) {
1524 err = sysfs_create_link(&f->dev->kobj,
1525 &common->luns[i].dev.kobj,
1526 name[i]);
1527 if (err)
1528 goto error;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001529 }
1530
1531 config->common = common;
1532 f->config = config;
1533 return 0;
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301534error:
1535 for (; i > 0 ; i--)
1536 sysfs_remove_link(&f->dev->kobj, name[i-1]);
1537
1538 fsg_common_release(&common->ref);
1539 kfree(config);
1540 return err;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001541}
1542
1543static void mass_storage_function_cleanup(struct android_usb_function *f)
1544{
1545 kfree(f->config);
1546 f->config = NULL;
1547}
1548
1549static int mass_storage_function_bind_config(struct android_usb_function *f,
1550 struct usb_configuration *c)
1551{
1552 struct mass_storage_function_config *config = f->config;
1553 return fsg_bind_config(c->cdev, c, config->common);
1554}
1555
1556static ssize_t mass_storage_inquiry_show(struct device *dev,
1557 struct device_attribute *attr, char *buf)
1558{
1559 struct android_usb_function *f = dev_get_drvdata(dev);
1560 struct mass_storage_function_config *config = f->config;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301561 return snprintf(buf, PAGE_SIZE, "%s\n", config->common->inquiry_string);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001562}
1563
1564static ssize_t mass_storage_inquiry_store(struct device *dev,
1565 struct device_attribute *attr, const char *buf, size_t size)
1566{
1567 struct android_usb_function *f = dev_get_drvdata(dev);
1568 struct mass_storage_function_config *config = f->config;
1569 if (size >= sizeof(config->common->inquiry_string))
1570 return -EINVAL;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301571 if (sscanf(buf, "%28s", config->common->inquiry_string) != 1)
Benoit Goby1e8ce152011-12-12 13:01:23 -08001572 return -EINVAL;
1573 return size;
1574}
1575
1576static DEVICE_ATTR(inquiry_string, S_IRUGO | S_IWUSR,
1577 mass_storage_inquiry_show,
1578 mass_storage_inquiry_store);
1579
1580static struct device_attribute *mass_storage_function_attributes[] = {
1581 &dev_attr_inquiry_string,
1582 NULL
1583};
1584
1585static struct android_usb_function mass_storage_function = {
1586 .name = "mass_storage",
1587 .init = mass_storage_function_init,
1588 .cleanup = mass_storage_function_cleanup,
1589 .bind_config = mass_storage_function_bind_config,
1590 .attributes = mass_storage_function_attributes,
1591};
1592
1593
Benoit Gobycf3fc062011-12-19 14:39:37 -08001594static int accessory_function_init(struct android_usb_function *f,
1595 struct usb_composite_dev *cdev)
1596{
1597 return acc_setup();
1598}
1599
1600static void accessory_function_cleanup(struct android_usb_function *f)
1601{
1602 acc_cleanup();
1603}
1604
1605static int accessory_function_bind_config(struct android_usb_function *f,
1606 struct usb_configuration *c)
1607{
1608 return acc_bind_config(c);
1609}
1610
1611static int accessory_function_ctrlrequest(struct android_usb_function *f,
1612 struct usb_composite_dev *cdev,
1613 const struct usb_ctrlrequest *c)
1614{
1615 return acc_ctrlrequest(cdev, c);
1616}
1617
1618static struct android_usb_function accessory_function = {
1619 .name = "accessory",
1620 .init = accessory_function_init,
1621 .cleanup = accessory_function_cleanup,
1622 .bind_config = accessory_function_bind_config,
1623 .ctrlrequest = accessory_function_ctrlrequest,
1624};
1625
Anna Perel3ee23dd2013-02-26 16:06:40 +02001626#ifdef CONFIG_SND_PCM
Mike Lockwood11874822012-08-27 16:43:53 +05301627static int audio_source_function_init(struct android_usb_function *f,
1628 struct usb_composite_dev *cdev)
1629{
1630 struct audio_source_config *config;
1631
1632 config = kzalloc(sizeof(struct audio_source_config), GFP_KERNEL);
1633 if (!config)
1634 return -ENOMEM;
1635 config->card = -1;
1636 config->device = -1;
1637 f->config = config;
1638 return 0;
1639}
1640
1641static void audio_source_function_cleanup(struct android_usb_function *f)
1642{
1643 kfree(f->config);
1644}
1645
1646static int audio_source_function_bind_config(struct android_usb_function *f,
1647 struct usb_configuration *c)
1648{
1649 struct audio_source_config *config = f->config;
1650
1651 return audio_source_bind_config(c, config);
1652}
1653
1654static void audio_source_function_unbind_config(struct android_usb_function *f,
1655 struct usb_configuration *c)
1656{
1657 struct audio_source_config *config = f->config;
1658
1659 config->card = -1;
1660 config->device = -1;
1661}
1662
1663static ssize_t audio_source_pcm_show(struct device *dev,
1664 struct device_attribute *attr, char *buf)
1665{
1666 struct android_usb_function *f = dev_get_drvdata(dev);
1667 struct audio_source_config *config = f->config;
1668
1669 /* print PCM card and device numbers */
1670 return sprintf(buf, "%d %d\n", config->card, config->device);
1671}
1672
1673static DEVICE_ATTR(pcm, S_IRUGO | S_IWUSR, audio_source_pcm_show, NULL);
1674
1675static struct device_attribute *audio_source_function_attributes[] = {
1676 &dev_attr_pcm,
1677 NULL
1678};
1679
1680static struct android_usb_function audio_source_function = {
1681 .name = "audio_source",
1682 .init = audio_source_function_init,
1683 .cleanup = audio_source_function_cleanup,
1684 .bind_config = audio_source_function_bind_config,
1685 .unbind_config = audio_source_function_unbind_config,
1686 .attributes = audio_source_function_attributes,
1687};
Anna Perel3ee23dd2013-02-26 16:06:40 +02001688#endif
Mike Lockwood11874822012-08-27 16:43:53 +05301689
Pavankumar Kondeti8f6ca4f2012-06-26 09:44:36 +05301690static int android_uasp_connect_cb(bool connect)
1691{
1692 /*
1693 * TODO
1694 * We may have to disable gadget till UASP configfs nodes
1695 * are configured which includes mapping LUN with the
1696 * backing file. It is a fundamental difference between
1697 * f_mass_storage and f_tcp. That means UASP can not be
1698 * in default composition.
1699 *
1700 * For now, assume that UASP configfs nodes are configured
1701 * before enabling android gadget. Or cable should be
1702 * reconnected after mapping the LUN.
1703 *
1704 * Also consider making UASP to respond to Host requests when
1705 * Lun is not mapped.
1706 */
1707 pr_debug("UASP %s\n", connect ? "connect" : "disconnect");
1708
1709 return 0;
1710}
1711
1712static int uasp_function_init(struct android_usb_function *f,
1713 struct usb_composite_dev *cdev)
1714{
1715 return f_tcm_init(&android_uasp_connect_cb);
1716}
1717
1718static void uasp_function_cleanup(struct android_usb_function *f)
1719{
1720 f_tcm_exit();
1721}
1722
1723static int uasp_function_bind_config(struct android_usb_function *f,
1724 struct usb_configuration *c)
1725{
1726 return tcm_bind_config(c);
1727}
1728
1729static struct android_usb_function uasp_function = {
1730 .name = "uasp",
1731 .init = uasp_function_init,
1732 .cleanup = uasp_function_cleanup,
1733 .bind_config = uasp_function_bind_config,
1734};
Benoit Gobycf3fc062011-12-19 14:39:37 -08001735
Benoit Goby1e8ce152011-12-12 13:01:23 -08001736static struct android_usb_function *supported_functions[] = {
Anna Perela8c991d2012-04-09 16:44:46 +03001737 &mbim_function,
Ofir Cohen7b155422012-07-31 13:02:49 +03001738 &ecm_qc_function,
Jack Pham2ec5fdc2012-09-26 10:13:48 -07001739#ifdef CONFIG_SND_PCM
Anna Perel432367a2012-09-20 10:55:32 +03001740 &audio_function,
Jack Pham2ec5fdc2012-09-26 10:13:48 -07001741#endif
Manu Gautam1c8ffd72011-09-02 16:00:49 +05301742 &rmnet_smd_function,
Manu Gautam8e0719b2011-09-26 14:47:55 +05301743 &rmnet_sdio_function,
1744 &rmnet_smd_sdio_function,
Manu Gautam2b0234a2011-09-07 16:47:52 +05301745 &rmnet_function,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001746 &diag_function,
Shimrit Malichia00d7322012-08-05 13:56:28 +03001747 &qdss_function,
Manu Gautama4d993f2011-08-30 18:25:55 +05301748 &serial_function,
Benoit Goby2b6862d2011-12-19 14:38:41 -08001749 &adb_function,
Chiranjeevi Velempatie130fd02011-11-29 05:06:13 +05301750 &ccid_function,
Benoit Goby1e8ce152011-12-12 13:01:23 -08001751 &acm_function,
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001752 &mtp_function,
1753 &ptp_function,
Benoit Goby1e8ce152011-12-12 13:01:23 -08001754 &rndis_function,
Ofir Cohenaef90b72012-07-31 12:37:04 +02001755 &rndis_qc_function,
Anna Perelf9d01552012-11-20 15:56:32 +02001756 &ecm_function,
Benoit Goby1e8ce152011-12-12 13:01:23 -08001757 &mass_storage_function,
Benoit Gobycf3fc062011-12-19 14:39:37 -08001758 &accessory_function,
Anna Perel3ee23dd2013-02-26 16:06:40 +02001759#ifdef CONFIG_SND_PCM
Mike Lockwood11874822012-08-27 16:43:53 +05301760 &audio_source_function,
Anna Perel3ee23dd2013-02-26 16:06:40 +02001761#endif
Pavankumar Kondeti8f6ca4f2012-06-26 09:44:36 +05301762 &uasp_function,
Benoit Goby1e8ce152011-12-12 13:01:23 -08001763 NULL
1764};
1765
Lena Salmand092f2d2012-03-12 17:27:24 +02001766static void android_cleanup_functions(struct android_usb_function **functions)
1767{
1768 struct android_usb_function *f;
1769 struct device_attribute **attrs;
1770 struct device_attribute *attr;
1771
1772 while (*functions) {
1773 f = *functions++;
1774
1775 if (f->dev) {
1776 device_destroy(android_class, f->dev->devt);
1777 kfree(f->dev_name);
1778 } else
1779 continue;
1780
1781 if (f->cleanup)
1782 f->cleanup(f);
1783
1784 attrs = f->attributes;
1785 if (attrs) {
1786 while ((attr = *attrs++))
1787 device_remove_file(f->dev, attr);
1788 }
1789 }
1790}
Benoit Goby1e8ce152011-12-12 13:01:23 -08001791
1792static int android_init_functions(struct android_usb_function **functions,
1793 struct usb_composite_dev *cdev)
1794{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001795 struct android_dev *dev = cdev_to_android_dev(cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001796 struct android_usb_function *f;
1797 struct device_attribute **attrs;
1798 struct device_attribute *attr;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301799 int err = 0;
Lena Salmand092f2d2012-03-12 17:27:24 +02001800 int index = 1; /* index 0 is for android0 device */
Benoit Goby1e8ce152011-12-12 13:01:23 -08001801
1802 for (; (f = *functions++); index++) {
1803 f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001804 f->android_dev = NULL;
Lena Salmand092f2d2012-03-12 17:27:24 +02001805 if (!f->dev_name) {
1806 err = -ENOMEM;
1807 goto err_out;
1808 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08001809 f->dev = device_create(android_class, dev->dev,
1810 MKDEV(0, index), f, f->dev_name);
1811 if (IS_ERR(f->dev)) {
1812 pr_err("%s: Failed to create dev %s", __func__,
1813 f->dev_name);
1814 err = PTR_ERR(f->dev);
Lena Salmand092f2d2012-03-12 17:27:24 +02001815 f->dev = NULL;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001816 goto err_create;
1817 }
1818
1819 if (f->init) {
1820 err = f->init(f, cdev);
1821 if (err) {
1822 pr_err("%s: Failed to init %s", __func__,
1823 f->name);
Lena Salmand092f2d2012-03-12 17:27:24 +02001824 goto err_init;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001825 }
1826 }
1827
1828 attrs = f->attributes;
1829 if (attrs) {
1830 while ((attr = *attrs++) && !err)
1831 err = device_create_file(f->dev, attr);
1832 }
1833 if (err) {
1834 pr_err("%s: Failed to create function %s attributes",
1835 __func__, f->name);
Lena Salmand092f2d2012-03-12 17:27:24 +02001836 goto err_attrs;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001837 }
1838 }
1839 return 0;
1840
Lena Salmand092f2d2012-03-12 17:27:24 +02001841err_attrs:
1842 for (attr = *(attrs -= 2); attrs != f->attributes; attr = *(attrs--))
1843 device_remove_file(f->dev, attr);
1844 if (f->cleanup)
1845 f->cleanup(f);
1846err_init:
Benoit Goby1e8ce152011-12-12 13:01:23 -08001847 device_destroy(android_class, f->dev->devt);
1848err_create:
Lena Salmand092f2d2012-03-12 17:27:24 +02001849 f->dev = NULL;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001850 kfree(f->dev_name);
Lena Salmand092f2d2012-03-12 17:27:24 +02001851err_out:
1852 android_cleanup_functions(dev->functions);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001853 return err;
1854}
1855
Benoit Goby1e8ce152011-12-12 13:01:23 -08001856static int
1857android_bind_enabled_functions(struct android_dev *dev,
1858 struct usb_configuration *c)
1859{
Ido Shayevitz68557e32012-11-06 12:40:37 +02001860 struct android_usb_function_holder *f_holder;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001861 struct android_configuration *conf =
1862 container_of(c, struct android_configuration, usb_config);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001863 int ret;
1864
Ido Shayevitz68557e32012-11-06 12:40:37 +02001865 list_for_each_entry(f_holder, &conf->enabled_functions, enabled_list) {
1866 ret = f_holder->f->bind_config(f_holder->f, c);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001867 if (ret) {
Ido Shayevitz68557e32012-11-06 12:40:37 +02001868 pr_err("%s: %s failed", __func__, f_holder->f->name);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001869 return ret;
1870 }
1871 }
1872 return 0;
1873}
1874
1875static void
1876android_unbind_enabled_functions(struct android_dev *dev,
1877 struct usb_configuration *c)
1878{
Ido Shayevitz68557e32012-11-06 12:40:37 +02001879 struct android_usb_function_holder *f_holder;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001880 struct android_configuration *conf =
1881 container_of(c, struct android_configuration, usb_config);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001882
Ido Shayevitz68557e32012-11-06 12:40:37 +02001883 list_for_each_entry(f_holder, &conf->enabled_functions, enabled_list) {
1884 if (f_holder->f->unbind_config)
1885 f_holder->f->unbind_config(f_holder->f, c);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001886 }
1887}
1888
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001889static int android_enable_function(struct android_dev *dev,
1890 struct android_configuration *conf,
1891 char *name)
Benoit Goby1e8ce152011-12-12 13:01:23 -08001892{
1893 struct android_usb_function **functions = dev->functions;
1894 struct android_usb_function *f;
Ido Shayevitz68557e32012-11-06 12:40:37 +02001895 struct android_usb_function_holder *f_holder;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001896 while ((f = *functions++)) {
1897 if (!strcmp(name, f->name)) {
Ido Shayevitz68557e32012-11-06 12:40:37 +02001898 if (f->android_dev && f->android_dev != dev)
1899 pr_err("%s is enabled in other device\n",
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001900 f->name);
1901 else {
Ido Shayevitz68557e32012-11-06 12:40:37 +02001902 f_holder = kzalloc(sizeof(*f_holder),
1903 GFP_KERNEL);
1904 if (!f_holder) {
1905 pr_err("Failed to alloc f_holder\n");
1906 return -ENOMEM;
1907 }
1908
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001909 f->android_dev = dev;
Ido Shayevitz68557e32012-11-06 12:40:37 +02001910 f_holder->f = f;
1911 list_add_tail(&f_holder->enabled_list,
1912 &conf->enabled_functions);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001913 return 0;
1914 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08001915 }
1916 }
1917 return -EINVAL;
1918}
1919
1920/*-------------------------------------------------------------------------*/
1921/* /sys/class/android_usb/android%d/ interface */
1922
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05301923static ssize_t remote_wakeup_show(struct device *pdev,
1924 struct device_attribute *attr, char *buf)
1925{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001926 struct android_dev *dev = dev_get_drvdata(pdev);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001927 struct android_configuration *conf;
1928
1929 /*
1930 * Show the wakeup attribute of the first configuration,
1931 * since all configurations have the same wakeup attribute
1932 */
1933 if (dev->configs_num == 0)
1934 return 0;
1935 conf = list_entry(dev->configs.next,
1936 struct android_configuration,
1937 list_item);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001938
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05301939 return snprintf(buf, PAGE_SIZE, "%d\n",
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001940 !!(conf->usb_config.bmAttributes &
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05301941 USB_CONFIG_ATT_WAKEUP));
1942}
1943
1944static ssize_t remote_wakeup_store(struct device *pdev,
1945 struct device_attribute *attr, const char *buff, size_t size)
1946{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001947 struct android_dev *dev = dev_get_drvdata(pdev);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001948 struct android_configuration *conf;
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05301949 int enable = 0;
1950
1951 sscanf(buff, "%d", &enable);
1952
1953 pr_debug("android_usb: %s remote wakeup\n",
1954 enable ? "enabling" : "disabling");
1955
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001956 list_for_each_entry(conf, &dev->configs, list_item)
1957 if (enable)
1958 conf->usb_config.bmAttributes |=
1959 USB_CONFIG_ATT_WAKEUP;
1960 else
1961 conf->usb_config.bmAttributes &=
1962 ~USB_CONFIG_ATT_WAKEUP;
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05301963
1964 return size;
1965}
1966
Benoit Goby1e8ce152011-12-12 13:01:23 -08001967static ssize_t
1968functions_show(struct device *pdev, struct device_attribute *attr, char *buf)
1969{
1970 struct android_dev *dev = dev_get_drvdata(pdev);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001971 struct android_configuration *conf;
Ido Shayevitz68557e32012-11-06 12:40:37 +02001972 struct android_usb_function_holder *f_holder;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001973 char *buff = buf;
1974
1975 mutex_lock(&dev->mutex);
1976
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001977 list_for_each_entry(conf, &dev->configs, list_item) {
1978 if (buff != buf)
1979 *(buff-1) = ':';
Ido Shayevitz68557e32012-11-06 12:40:37 +02001980 list_for_each_entry(f_holder, &conf->enabled_functions,
1981 enabled_list)
1982 buff += snprintf(buff, PAGE_SIZE, "%s,",
1983 f_holder->f->name);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001984 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08001985
1986 mutex_unlock(&dev->mutex);
1987
1988 if (buff != buf)
1989 *(buff-1) = '\n';
1990 return buff - buf;
1991}
1992
1993static ssize_t
1994functions_store(struct device *pdev, struct device_attribute *attr,
1995 const char *buff, size_t size)
1996{
1997 struct android_dev *dev = dev_get_drvdata(pdev);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001998 struct list_head *curr_conf = &dev->configs;
1999 struct android_configuration *conf;
2000 char *conf_str;
Ido Shayevitz68557e32012-11-06 12:40:37 +02002001 struct android_usb_function_holder *f_holder;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002002 char *name;
2003 char buf[256], *b;
2004 int err;
2005
2006 mutex_lock(&dev->mutex);
2007
2008 if (dev->enabled) {
2009 mutex_unlock(&dev->mutex);
2010 return -EBUSY;
2011 }
2012
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002013 /* Clear previous enabled list */
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002014 list_for_each_entry(conf, &dev->configs, list_item) {
Ido Shayevitz68557e32012-11-06 12:40:37 +02002015 while (conf->enabled_functions.next !=
2016 &conf->enabled_functions) {
2017 f_holder = list_entry(conf->enabled_functions.next,
2018 typeof(*f_holder),
2019 enabled_list);
2020 f_holder->f->android_dev = NULL;
2021 list_del(&f_holder->enabled_list);
2022 kfree(f_holder);
2023 }
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002024 INIT_LIST_HEAD(&conf->enabled_functions);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002025 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002026
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302027 strlcpy(buf, buff, sizeof(buf));
Benoit Goby1e8ce152011-12-12 13:01:23 -08002028 b = strim(buf);
2029
2030 while (b) {
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002031 conf_str = strsep(&b, ":");
2032 if (conf_str) {
2033 /* If the next not equal to the head, take it */
2034 if (curr_conf->next != &dev->configs)
2035 conf = list_entry(curr_conf->next,
2036 struct android_configuration,
2037 list_item);
2038 else
2039 conf = alloc_android_config(dev);
2040
2041 curr_conf = curr_conf->next;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002042 }
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002043
2044 while (conf_str) {
2045 name = strsep(&conf_str, ",");
2046 if (name) {
2047 err = android_enable_function(dev, conf, name);
2048 if (err)
2049 pr_err("android_usb: Cannot enable %s",
2050 name);
2051 }
2052 }
2053 }
2054
2055 /* Free uneeded configurations if exists */
2056 while (curr_conf->next != &dev->configs) {
2057 conf = list_entry(curr_conf->next,
2058 struct android_configuration, list_item);
2059 free_android_config(dev, conf);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002060 }
2061
2062 mutex_unlock(&dev->mutex);
2063
2064 return size;
2065}
2066
2067static ssize_t enable_show(struct device *pdev, struct device_attribute *attr,
2068 char *buf)
2069{
2070 struct android_dev *dev = dev_get_drvdata(pdev);
Steve Mucklef132c6c2012-06-06 18:30:57 -07002071
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302072 return snprintf(buf, PAGE_SIZE, "%d\n", dev->enabled);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002073}
2074
2075static ssize_t enable_store(struct device *pdev, struct device_attribute *attr,
2076 const char *buff, size_t size)
2077{
2078 struct android_dev *dev = dev_get_drvdata(pdev);
2079 struct usb_composite_dev *cdev = dev->cdev;
Ido Shayevitz68557e32012-11-06 12:40:37 +02002080 struct android_usb_function_holder *f_holder;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002081 struct android_configuration *conf;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002082 int enabled = 0;
Rajkumar Raghupathya79363b2013-01-02 19:08:49 +05302083 bool audio_enabled = false;
Pavankumar Kondeti19d8bc62013-02-28 10:19:40 +05302084 static DEFINE_RATELIMIT_STATE(rl, 10*HZ, 1);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002085
Benoit Gobycf3fc062011-12-19 14:39:37 -08002086 if (!cdev)
2087 return -ENODEV;
2088
Benoit Goby1e8ce152011-12-12 13:01:23 -08002089 mutex_lock(&dev->mutex);
2090
2091 sscanf(buff, "%d", &enabled);
2092 if (enabled && !dev->enabled) {
Benoit Goby1e8ce152011-12-12 13:01:23 -08002093 /*
2094 * Update values in composite driver's copy of
2095 * device descriptor.
2096 */
2097 cdev->desc.idVendor = device_desc.idVendor;
2098 cdev->desc.idProduct = device_desc.idProduct;
2099 cdev->desc.bcdDevice = device_desc.bcdDevice;
2100 cdev->desc.bDeviceClass = device_desc.bDeviceClass;
2101 cdev->desc.bDeviceSubClass = device_desc.bDeviceSubClass;
2102 cdev->desc.bDeviceProtocol = device_desc.bDeviceProtocol;
Rajkumar Raghupathya79363b2013-01-02 19:08:49 +05302103
2104 /* Audio dock accessory is unable to enumerate device if
2105 * pull-up is enabled immediately. The enumeration is
2106 * reliable with 100 msec delay.
2107 */
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002108 list_for_each_entry(conf, &dev->configs, list_item)
Ido Shayevitz68557e32012-11-06 12:40:37 +02002109 list_for_each_entry(f_holder, &conf->enabled_functions,
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002110 enabled_list) {
Ido Shayevitz68557e32012-11-06 12:40:37 +02002111 if (f_holder->f->enable)
2112 f_holder->f->enable(f_holder->f);
Rajkumar Raghupathya79363b2013-01-02 19:08:49 +05302113 if (!strncmp(f_holder->f->name,
2114 "audio_source", 12))
2115 audio_enabled = true;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002116 }
Rajkumar Raghupathya79363b2013-01-02 19:08:49 +05302117 if (audio_enabled)
2118 msleep(100);
Benoit Goby80ba14d2012-03-19 18:56:52 -07002119 android_enable(dev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002120 dev->enabled = true;
2121 } else if (!enabled && dev->enabled) {
Benoit Goby80ba14d2012-03-19 18:56:52 -07002122 android_disable(dev);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002123 list_for_each_entry(conf, &dev->configs, list_item)
Ido Shayevitz68557e32012-11-06 12:40:37 +02002124 list_for_each_entry(f_holder, &conf->enabled_functions,
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002125 enabled_list) {
Ido Shayevitz68557e32012-11-06 12:40:37 +02002126 if (f_holder->f->disable)
2127 f_holder->f->disable(f_holder->f);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002128 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002129 dev->enabled = false;
Pavankumar Kondeti19d8bc62013-02-28 10:19:40 +05302130 } else if (__ratelimit(&rl)) {
Benoit Goby1e8ce152011-12-12 13:01:23 -08002131 pr_err("android_usb: already %s\n",
2132 dev->enabled ? "enabled" : "disabled");
2133 }
2134
2135 mutex_unlock(&dev->mutex);
Steve Mucklef132c6c2012-06-06 18:30:57 -07002136
Benoit Gobyaab96812011-04-19 20:37:33 -07002137 return size;
2138}
2139
Ofir Cohen94213a72012-05-03 14:26:32 +03002140static ssize_t pm_qos_show(struct device *pdev,
2141 struct device_attribute *attr, char *buf)
2142{
2143 struct android_dev *dev = dev_get_drvdata(pdev);
2144
2145 return snprintf(buf, PAGE_SIZE, "%s\n", dev->pm_qos);
2146}
2147
2148static ssize_t pm_qos_store(struct device *pdev,
2149 struct device_attribute *attr,
2150 const char *buff, size_t size)
2151{
2152 struct android_dev *dev = dev_get_drvdata(pdev);
2153
2154 strlcpy(dev->pm_qos, buff, sizeof(dev->pm_qos));
2155
Benoit Goby1e8ce152011-12-12 13:01:23 -08002156 return size;
2157}
2158
2159static ssize_t state_show(struct device *pdev, struct device_attribute *attr,
2160 char *buf)
2161{
2162 struct android_dev *dev = dev_get_drvdata(pdev);
2163 struct usb_composite_dev *cdev = dev->cdev;
2164 char *state = "DISCONNECTED";
2165 unsigned long flags;
2166
2167 if (!cdev)
2168 goto out;
2169
2170 spin_lock_irqsave(&cdev->lock, flags);
2171 if (cdev->config)
2172 state = "CONFIGURED";
2173 else if (dev->connected)
2174 state = "CONNECTED";
2175 spin_unlock_irqrestore(&cdev->lock, flags);
2176out:
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302177 return snprintf(buf, PAGE_SIZE, "%s\n", state);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002178}
2179
2180#define DESCRIPTOR_ATTR(field, format_string) \
2181static ssize_t \
2182field ## _show(struct device *dev, struct device_attribute *attr, \
2183 char *buf) \
2184{ \
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302185 return snprintf(buf, PAGE_SIZE, \
2186 format_string, device_desc.field); \
Benoit Goby1e8ce152011-12-12 13:01:23 -08002187} \
2188static ssize_t \
2189field ## _store(struct device *dev, struct device_attribute *attr, \
2190 const char *buf, size_t size) \
2191{ \
2192 int value; \
2193 if (sscanf(buf, format_string, &value) == 1) { \
2194 device_desc.field = value; \
2195 return size; \
2196 } \
2197 return -1; \
2198} \
2199static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store);
2200
2201#define DESCRIPTOR_STRING_ATTR(field, buffer) \
2202static ssize_t \
2203field ## _show(struct device *dev, struct device_attribute *attr, \
2204 char *buf) \
2205{ \
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302206 return snprintf(buf, PAGE_SIZE, "%s", buffer); \
Benoit Goby1e8ce152011-12-12 13:01:23 -08002207} \
2208static ssize_t \
2209field ## _store(struct device *dev, struct device_attribute *attr, \
2210 const char *buf, size_t size) \
2211{ \
2212 if (size >= sizeof(buffer)) \
2213 return -EINVAL; \
Pavankumar Kondetie02a51a2012-06-20 08:52:37 +05302214 strlcpy(buffer, buf, sizeof(buffer)); \
2215 strim(buffer); \
Pavankumar Kondeti4c22c102012-06-15 10:59:05 +05302216 return size; \
Benoit Goby1e8ce152011-12-12 13:01:23 -08002217} \
2218static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store);
2219
2220
2221DESCRIPTOR_ATTR(idVendor, "%04x\n")
2222DESCRIPTOR_ATTR(idProduct, "%04x\n")
2223DESCRIPTOR_ATTR(bcdDevice, "%04x\n")
2224DESCRIPTOR_ATTR(bDeviceClass, "%d\n")
2225DESCRIPTOR_ATTR(bDeviceSubClass, "%d\n")
2226DESCRIPTOR_ATTR(bDeviceProtocol, "%d\n")
2227DESCRIPTOR_STRING_ATTR(iManufacturer, manufacturer_string)
2228DESCRIPTOR_STRING_ATTR(iProduct, product_string)
2229DESCRIPTOR_STRING_ATTR(iSerial, serial_string)
2230
2231static DEVICE_ATTR(functions, S_IRUGO | S_IWUSR, functions_show,
2232 functions_store);
2233static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store);
Ofir Cohen94213a72012-05-03 14:26:32 +03002234static DEVICE_ATTR(pm_qos, S_IRUGO | S_IWUSR,
2235 pm_qos_show, pm_qos_store);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002236static DEVICE_ATTR(state, S_IRUGO, state_show, NULL);
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05302237static DEVICE_ATTR(remote_wakeup, S_IRUGO | S_IWUSR,
2238 remote_wakeup_show, remote_wakeup_store);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002239
2240static struct device_attribute *android_usb_attributes[] = {
2241 &dev_attr_idVendor,
2242 &dev_attr_idProduct,
2243 &dev_attr_bcdDevice,
2244 &dev_attr_bDeviceClass,
2245 &dev_attr_bDeviceSubClass,
2246 &dev_attr_bDeviceProtocol,
2247 &dev_attr_iManufacturer,
2248 &dev_attr_iProduct,
2249 &dev_attr_iSerial,
2250 &dev_attr_functions,
2251 &dev_attr_enable,
Ofir Cohen94213a72012-05-03 14:26:32 +03002252 &dev_attr_pm_qos,
Benoit Goby1e8ce152011-12-12 13:01:23 -08002253 &dev_attr_state,
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05302254 &dev_attr_remote_wakeup,
Benoit Goby1e8ce152011-12-12 13:01:23 -08002255 NULL
2256};
2257
2258/*-------------------------------------------------------------------------*/
2259/* Composite driver */
2260
2261static int android_bind_config(struct usb_configuration *c)
2262{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002263 struct android_dev *dev = cdev_to_android_dev(c->cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002264 int ret = 0;
2265
2266 ret = android_bind_enabled_functions(dev, c);
2267 if (ret)
2268 return ret;
2269
2270 return 0;
2271}
2272
2273static void android_unbind_config(struct usb_configuration *c)
2274{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002275 struct android_dev *dev = cdev_to_android_dev(c->cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002276
2277 android_unbind_enabled_functions(dev, c);
2278}
2279
2280static int android_bind(struct usb_composite_dev *cdev)
2281{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002282 struct android_dev *dev;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002283 struct usb_gadget *gadget = cdev->gadget;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002284 struct android_configuration *conf;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002285 int gcnum, id, ret;
2286
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002287 /* Bind to the last android_dev that was probed */
2288 dev = list_entry(android_dev_list.prev, struct android_dev, list_item);
2289
2290 dev->cdev = cdev;
2291
Benoit Goby1e8ce152011-12-12 13:01:23 -08002292 /*
2293 * Start disconnected. Userspace will connect the gadget once
2294 * it is done configuring the functions.
2295 */
2296 usb_gadget_disconnect(gadget);
2297
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002298 /* Init the supported functions only once, on the first android_dev */
2299 if (android_dev_count == 1) {
2300 ret = android_init_functions(dev->functions, cdev);
2301 if (ret)
2302 return ret;
2303 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002304
2305 /* Allocate string descriptor numbers ... note that string
2306 * contents can be overridden by the composite_dev glue.
2307 */
2308 id = usb_string_id(cdev);
2309 if (id < 0)
2310 return id;
2311 strings_dev[STRING_MANUFACTURER_IDX].id = id;
2312 device_desc.iManufacturer = id;
2313
2314 id = usb_string_id(cdev);
2315 if (id < 0)
2316 return id;
2317 strings_dev[STRING_PRODUCT_IDX].id = id;
2318 device_desc.iProduct = id;
2319
2320 /* Default strings - should be updated by userspace */
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302321 strlcpy(manufacturer_string, "Android",
2322 sizeof(manufacturer_string) - 1);
2323 strlcpy(product_string, "Android", sizeof(product_string) - 1);
2324 strlcpy(serial_string, "0123456789ABCDEF", sizeof(serial_string) - 1);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002325
2326 id = usb_string_id(cdev);
2327 if (id < 0)
2328 return id;
2329 strings_dev[STRING_SERIAL_IDX].id = id;
2330 device_desc.iSerialNumber = id;
2331
Vijayavardhan Vennapusa56e60522012-02-16 15:40:16 +05302332 if (gadget_is_otg(cdev->gadget))
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002333 list_for_each_entry(conf, &dev->configs, list_item)
2334 conf->usb_config.descriptors = otg_desc;
Vijayavardhan Vennapusa56e60522012-02-16 15:40:16 +05302335
Benoit Goby1e8ce152011-12-12 13:01:23 -08002336 gcnum = usb_gadget_controller_number(gadget);
2337 if (gcnum >= 0)
2338 device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
2339 else {
2340 pr_warning("%s: controller '%s' not recognized\n",
2341 longname, gadget->name);
2342 device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
2343 }
2344
Benoit Goby1e8ce152011-12-12 13:01:23 -08002345 return 0;
2346}
2347
2348static int android_usb_unbind(struct usb_composite_dev *cdev)
2349{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002350 struct android_dev *dev = cdev_to_android_dev(cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002351
Lena Salmand092f2d2012-03-12 17:27:24 +02002352 manufacturer_string[0] = '\0';
2353 product_string[0] = '\0';
2354 serial_string[0] = '0';
Benoit Goby1e8ce152011-12-12 13:01:23 -08002355 cancel_work_sync(&dev->work);
2356 android_cleanup_functions(dev->functions);
2357 return 0;
2358}
2359
2360static struct usb_composite_driver android_usb_driver = {
2361 .name = "android_usb",
2362 .dev = &device_desc,
2363 .strings = dev_strings,
2364 .unbind = android_usb_unbind,
Tatyana Brokhman3ba28902011-06-29 16:41:49 +03002365 .max_speed = USB_SPEED_SUPER
Benoit Goby1e8ce152011-12-12 13:01:23 -08002366};
2367
2368static int
2369android_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *c)
2370{
Benoit Goby1e8ce152011-12-12 13:01:23 -08002371 struct usb_composite_dev *cdev = get_gadget_data(gadget);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002372 struct android_dev *dev = cdev_to_android_dev(cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002373 struct usb_request *req = cdev->req;
2374 struct android_usb_function *f;
Ido Shayevitz68557e32012-11-06 12:40:37 +02002375 struct android_usb_function_holder *f_holder;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002376 struct android_configuration *conf;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002377 int value = -EOPNOTSUPP;
2378 unsigned long flags;
2379
2380 req->zero = 0;
2381 req->complete = composite_setup_complete;
2382 req->length = 0;
2383 gadget->ep0->driver_data = cdev;
2384
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002385 list_for_each_entry(conf, &dev->configs, list_item)
Ido Shayevitz68557e32012-11-06 12:40:37 +02002386 list_for_each_entry(f_holder,
2387 &conf->enabled_functions,
2388 enabled_list) {
2389 f = f_holder->f;
2390 if (f->ctrlrequest) {
2391 value = f->ctrlrequest(f, cdev, c);
2392 if (value >= 0)
2393 break;
2394 }
2395 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002396
Benoit Gobycf3fc062011-12-19 14:39:37 -08002397 /* Special case the accessory function.
2398 * It needs to handle control requests before it is enabled.
2399 */
2400 if (value < 0)
2401 value = acc_ctrlrequest(cdev, c);
2402
Benoit Goby1e8ce152011-12-12 13:01:23 -08002403 if (value < 0)
2404 value = composite_setup(gadget, c);
2405
2406 spin_lock_irqsave(&cdev->lock, flags);
2407 if (!dev->connected) {
2408 dev->connected = 1;
2409 schedule_work(&dev->work);
2410 } else if (c->bRequest == USB_REQ_SET_CONFIGURATION &&
2411 cdev->config) {
2412 schedule_work(&dev->work);
2413 }
2414 spin_unlock_irqrestore(&cdev->lock, flags);
2415
2416 return value;
2417}
2418
2419static void android_disconnect(struct usb_gadget *gadget)
2420{
Benoit Goby1e8ce152011-12-12 13:01:23 -08002421 struct usb_composite_dev *cdev = get_gadget_data(gadget);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002422 struct android_dev *dev = cdev_to_android_dev(cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002423 unsigned long flags;
2424
2425 composite_disconnect(gadget);
Mike Lockwoode7558bb2012-08-27 16:23:48 +05302426 /* accessory HID support can be active while the
2427 accessory function is not actually enabled,
2428 so we need to inform it when we are disconnected.
2429 */
2430 acc_disconnect();
Benoit Goby1e8ce152011-12-12 13:01:23 -08002431
2432 spin_lock_irqsave(&cdev->lock, flags);
2433 dev->connected = 0;
2434 schedule_work(&dev->work);
2435 spin_unlock_irqrestore(&cdev->lock, flags);
2436}
2437
Ido Shayevitzfb5edfe2012-12-26 14:26:37 +02002438static void android_suspend(struct usb_gadget *gadget)
2439{
2440 struct usb_composite_dev *cdev = get_gadget_data(gadget);
2441 struct android_dev *dev = cdev_to_android_dev(cdev);
2442 unsigned long flags;
2443
2444 spin_lock_irqsave(&cdev->lock, flags);
2445 dev->suspended = 1;
2446 schedule_work(&dev->work);
2447 spin_unlock_irqrestore(&cdev->lock, flags);
2448
2449 composite_suspend(gadget);
2450}
2451
2452static void android_resume(struct usb_gadget *gadget)
2453{
2454 struct usb_composite_dev *cdev = get_gadget_data(gadget);
2455 struct android_dev *dev = cdev_to_android_dev(cdev);
2456 unsigned long flags;
2457
2458 spin_lock_irqsave(&cdev->lock, flags);
2459 dev->suspended = 0;
2460 schedule_work(&dev->work);
2461 spin_unlock_irqrestore(&cdev->lock, flags);
2462
2463 composite_resume(gadget);
2464}
2465
2466
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002467static int android_create_device(struct android_dev *dev, u8 usb_core_id)
Benoit Goby1e8ce152011-12-12 13:01:23 -08002468{
2469 struct device_attribute **attrs = android_usb_attributes;
2470 struct device_attribute *attr;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002471 char device_node_name[ANDROID_DEVICE_NODE_NAME_LENGTH];
Benoit Goby1e8ce152011-12-12 13:01:23 -08002472 int err;
2473
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002474 /*
2475 * The primary usb core should always have usb_core_id=0, since
2476 * Android user space is currently interested in android0 events.
2477 */
2478 snprintf(device_node_name, ANDROID_DEVICE_NODE_NAME_LENGTH,
2479 "android%d", usb_core_id);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002480 dev->dev = device_create(android_class, NULL,
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002481 MKDEV(0, 0), NULL, device_node_name);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002482 if (IS_ERR(dev->dev))
2483 return PTR_ERR(dev->dev);
2484
2485 dev_set_drvdata(dev->dev, dev);
2486
2487 while ((attr = *attrs++)) {
2488 err = device_create_file(dev->dev, attr);
2489 if (err) {
2490 device_destroy(android_class, dev->dev->devt);
2491 return err;
2492 }
2493 }
2494 return 0;
2495}
2496
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05302497static void android_destroy_device(struct android_dev *dev)
Benoit Goby1e8ce152011-12-12 13:01:23 -08002498{
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05302499 struct device_attribute **attrs = android_usb_attributes;
2500 struct device_attribute *attr;
2501
2502 while ((attr = *attrs++))
2503 device_remove_file(dev->dev, attr);
2504 device_destroy(android_class, dev->dev->devt);
2505}
2506
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002507static struct android_dev *cdev_to_android_dev(struct usb_composite_dev *cdev)
2508{
2509 struct android_dev *dev = NULL;
2510
2511 /* Find the android dev from the list */
2512 list_for_each_entry(dev, &android_dev_list, list_item) {
2513 if (dev->cdev == cdev)
2514 break;
2515 }
2516
2517 return dev;
2518}
2519
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002520static struct android_configuration *alloc_android_config
2521 (struct android_dev *dev)
2522{
2523 struct android_configuration *conf;
2524
2525 conf = kzalloc(sizeof(*conf), GFP_KERNEL);
2526 if (!conf) {
2527 pr_err("%s(): Failed to alloc memory for android conf\n",
2528 __func__);
2529 return ERR_PTR(-ENOMEM);
2530 }
2531
2532 dev->configs_num++;
2533 conf->usb_config.label = dev->name;
2534 conf->usb_config.unbind = android_unbind_config;
2535 conf->usb_config.bConfigurationValue = dev->configs_num;
2536
2537 INIT_LIST_HEAD(&conf->enabled_functions);
2538
2539 list_add_tail(&conf->list_item, &dev->configs);
2540
2541 return conf;
2542}
2543
2544static void free_android_config(struct android_dev *dev,
2545 struct android_configuration *conf)
2546{
2547 list_del(&conf->list_item);
2548 dev->configs_num--;
2549 kfree(conf);
2550}
2551
Manu Gautam43c61a12012-08-22 17:09:37 -07002552static int usb_diag_update_pid_and_serial_num(u32 pid, const char *snum)
2553{
2554 struct dload_struct local_diag_dload = { 0 };
2555 int *src, *dst, i;
2556
2557 if (!diag_dload) {
2558 pr_debug("%s: unable to update PID and serial_no\n", __func__);
2559 return -ENODEV;
2560 }
2561
2562 pr_debug("%s: dload:%p pid:%x serial_num:%s\n",
2563 __func__, diag_dload, pid, snum);
2564
2565 /* update pid */
2566 local_diag_dload.magic_struct.pid = PID_MAGIC_ID;
2567 local_diag_dload.pid = pid;
2568
2569 /* update serial number */
2570 if (!snum) {
2571 local_diag_dload.magic_struct.serial_num = 0;
2572 memset(&local_diag_dload.serial_number, 0,
2573 SERIAL_NUMBER_LENGTH);
2574 } else {
2575 local_diag_dload.magic_struct.serial_num = SERIAL_NUM_MAGIC_ID;
2576 strlcpy((char *)&local_diag_dload.serial_number, snum,
2577 SERIAL_NUMBER_LENGTH);
2578 }
2579
2580 /* Copy to shared struct (accesses need to be 32 bit aligned) */
2581 src = (int *)&local_diag_dload;
2582 dst = (int *)diag_dload;
2583
2584 for (i = 0; i < sizeof(*diag_dload) / 4; i++)
2585 *dst++ = *src++;
2586
2587 return 0;
2588}
2589
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002590static int __devinit android_probe(struct platform_device *pdev)
2591{
Vijayavardhan Vennapusa8ceade82012-11-01 15:11:21 +05302592 struct android_usb_platform_data *pdata;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002593 struct android_dev *android_dev;
Manu Gautam43c61a12012-08-22 17:09:37 -07002594 struct resource *res;
Lena Salmand092f2d2012-03-12 17:27:24 +02002595 int ret = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002596
Vijayavardhan Vennapusa8ceade82012-11-01 15:11:21 +05302597 if (pdev->dev.of_node) {
2598 dev_dbg(&pdev->dev, "device tree enabled\n");
2599 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
2600 if (!pdata) {
2601 pr_err("unable to allocate platform data\n");
2602 return -ENOMEM;
2603 }
2604
2605 of_property_read_u32(pdev->dev.of_node,
2606 "qcom,android-usb-swfi-latency",
2607 &pdata->swfi_latency);
2608 } else {
2609 pdata = pdev->dev.platform_data;
2610 }
2611
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002612 if (!android_class) {
2613 android_class = class_create(THIS_MODULE, "android_usb");
2614 if (IS_ERR(android_class))
2615 return PTR_ERR(android_class);
2616 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002617
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002618 android_dev = kzalloc(sizeof(*android_dev), GFP_KERNEL);
2619 if (!android_dev) {
2620 pr_err("%s(): Failed to alloc memory for android_dev\n",
2621 __func__);
2622 ret = -ENOMEM;
2623 goto err_alloc;
2624 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002625
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002626 android_dev->name = pdev->name;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002627 android_dev->disable_depth = 1;
2628 android_dev->functions = supported_functions;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002629 android_dev->configs_num = 0;
2630 INIT_LIST_HEAD(&android_dev->configs);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002631 INIT_WORK(&android_dev->work, android_work);
2632 mutex_init(&android_dev->mutex);
2633
2634 android_dev->pdata = pdata;
2635
2636 list_add_tail(&android_dev->list_item, &android_dev_list);
2637 android_dev_count++;
2638
2639 if (pdata)
2640 composite_driver.usb_core_id = pdata->usb_core_id;
2641 else
2642 composite_driver.usb_core_id = 0; /*To backward compatibility*/
2643
Manu Gautam43c61a12012-08-22 17:09:37 -07002644 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2645 if (res) {
2646 diag_dload = devm_ioremap(&pdev->dev, res->start,
2647 resource_size(res));
2648 if (!diag_dload) {
2649 dev_err(&pdev->dev, "ioremap failed\n");
2650 ret = -ENOMEM;
2651 goto err_dev;
2652 }
2653 } else {
2654 dev_dbg(&pdev->dev, "failed to get mem resource\n");
2655 }
2656
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002657 ret = android_create_device(android_dev, composite_driver.usb_core_id);
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05302658 if (ret) {
2659 pr_err("%s(): android_create_device failed\n", __func__);
2660 goto err_dev;
2661 }
2662
Lena Salmand092f2d2012-03-12 17:27:24 +02002663 ret = usb_composite_probe(&android_usb_driver, android_bind);
2664 if (ret) {
2665 pr_err("%s(): Failed to register android "
2666 "composite driver\n", __func__);
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05302667 goto err_probe;
Lena Salmand092f2d2012-03-12 17:27:24 +02002668 }
2669
Ofir Cohen94213a72012-05-03 14:26:32 +03002670 /* pm qos request to prevent apps idle power collapse */
Manu Gautam94dc6142012-05-08 14:35:24 +05302671 if (pdata && pdata->swfi_latency)
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002672 pm_qos_add_request(&android_dev->pm_qos_req_dma,
Ofir Cohen94213a72012-05-03 14:26:32 +03002673 PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002674 strlcpy(android_dev->pm_qos, "high", sizeof(android_dev->pm_qos));
Ofir Cohen94213a72012-05-03 14:26:32 +03002675
Lena Salmand092f2d2012-03-12 17:27:24 +02002676 return ret;
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05302677err_probe:
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002678 android_destroy_device(android_dev);
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05302679err_dev:
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002680 list_del(&android_dev->list_item);
2681 android_dev_count--;
2682 kfree(android_dev);
2683err_alloc:
2684 if (list_empty(&android_dev_list)) {
2685 class_destroy(android_class);
2686 android_class = NULL;
2687 }
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05302688 return ret;
Lena Salmand092f2d2012-03-12 17:27:24 +02002689}
2690
2691static int android_remove(struct platform_device *pdev)
2692{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002693 struct android_dev *dev = NULL;
Ofir Cohen94213a72012-05-03 14:26:32 +03002694 struct android_usb_platform_data *pdata = pdev->dev.platform_data;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002695 int usb_core_id = 0;
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05302696
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002697 if (pdata)
2698 usb_core_id = pdata->usb_core_id;
2699
2700 /* Find the android dev from the list */
2701 list_for_each_entry(dev, &android_dev_list, list_item) {
2702 if (!dev->pdata)
2703 break; /*To backward compatibility*/
2704 if (dev->pdata->usb_core_id == usb_core_id)
2705 break;
2706 }
2707
2708 if (dev) {
2709 android_destroy_device(dev);
2710 if (pdata && pdata->swfi_latency)
2711 pm_qos_remove_request(&dev->pm_qos_req_dma);
2712 list_del(&dev->list_item);
2713 android_dev_count--;
2714 kfree(dev);
2715 }
2716
2717 if (list_empty(&android_dev_list)) {
2718 class_destroy(android_class);
2719 android_class = NULL;
2720 usb_composite_unregister(&android_usb_driver);
2721 }
Ofir Cohen94213a72012-05-03 14:26:32 +03002722
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002723 return 0;
2724}
2725
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002726static const struct platform_device_id android_id_table[] __devinitconst = {
2727 {
2728 .name = "android_usb",
2729 },
2730 {
2731 .name = "android_usb_hsic",
2732 },
2733};
2734
Manu Gautam43c61a12012-08-22 17:09:37 -07002735static struct of_device_id usb_android_dt_match[] = {
2736 { .compatible = "qcom,android-usb",
2737 },
2738 {}
2739};
2740
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002741static struct platform_driver android_platform_driver = {
Manu Gautam43c61a12012-08-22 17:09:37 -07002742 .driver = {
2743 .name = "android_usb",
2744 .of_match_table = usb_android_dt_match,
2745 },
Lena Salmand092f2d2012-03-12 17:27:24 +02002746 .probe = android_probe,
2747 .remove = android_remove,
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002748 .id_table = android_id_table,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002749};
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05002750
2751static int __init init(void)
2752{
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05302753 int ret;
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05002754
Benoit Goby1e8ce152011-12-12 13:01:23 -08002755 /* Override composite driver functions */
2756 composite_driver.setup = android_setup;
2757 composite_driver.disconnect = android_disconnect;
Ido Shayevitzfb5edfe2012-12-26 14:26:37 +02002758 composite_driver.suspend = android_suspend;
2759 composite_driver.resume = android_resume;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002760
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002761 INIT_LIST_HEAD(&android_dev_list);
2762 android_dev_count = 0;
2763
Pavankumar Kondeti044914d2012-01-31 12:56:13 +05302764 ret = platform_driver_register(&android_platform_driver);
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05302765 if (ret) {
2766 pr_err("%s(): Failed to register android"
2767 "platform driver\n", __func__);
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05302768 }
Lena Salmand092f2d2012-03-12 17:27:24 +02002769
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05302770 return ret;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002771}
2772module_init(init);
2773
2774static void __exit cleanup(void)
2775{
Lena Salmand092f2d2012-03-12 17:27:24 +02002776 platform_driver_unregister(&android_platform_driver);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002777}
2778module_exit(cleanup);