blob: c65ed259a0205b97f6add83f8ed25451d07352b4 [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"
Bar Weinered1059e2013-04-16 11:23:55 +030056#include "f_gps.c"
Anna Perel3ee23dd2013-02-26 16:06:40 +020057#ifdef CONFIG_SND_PCM
Mike Lockwood11874822012-08-27 16:43:53 +053058#include "f_audio_source.c"
Anna Perel3ee23dd2013-02-26 16:06:40 +020059#endif
Benoit Goby1e8ce152011-12-12 13:01:23 -080060#include "f_mass_storage.c"
61#include "u_serial.c"
Manu Gautama4d993f2011-08-30 18:25:55 +053062#include "u_sdio.c"
63#include "u_smd.c"
64#include "u_bam.c"
Manu Gautam2b0234a2011-09-07 16:47:52 +053065#include "u_rmnet_ctrl_smd.c"
Bar Weiner0dae81b2013-02-14 13:53:54 +020066#include "u_rmnet_ctrl_qti.c"
Jack Pham427f6922011-11-23 19:42:00 -080067#include "u_ctrl_hsic.c"
68#include "u_data_hsic.c"
Vijayavardhan Vennapusaeb8d2392012-04-03 18:58:49 +053069#include "u_ctrl_hsuart.c"
70#include "u_data_hsuart.c"
Manu Gautama4d993f2011-08-30 18:25:55 +053071#include "f_serial.c"
Benoit Goby1e8ce152011-12-12 13:01:23 -080072#include "f_acm.c"
Benoit Goby2b6862d2011-12-19 14:38:41 -080073#include "f_adb.c"
Chiranjeevi Velempatie130fd02011-11-29 05:06:13 +053074#include "f_ccid.c"
Benoit Gobyf0fbc482011-12-19 14:37:50 -080075#include "f_mtp.c"
Benoit Gobycf3fc062011-12-19 14:39:37 -080076#include "f_accessory.c"
Benoit Goby1e8ce152011-12-12 13:01:23 -080077#define USB_ETH_RNDIS y
78#include "f_rndis.c"
79#include "rndis.c"
Amit Blayf9b352b2013-03-04 15:01:40 +020080#include "f_qc_ecm.c"
Anna Perela8c991d2012-04-09 16:44:46 +030081#include "f_mbim.c"
Lena Salmandf7e7992013-03-15 09:46:27 +020082#include "u_bam_data.c"
Anna Perelf9d01552012-11-20 15:56:32 +020083#include "f_ecm.c"
Ofir Cohenaef90b72012-07-31 12:37:04 +020084#include "f_qc_rndis.c"
Jack Pham0ad82e62012-09-27 17:31:08 -070085#include "u_ether.c"
Ofir Cohen7b155422012-07-31 13:02:49 +030086#include "u_qc_ether.c"
Pavankumar Kondeti8f6ca4f2012-06-26 09:44:36 +053087#ifdef CONFIG_TARGET_CORE
88#include "f_tcm.c"
89#endif
Jack Pham2ec5fdc2012-09-26 10:13:48 -070090#ifdef CONFIG_SND_PCM
Anna Perel432367a2012-09-20 10:55:32 +030091#include "u_uac1.c"
92#include "f_uac1.c"
Jack Pham2ec5fdc2012-09-26 10:13:48 -070093#endif
Vamsi Krishna932c9de2013-05-22 12:18:05 -070094#include "f_ncm.c"
Benoit Goby1e8ce152011-12-12 13:01:23 -080095
96MODULE_AUTHOR("Mike Lockwood");
97MODULE_DESCRIPTION("Android Composite USB Driver");
98MODULE_LICENSE("GPL");
99MODULE_VERSION("1.0");
100
101static const char longname[] = "Gadget Android";
102
103/* Default vendor and product IDs, overridden by userspace */
104#define VENDOR_ID 0x18D1
105#define PRODUCT_ID 0x0001
106
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300107#define ANDROID_DEVICE_NODE_NAME_LENGTH 11
108
Benoit Goby1e8ce152011-12-12 13:01:23 -0800109struct android_usb_function {
110 char *name;
111 void *config;
112
113 struct device *dev;
114 char *dev_name;
115 struct device_attribute **attributes;
116
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300117 struct android_dev *android_dev;
118
Benoit Goby1e8ce152011-12-12 13:01:23 -0800119 /* Optional: initialization during gadget bind */
120 int (*init)(struct android_usb_function *, struct usb_composite_dev *);
121 /* Optional: cleanup during gadget unbind */
122 void (*cleanup)(struct android_usb_function *);
Benoit Goby80ba14d2012-03-19 18:56:52 -0700123 /* Optional: called when the function is added the list of
124 * enabled functions */
125 void (*enable)(struct android_usb_function *);
126 /* Optional: called when it is removed */
127 void (*disable)(struct android_usb_function *);
Benoit Goby1e8ce152011-12-12 13:01:23 -0800128
129 int (*bind_config)(struct android_usb_function *,
130 struct usb_configuration *);
131
132 /* Optional: called when the configuration is removed */
133 void (*unbind_config)(struct android_usb_function *,
134 struct usb_configuration *);
135 /* Optional: handle ctrl requests before the device is configured */
136 int (*ctrlrequest)(struct android_usb_function *,
137 struct usb_composite_dev *,
138 const struct usb_ctrlrequest *);
139};
140
Ido Shayevitz68557e32012-11-06 12:40:37 +0200141struct android_usb_function_holder {
142
143 struct android_usb_function *f;
144
145 /* for android_conf.enabled_functions */
146 struct list_head enabled_list;
147};
148
Ido Shayevitzfb5edfe2012-12-26 14:26:37 +0200149/**
150* struct android_dev - represents android USB gadget device
151* @name: device name.
152* @functions: an array of all the supported USB function
153* drivers that this gadget support but not necessarily
154* added to one of the gadget configurations.
155* @cdev: The internal composite device. Android gadget device
156* is a composite device, such that it can support configurations
157* with more than one function driver.
158* @dev: The kernel device that represents this android device.
159* @enabled: True if the android gadget is enabled, means all
160* the configurations were set and all function drivers were
161* bind and ready for USB enumeration.
162* @disable_depth: Number of times the device was disabled, after
163* symmetrical number of enables the device willl be enabled.
164* Used for controlling ADB userspace disable/enable requests.
165* @mutex: Internal mutex for protecting device member fields.
166* @pdata: Platform data fetched from the kernel device platfrom data.
167* @connected: True if got connect notification from the gadget UDC.
168* False if got disconnect notification from the gadget UDC.
169* @sw_connected: Equal to 'connected' only after the connect
170* notification was handled by the android gadget work function.
171* @suspended: True if got suspend notification from the gadget UDC.
172* False if got resume notification from the gadget UDC.
173* @sw_suspended: Equal to 'suspended' only after the susped
174* notification was handled by the android gadget work function.
175* @pm_qos: An attribute string that can be set by user space in order to
176* determine pm_qos policy. Set to 'high' for always demand pm_qos
177* when USB bus is connected and resumed. Set to 'low' for disable
178* any setting of pm_qos by this driver. Default = 'high'.
179* @work: workqueue used for handling notifications from the gadget UDC.
180* @configs: List of configurations currently configured into the device.
181* The android gadget supports more than one configuration. The host
182* may choose one configuration from the suggested.
183* @configs_num: Number of configurations currently configured and existing
184* in the configs list.
185* @list_item: This driver supports more than one android gadget device (for
186* example in order to support multiple USB cores), therefore this is
187* a item in a linked list of android devices.
188*/
Benoit Goby1e8ce152011-12-12 13:01:23 -0800189struct android_dev {
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300190 const char *name;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800191 struct android_usb_function **functions;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800192 struct usb_composite_dev *cdev;
193 struct device *dev;
194
195 bool enabled;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700196 int disable_depth;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800197 struct mutex mutex;
Steve Mucklef132c6c2012-06-06 18:30:57 -0700198 struct android_usb_platform_data *pdata;
199
Benoit Goby1e8ce152011-12-12 13:01:23 -0800200 bool connected;
201 bool sw_connected;
Ido Shayevitzfb5edfe2012-12-26 14:26:37 +0200202 bool suspended;
203 bool sw_suspended;
Ofir Cohen94213a72012-05-03 14:26:32 +0300204 char pm_qos[5];
Steve Mucklef132c6c2012-06-06 18:30:57 -0700205 struct pm_qos_request pm_qos_req_dma;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800206 struct work_struct work;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300207
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300208 /* A list of struct android_configuration */
209 struct list_head configs;
210 int configs_num;
211
212 /* A list node inside the android_dev_list */
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300213 struct list_head list_item;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300214};
215
216struct android_configuration {
217 struct usb_configuration usb_config;
218
219 /* A list of the functions supported by this config */
220 struct list_head enabled_functions;
221
222 /* A list node inside the struct android_dev.configs list */
223 struct list_head list_item;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800224};
225
Manu Gautam43c61a12012-08-22 17:09:37 -0700226struct dload_struct __iomem *diag_dload;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800227static struct class *android_class;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300228static struct list_head android_dev_list;
229static int android_dev_count;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800230static int android_bind_config(struct usb_configuration *c);
231static void android_unbind_config(struct usb_configuration *c);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300232static struct android_dev *cdev_to_android_dev(struct usb_composite_dev *cdev);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300233static struct android_configuration *alloc_android_config
234 (struct android_dev *dev);
235static void free_android_config(struct android_dev *dev,
236 struct android_configuration *conf);
Manu Gautam43c61a12012-08-22 17:09:37 -0700237static int usb_diag_update_pid_and_serial_num(uint32_t pid, const char *snum);
Benoit Goby1e8ce152011-12-12 13:01:23 -0800238
239/* string IDs are assigned dynamically */
240#define STRING_MANUFACTURER_IDX 0
241#define STRING_PRODUCT_IDX 1
242#define STRING_SERIAL_IDX 2
243
244static char manufacturer_string[256];
245static char product_string[256];
246static char serial_string[256];
247
248/* String Table */
249static struct usb_string strings_dev[] = {
250 [STRING_MANUFACTURER_IDX].s = manufacturer_string,
251 [STRING_PRODUCT_IDX].s = product_string,
252 [STRING_SERIAL_IDX].s = serial_string,
253 { } /* end of list */
254};
255
256static struct usb_gadget_strings stringtab_dev = {
257 .language = 0x0409, /* en-us */
258 .strings = strings_dev,
259};
260
261static struct usb_gadget_strings *dev_strings[] = {
262 &stringtab_dev,
263 NULL,
264};
265
266static struct usb_device_descriptor device_desc = {
267 .bLength = sizeof(device_desc),
268 .bDescriptorType = USB_DT_DEVICE,
269 .bcdUSB = __constant_cpu_to_le16(0x0200),
270 .bDeviceClass = USB_CLASS_PER_INTERFACE,
271 .idVendor = __constant_cpu_to_le16(VENDOR_ID),
272 .idProduct = __constant_cpu_to_le16(PRODUCT_ID),
273 .bcdDevice = __constant_cpu_to_le16(0xffff),
274 .bNumConfigurations = 1,
275};
276
Vijayavardhan Vennapusa56e60522012-02-16 15:40:16 +0530277static struct usb_otg_descriptor otg_descriptor = {
278 .bLength = sizeof otg_descriptor,
279 .bDescriptorType = USB_DT_OTG,
280 .bmAttributes = USB_OTG_SRP | USB_OTG_HNP,
281 .bcdOTG = __constant_cpu_to_le16(0x0200),
282};
283
284static const struct usb_descriptor_header *otg_desc[] = {
285 (struct usb_descriptor_header *) &otg_descriptor,
286 NULL,
287};
288
Manu Gautama2b54142012-04-03 14:34:32 +0530289enum android_device_state {
290 USB_DISCONNECTED,
291 USB_CONNECTED,
292 USB_CONFIGURED,
Ido Shayevitzfb5edfe2012-12-26 14:26:37 +0200293 USB_SUSPENDED,
294 USB_RESUMED
Manu Gautama2b54142012-04-03 14:34:32 +0530295};
296
Ofir Cohen94213a72012-05-03 14:26:32 +0300297static void android_pm_qos_update_latency(struct android_dev *dev, int vote)
298{
299 struct android_usb_platform_data *pdata = dev->pdata;
300 u32 swfi_latency = 0;
301 static int last_vote = -1;
302
Ofir Cohen56eb7072012-05-20 11:41:39 +0300303 if (!pdata || vote == last_vote
304 || !pdata->swfi_latency)
Ofir Cohen94213a72012-05-03 14:26:32 +0300305 return;
306
307 swfi_latency = pdata->swfi_latency + 1;
308 if (vote)
309 pm_qos_update_request(&dev->pm_qos_req_dma,
310 swfi_latency);
311 else
312 pm_qos_update_request(&dev->pm_qos_req_dma,
313 PM_QOS_DEFAULT_VALUE);
314 last_vote = vote;
315}
316
Benoit Goby1e8ce152011-12-12 13:01:23 -0800317static void android_work(struct work_struct *data)
318{
319 struct android_dev *dev = container_of(data, struct android_dev, work);
320 struct usb_composite_dev *cdev = dev->cdev;
321 char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL };
322 char *connected[2] = { "USB_STATE=CONNECTED", NULL };
323 char *configured[2] = { "USB_STATE=CONFIGURED", NULL };
Ido Shayevitzfb5edfe2012-12-26 14:26:37 +0200324 char *suspended[2] = { "USB_STATE=SUSPENDED", NULL };
325 char *resumed[2] = { "USB_STATE=RESUMED", NULL };
Benoit Goby1e8ce152011-12-12 13:01:23 -0800326 char **uevent_envp = NULL;
Manu Gautama2b54142012-04-03 14:34:32 +0530327 static enum android_device_state last_uevent, next_state;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800328 unsigned long flags;
Ofir Cohenbcbb1a72012-05-20 16:28:15 +0300329 int pm_qos_vote = -1;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800330
331 spin_lock_irqsave(&cdev->lock, flags);
Ido Shayevitzfb5edfe2012-12-26 14:26:37 +0200332 if (dev->suspended != dev->sw_suspended && cdev->config) {
333 if (strncmp(dev->pm_qos, "low", 3))
334 pm_qos_vote = dev->suspended ? 0 : 1;
335 next_state = dev->suspended ? USB_SUSPENDED : USB_RESUMED;
336 uevent_envp = dev->suspended ? suspended : resumed;
337 } else if (cdev->config) {
Benoit Goby1e8ce152011-12-12 13:01:23 -0800338 uevent_envp = configured;
Manu Gautama2b54142012-04-03 14:34:32 +0530339 next_state = USB_CONFIGURED;
340 } else if (dev->connected != dev->sw_connected) {
Benoit Goby1e8ce152011-12-12 13:01:23 -0800341 uevent_envp = dev->connected ? connected : disconnected;
Manu Gautama2b54142012-04-03 14:34:32 +0530342 next_state = dev->connected ? USB_CONNECTED : USB_DISCONNECTED;
Ofir Cohen94213a72012-05-03 14:26:32 +0300343 if (dev->connected && strncmp(dev->pm_qos, "low", 3))
Ofir Cohenbcbb1a72012-05-20 16:28:15 +0300344 pm_qos_vote = 1;
Ofir Cohen94213a72012-05-03 14:26:32 +0300345 else if (!dev->connected || !strncmp(dev->pm_qos, "low", 3))
Ofir Cohenbcbb1a72012-05-20 16:28:15 +0300346 pm_qos_vote = 0;
Manu Gautama2b54142012-04-03 14:34:32 +0530347 }
Benoit Goby1e8ce152011-12-12 13:01:23 -0800348 dev->sw_connected = dev->connected;
Ido Shayevitzfb5edfe2012-12-26 14:26:37 +0200349 dev->sw_suspended = dev->suspended;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800350 spin_unlock_irqrestore(&cdev->lock, flags);
351
Ofir Cohenbcbb1a72012-05-20 16:28:15 +0300352 if (pm_qos_vote != -1)
353 android_pm_qos_update_latency(dev, pm_qos_vote);
354
Benoit Goby1e8ce152011-12-12 13:01:23 -0800355 if (uevent_envp) {
Manu Gautama2b54142012-04-03 14:34:32 +0530356 /*
357 * Some userspace modules, e.g. MTP, work correctly only if
358 * CONFIGURED uevent is preceded by DISCONNECT uevent.
359 * Check if we missed sending out a DISCONNECT uevent. This can
360 * happen if host PC resets and configures device really quick.
361 */
362 if (((uevent_envp == connected) &&
363 (last_uevent != USB_DISCONNECTED)) ||
364 ((uevent_envp == configured) &&
365 (last_uevent == USB_CONFIGURED))) {
366 pr_info("%s: sent missed DISCONNECT event\n", __func__);
367 kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE,
368 disconnected);
369 msleep(20);
370 }
371 /*
372 * Before sending out CONFIGURED uevent give function drivers
373 * a chance to wakeup userspace threads and notify disconnect
374 */
375 if (uevent_envp == configured)
376 msleep(50);
377
Ido Shayevitzfb5edfe2012-12-26 14:26:37 +0200378 /* Do not notify on suspend / resume */
379 if (next_state != USB_SUSPENDED && next_state != USB_RESUMED) {
380 kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE,
381 uevent_envp);
382 last_uevent = next_state;
383 }
Benoit Goby1e8ce152011-12-12 13:01:23 -0800384 pr_info("%s: sent uevent %s\n", __func__, uevent_envp[0]);
385 } else {
386 pr_info("%s: did not send uevent (%d %d %p)\n", __func__,
387 dev->connected, dev->sw_connected, cdev->config);
388 }
389}
390
Vijayavardhan Vennapusa7a4f2452013-07-19 11:04:39 +0530391static int android_enable(struct android_dev *dev)
Benoit Goby80ba14d2012-03-19 18:56:52 -0700392{
393 struct usb_composite_dev *cdev = dev->cdev;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300394 struct android_configuration *conf;
Vijayavardhan Vennapusa7a4f2452013-07-19 11:04:39 +0530395 int err = 0;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700396
397 if (WARN_ON(!dev->disable_depth))
Vijayavardhan Vennapusa7a4f2452013-07-19 11:04:39 +0530398 return err;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700399
400 if (--dev->disable_depth == 0) {
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300401
Vijayavardhan Vennapusa7a4f2452013-07-19 11:04:39 +0530402 list_for_each_entry(conf, &dev->configs, list_item) {
403 err = usb_add_config(cdev, &conf->usb_config,
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300404 android_bind_config);
Vijayavardhan Vennapusa7a4f2452013-07-19 11:04:39 +0530405 if (err < 0) {
406 pr_err("%s: usb_add_config failed : err: %d\n",
407 __func__, err);
408 return err;
409 }
410 }
Benoit Goby80ba14d2012-03-19 18:56:52 -0700411 usb_gadget_connect(cdev->gadget);
412 }
Vijayavardhan Vennapusa7a4f2452013-07-19 11:04:39 +0530413
414 return err;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700415}
416
417static void android_disable(struct android_dev *dev)
418{
419 struct usb_composite_dev *cdev = dev->cdev;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300420 struct android_configuration *conf;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700421
422 if (dev->disable_depth++ == 0) {
423 usb_gadget_disconnect(cdev->gadget);
424 /* Cancel pending control requests */
425 usb_ep_dequeue(cdev->gadget->ep0, cdev->req);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300426
427 list_for_each_entry(conf, &dev->configs, list_item)
428 usb_remove_config(cdev, &conf->usb_config);
Benoit Goby80ba14d2012-03-19 18:56:52 -0700429 }
430}
Benoit Goby1e8ce152011-12-12 13:01:23 -0800431
432/*-------------------------------------------------------------------------*/
433/* Supported functions initialization */
434
Benoit Goby80ba14d2012-03-19 18:56:52 -0700435struct adb_data {
436 bool opened;
437 bool enabled;
Amit Blay637e5b22013-05-07 17:19:09 +0300438 struct android_dev *dev;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700439};
440
Benoit Goby2b6862d2011-12-19 14:38:41 -0800441static int
442adb_function_init(struct android_usb_function *f,
443 struct usb_composite_dev *cdev)
444{
Benoit Goby80ba14d2012-03-19 18:56:52 -0700445 f->config = kzalloc(sizeof(struct adb_data), GFP_KERNEL);
446 if (!f->config)
447 return -ENOMEM;
448
Benoit Goby2b6862d2011-12-19 14:38:41 -0800449 return adb_setup();
450}
451
452static void adb_function_cleanup(struct android_usb_function *f)
453{
454 adb_cleanup();
Benoit Goby80ba14d2012-03-19 18:56:52 -0700455 kfree(f->config);
Benoit Goby2b6862d2011-12-19 14:38:41 -0800456}
457
458static int
459adb_function_bind_config(struct android_usb_function *f,
460 struct usb_configuration *c)
461{
462 return adb_bind_config(c);
463}
464
Benoit Goby80ba14d2012-03-19 18:56:52 -0700465static void adb_android_function_enable(struct android_usb_function *f)
466{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300467 struct android_dev *dev = f->android_dev;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700468 struct adb_data *data = f->config;
469
470 data->enabled = true;
471
Amit Blay637e5b22013-05-07 17:19:09 +0300472
Benoit Goby80ba14d2012-03-19 18:56:52 -0700473 /* Disable the gadget until adbd is ready */
474 if (!data->opened)
475 android_disable(dev);
476}
477
478static void adb_android_function_disable(struct android_usb_function *f)
479{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300480 struct android_dev *dev = f->android_dev;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700481 struct adb_data *data = f->config;
482
483 data->enabled = false;
484
485 /* Balance the disable that was called in closed_callback */
486 if (!data->opened)
487 android_enable(dev);
488}
489
Benoit Goby2b6862d2011-12-19 14:38:41 -0800490static struct android_usb_function adb_function = {
491 .name = "adb",
Benoit Goby80ba14d2012-03-19 18:56:52 -0700492 .enable = adb_android_function_enable,
493 .disable = adb_android_function_disable,
Benoit Goby2b6862d2011-12-19 14:38:41 -0800494 .init = adb_function_init,
495 .cleanup = adb_function_cleanup,
496 .bind_config = adb_function_bind_config,
497};
498
Benoit Goby80ba14d2012-03-19 18:56:52 -0700499static void adb_ready_callback(void)
500{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300501 struct android_dev *dev = adb_function.android_dev;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700502 struct adb_data *data = adb_function.config;
503
Amit Blay637e5b22013-05-07 17:19:09 +0300504 /* dev is null in case ADB is not in the composition */
505 if (dev)
506 mutex_lock(&dev->mutex);
507
508 /* Save dev in case the adb function will get disabled */
509 data->dev = dev;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700510 data->opened = true;
511
Amit Blay637e5b22013-05-07 17:19:09 +0300512 if (data->enabled && dev)
Benoit Goby80ba14d2012-03-19 18:56:52 -0700513 android_enable(dev);
Amit Blay637e5b22013-05-07 17:19:09 +0300514
515 if (dev)
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300516 mutex_unlock(&dev->mutex);
Benoit Goby80ba14d2012-03-19 18:56:52 -0700517}
518
519static void adb_closed_callback(void)
520{
Benoit Goby80ba14d2012-03-19 18:56:52 -0700521 struct adb_data *data = adb_function.config;
Amit Blay637e5b22013-05-07 17:19:09 +0300522 struct android_dev *dev = adb_function.android_dev;
523
524 /* In case new composition is without ADB, use saved one */
525 if (!dev)
526 dev = data->dev;
527
528 if (!dev)
529 pr_err("adb_closed_callback: data->dev is NULL");
530
531 if (dev)
532 mutex_lock(&dev->mutex);
Benoit Goby80ba14d2012-03-19 18:56:52 -0700533
Benoit Goby80ba14d2012-03-19 18:56:52 -0700534 data->opened = false;
535
Pavankumar Kondetidc1f67e2013-05-28 12:10:24 +0530536 if (data->enabled && dev)
Benoit Goby80ba14d2012-03-19 18:56:52 -0700537 android_disable(dev);
Amit Blay637e5b22013-05-07 17:19:09 +0300538
539 data->dev = NULL;
540
541 if (dev)
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300542 mutex_unlock(&dev->mutex);
Benoit Goby80ba14d2012-03-19 18:56:52 -0700543}
544
Benoit Goby2b6862d2011-12-19 14:38:41 -0800545
Benoit Gobyaab96812011-04-19 20:37:33 -0700546/*-------------------------------------------------------------------------*/
547/* Supported functions initialization */
548
Stephen Boyd83ed8e22013-03-08 17:04:08 -0800549/* ACM */
550static char acm_transports[32]; /*enabled ACM ports - "tty[,sdio]"*/
551static ssize_t acm_transports_store(
552 struct device *device, struct device_attribute *attr,
553 const char *buff, size_t size)
554{
555 strlcpy(acm_transports, buff, sizeof(acm_transports));
556
557 return size;
558}
559
560static DEVICE_ATTR(acm_transports, S_IWUSR, NULL, acm_transports_store);
561static struct device_attribute *acm_function_attributes[] = {
562 &dev_attr_acm_transports,
563 NULL
564};
565
566static void acm_function_cleanup(struct android_usb_function *f)
567{
568 gserial_cleanup();
569}
570
571static int
572acm_function_bind_config(struct android_usb_function *f,
573 struct usb_configuration *c)
574{
575 char *name;
576 char buf[32], *b;
577 int err = -1, i;
578 static int acm_initialized, ports;
579
580 if (acm_initialized)
581 goto bind_config;
582
583 acm_initialized = 1;
584 strlcpy(buf, acm_transports, sizeof(buf));
585 b = strim(buf);
586
587 while (b) {
588 name = strsep(&b, ",");
589
590 if (name) {
591 err = acm_init_port(ports, name);
592 if (err) {
593 pr_err("acm: Cannot open port '%s'", name);
594 goto out;
595 }
596 ports++;
597 }
598 }
599 err = acm_port_setup(c);
600 if (err) {
601 pr_err("acm: Cannot setup transports");
602 goto out;
603 }
604
605bind_config:
606 for (i = 0; i < ports; i++) {
607 err = acm_bind_config(c, i);
608 if (err) {
609 pr_err("acm: bind_config failed for port %d", i);
610 goto out;
611 }
612 }
613
614out:
615 return err;
616}
617
618static struct android_usb_function acm_function = {
619 .name = "acm",
620 .cleanup = acm_function_cleanup,
621 .bind_config = acm_function_bind_config,
622 .attributes = acm_function_attributes,
623};
624
Manu Gautam8e0719b2011-09-26 14:47:55 +0530625/* RMNET_SMD */
Manu Gautam1c8ffd72011-09-02 16:00:49 +0530626static int rmnet_smd_function_bind_config(struct android_usb_function *f,
627 struct usb_configuration *c)
628{
629 return rmnet_smd_bind_config(c);
630}
631
632static struct android_usb_function rmnet_smd_function = {
633 .name = "rmnet_smd",
634 .bind_config = rmnet_smd_function_bind_config,
Benoit Goby1e8ce152011-12-12 13:01:23 -0800635};
636
Manu Gautam8e0719b2011-09-26 14:47:55 +0530637/* RMNET_SDIO */
638static int rmnet_sdio_function_bind_config(struct android_usb_function *f,
639 struct usb_configuration *c)
Benoit Goby1e8ce152011-12-12 13:01:23 -0800640{
Manu Gautam8e0719b2011-09-26 14:47:55 +0530641 return rmnet_sdio_function_add(c);
Benoit Goby1e8ce152011-12-12 13:01:23 -0800642}
643
Manu Gautam8e0719b2011-09-26 14:47:55 +0530644static struct android_usb_function rmnet_sdio_function = {
645 .name = "rmnet_sdio",
646 .bind_config = rmnet_sdio_function_bind_config,
647};
648
649/* RMNET_SMD_SDIO */
650static int rmnet_smd_sdio_function_init(struct android_usb_function *f,
651 struct usb_composite_dev *cdev)
652{
653 return rmnet_smd_sdio_init();
654}
655
656static void rmnet_smd_sdio_function_cleanup(struct android_usb_function *f)
657{
658 rmnet_smd_sdio_cleanup();
659}
660
661static int rmnet_smd_sdio_bind_config(struct android_usb_function *f,
662 struct usb_configuration *c)
663{
664 return rmnet_smd_sdio_function_add(c);
665}
666
667static struct device_attribute *rmnet_smd_sdio_attributes[] = {
668 &dev_attr_transport, NULL };
669
670static struct android_usb_function rmnet_smd_sdio_function = {
671 .name = "rmnet_smd_sdio",
672 .init = rmnet_smd_sdio_function_init,
673 .cleanup = rmnet_smd_sdio_function_cleanup,
674 .bind_config = rmnet_smd_sdio_bind_config,
675 .attributes = rmnet_smd_sdio_attributes,
676};
677
Hemant Kumar1b820d52011-11-03 15:08:28 -0700678/*rmnet transport string format(per port):"ctrl0,data0,ctrl1,data1..." */
679#define MAX_XPORT_STR_LEN 50
680static char rmnet_transports[MAX_XPORT_STR_LEN];
Manu Gautam1c8ffd72011-09-02 16:00:49 +0530681
Hemant Kumarc2b17782013-02-03 15:56:29 -0800682/*rmnet transport name string - "rmnet_hsic[,rmnet_hsusb]" */
683static char rmnet_xport_names[MAX_XPORT_STR_LEN];
684
Manu Gautame3e897c2011-09-12 17:18:46 +0530685static void rmnet_function_cleanup(struct android_usb_function *f)
686{
687 frmnet_cleanup();
688}
689
Manu Gautam2b0234a2011-09-07 16:47:52 +0530690static int rmnet_function_bind_config(struct android_usb_function *f,
691 struct usb_configuration *c)
692{
693 int i;
Hemant Kumar1b820d52011-11-03 15:08:28 -0700694 int err = 0;
695 char *ctrl_name;
696 char *data_name;
Hemant Kumarc2b17782013-02-03 15:56:29 -0800697 char *tname = NULL;
Hemant Kumar1b820d52011-11-03 15:08:28 -0700698 char buf[MAX_XPORT_STR_LEN], *b;
Hemant Kumarc2b17782013-02-03 15:56:29 -0800699 char xport_name_buf[MAX_XPORT_STR_LEN], *tb;
Hemant Kumar1b820d52011-11-03 15:08:28 -0700700 static int rmnet_initialized, ports;
Manu Gautam2b0234a2011-09-07 16:47:52 +0530701
Hemant Kumar1b820d52011-11-03 15:08:28 -0700702 if (!rmnet_initialized) {
703 rmnet_initialized = 1;
704 strlcpy(buf, rmnet_transports, sizeof(buf));
705 b = strim(buf);
Hemant Kumarc2b17782013-02-03 15:56:29 -0800706
707 strlcpy(xport_name_buf, rmnet_xport_names,
708 sizeof(xport_name_buf));
709 tb = strim(xport_name_buf);
710
Hemant Kumar1b820d52011-11-03 15:08:28 -0700711 while (b) {
712 ctrl_name = strsep(&b, ",");
713 data_name = strsep(&b, ",");
714 if (ctrl_name && data_name) {
Hemant Kumarc2b17782013-02-03 15:56:29 -0800715 if (tb)
716 tname = strsep(&tb, ",");
717 err = frmnet_init_port(ctrl_name, data_name,
718 tname);
Hemant Kumar1b820d52011-11-03 15:08:28 -0700719 if (err) {
720 pr_err("rmnet: Cannot open ctrl port:"
721 "'%s' data port:'%s'\n",
722 ctrl_name, data_name);
723 goto out;
724 }
725 ports++;
726 }
727 }
728
729 err = rmnet_gport_setup();
730 if (err) {
731 pr_err("rmnet: Cannot setup transports");
732 goto out;
733 }
734 }
735
736 for (i = 0; i < ports; i++) {
737 err = frmnet_bind_config(c, i);
738 if (err) {
Manu Gautam2b0234a2011-09-07 16:47:52 +0530739 pr_err("Could not bind rmnet%u config\n", i);
740 break;
741 }
742 }
Hemant Kumar1b820d52011-11-03 15:08:28 -0700743out:
744 return err;
Manu Gautam2b0234a2011-09-07 16:47:52 +0530745}
746
Hemant Kumar1b820d52011-11-03 15:08:28 -0700747static ssize_t rmnet_transports_show(struct device *dev,
Manu Gautam2b0234a2011-09-07 16:47:52 +0530748 struct device_attribute *attr, char *buf)
749{
Hemant Kumar1b820d52011-11-03 15:08:28 -0700750 return snprintf(buf, PAGE_SIZE, "%s\n", rmnet_transports);
Manu Gautam2b0234a2011-09-07 16:47:52 +0530751}
752
Hemant Kumar1b820d52011-11-03 15:08:28 -0700753static ssize_t rmnet_transports_store(
754 struct device *device, struct device_attribute *attr,
755 const char *buff, size_t size)
Manu Gautam2b0234a2011-09-07 16:47:52 +0530756{
Hemant Kumar1b820d52011-11-03 15:08:28 -0700757 strlcpy(rmnet_transports, buff, sizeof(rmnet_transports));
Manu Gautam2b0234a2011-09-07 16:47:52 +0530758
Manu Gautam2b0234a2011-09-07 16:47:52 +0530759 return size;
760}
761
Hemant Kumarc2b17782013-02-03 15:56:29 -0800762static ssize_t rmnet_xport_names_show(struct device *dev,
763 struct device_attribute *attr, char *buf)
764{
765 return snprintf(buf, PAGE_SIZE, "%s\n", rmnet_xport_names);
766}
767
768static ssize_t rmnet_xport_names_store(
769 struct device *device, struct device_attribute *attr,
770 const char *buff, size_t size)
771{
772 strlcpy(rmnet_xport_names, buff, sizeof(rmnet_xport_names));
773
774 return size;
775}
776
Hemant Kumar1b820d52011-11-03 15:08:28 -0700777static struct device_attribute dev_attr_rmnet_transports =
778 __ATTR(transports, S_IRUGO | S_IWUSR,
779 rmnet_transports_show,
780 rmnet_transports_store);
Hemant Kumarc2b17782013-02-03 15:56:29 -0800781
782static struct device_attribute dev_attr_rmnet_xport_names =
783 __ATTR(transport_names, S_IRUGO | S_IWUSR,
784 rmnet_xport_names_show,
785 rmnet_xport_names_store);
786
Manu Gautam2b0234a2011-09-07 16:47:52 +0530787static struct device_attribute *rmnet_function_attributes[] = {
Hemant Kumar1b820d52011-11-03 15:08:28 -0700788 &dev_attr_rmnet_transports,
Hemant Kumarc2b17782013-02-03 15:56:29 -0800789 &dev_attr_rmnet_xport_names,
Hemant Kumar1b820d52011-11-03 15:08:28 -0700790 NULL };
Manu Gautam2b0234a2011-09-07 16:47:52 +0530791
792static struct android_usb_function rmnet_function = {
793 .name = "rmnet",
Manu Gautame3e897c2011-09-12 17:18:46 +0530794 .cleanup = rmnet_function_cleanup,
Manu Gautam2b0234a2011-09-07 16:47:52 +0530795 .bind_config = rmnet_function_bind_config,
796 .attributes = rmnet_function_attributes,
797};
798
Bar Weinered1059e2013-04-16 11:23:55 +0300799static void gps_function_cleanup(struct android_usb_function *f)
800{
801 gps_cleanup();
802}
803
804static int gps_function_bind_config(struct android_usb_function *f,
805 struct usb_configuration *c)
806{
807 int err;
808 static int gps_initialized;
809
810 if (!gps_initialized) {
811 gps_initialized = 1;
812 err = gps_init_port();
813 if (err) {
814 pr_err("gps: Cannot init gps port");
815 return err;
816 }
817 }
818
819 err = gps_gport_setup();
820 if (err) {
821 pr_err("gps: Cannot setup transports");
822 return err;
823 }
824 err = gps_bind_config(c);
825 if (err) {
826 pr_err("Could not bind gps config\n");
827 return err;
828 }
829
830 return 0;
831}
832
833static struct android_usb_function gps_function = {
834 .name = "gps",
835 .cleanup = gps_function_cleanup,
836 .bind_config = gps_function_bind_config,
837};
838
Vamsi Krishna932c9de2013-05-22 12:18:05 -0700839/* ncm */
840struct ncm_function_config {
841 u8 ethaddr[ETH_ALEN];
842};
843static int
844ncm_function_init(struct android_usb_function *f, struct usb_composite_dev *c)
845{
846 f->config = kzalloc(sizeof(struct ncm_function_config), GFP_KERNEL);
847 if (!f->config)
848 return -ENOMEM;
Bar Weinered1059e2013-04-16 11:23:55 +0300849
Vamsi Krishna932c9de2013-05-22 12:18:05 -0700850 return 0;
851}
852
853static void ncm_function_cleanup(struct android_usb_function *f)
854{
855 kfree(f->config);
856 f->config = NULL;
857}
858
859static int
860ncm_function_bind_config(struct android_usb_function *f,
861 struct usb_configuration *c)
862{
863 struct ncm_function_config *ncm = f->config;
864 int ret;
865
866 if (!ncm) {
867 pr_err("%s: ncm config is null\n", __func__);
868 return -EINVAL;
869 }
870
871 pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
872 ncm->ethaddr[0], ncm->ethaddr[1], ncm->ethaddr[2],
873 ncm->ethaddr[3], ncm->ethaddr[4], ncm->ethaddr[5]);
874
875 ret = gether_setup_name(c->cdev->gadget, ncm->ethaddr, "ncm");
876 if (ret) {
877 pr_err("%s: gether setup failed err:%d\n", __func__, ret);
878 return ret;
879 }
880
881 ret = ncm_bind_config(c, ncm->ethaddr);
882 if (ret) {
883 pr_err("%s: ncm bind config failed err:%d", __func__, ret);
884 gether_cleanup();
885 return ret;
886 }
887
888 return ret;
889}
890
891static void ncm_function_unbind_config(struct android_usb_function *f,
892 struct usb_configuration *c)
893{
894 gether_cleanup();
895}
896
897static ssize_t ncm_ethaddr_show(struct device *dev,
898 struct device_attribute *attr, char *buf)
899{
900 struct android_usb_function *f = dev_get_drvdata(dev);
901 struct ncm_function_config *ncm = f->config;
902 return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n",
903 ncm->ethaddr[0], ncm->ethaddr[1], ncm->ethaddr[2],
904 ncm->ethaddr[3], ncm->ethaddr[4], ncm->ethaddr[5]);
905}
906
907static ssize_t ncm_ethaddr_store(struct device *dev,
908 struct device_attribute *attr, const char *buf, size_t size)
909{
910 struct android_usb_function *f = dev_get_drvdata(dev);
911 struct ncm_function_config *ncm = f->config;
912
913 if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
914 (int *)&ncm->ethaddr[0], (int *)&ncm->ethaddr[1],
915 (int *)&ncm->ethaddr[2], (int *)&ncm->ethaddr[3],
916 (int *)&ncm->ethaddr[4], (int *)&ncm->ethaddr[5]) == 6)
917 return size;
918 return -EINVAL;
919}
920
921static DEVICE_ATTR(ncm_ethaddr, S_IRUGO | S_IWUSR, ncm_ethaddr_show,
922 ncm_ethaddr_store);
923static struct device_attribute *ncm_function_attributes[] = {
924 &dev_attr_ncm_ethaddr,
925 NULL
926};
927
928static struct android_usb_function ncm_function = {
929 .name = "ncm",
930 .init = ncm_function_init,
931 .cleanup = ncm_function_cleanup,
932 .bind_config = ncm_function_bind_config,
933 .unbind_config = ncm_function_unbind_config,
934 .attributes = ncm_function_attributes,
935};
Amit Blayf9b352b2013-03-04 15:01:40 +0200936/* ecm transport string */
937static char ecm_transports[MAX_XPORT_STR_LEN];
938
Ofir Cohen7b155422012-07-31 13:02:49 +0300939struct ecm_function_config {
940 u8 ethaddr[ETH_ALEN];
941};
942
943static int ecm_function_init(struct android_usb_function *f,
944 struct usb_composite_dev *cdev)
945{
946 f->config = kzalloc(sizeof(struct ecm_function_config), GFP_KERNEL);
947 if (!f->config)
948 return -ENOMEM;
949 return 0;
950}
951
952static void ecm_function_cleanup(struct android_usb_function *f)
953{
954 kfree(f->config);
955 f->config = NULL;
956}
957
958static int ecm_qc_function_bind_config(struct android_usb_function *f,
959 struct usb_configuration *c)
960{
961 int ret;
Amit Blayf9b352b2013-03-04 15:01:40 +0200962 char *trans;
Ofir Cohen7b155422012-07-31 13:02:49 +0300963 struct ecm_function_config *ecm = f->config;
964
965 if (!ecm) {
966 pr_err("%s: ecm_pdata\n", __func__);
967 return -EINVAL;
968 }
969
970 pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
971 ecm->ethaddr[0], ecm->ethaddr[1], ecm->ethaddr[2],
972 ecm->ethaddr[3], ecm->ethaddr[4], ecm->ethaddr[5]);
973
Amit Blayf9b352b2013-03-04 15:01:40 +0200974 pr_debug("%s: ecm_transport is %s", __func__, ecm_transports);
975
976 trans = strim(ecm_transports);
977 if (strcmp("BAM2BAM_IPA", trans)) {
978 ret = gether_qc_setup_name(c->cdev->gadget,
979 ecm->ethaddr, "ecm");
980 if (ret) {
981 pr_err("%s: gether_setup failed\n", __func__);
982 return ret;
983 }
Ofir Cohen7b155422012-07-31 13:02:49 +0300984 }
985
Amit Blayf9b352b2013-03-04 15:01:40 +0200986 return ecm_qc_bind_config(c, ecm->ethaddr, trans);
Ofir Cohen7b155422012-07-31 13:02:49 +0300987}
988
989static void ecm_qc_function_unbind_config(struct android_usb_function *f,
990 struct usb_configuration *c)
991{
Amit Blayf9b352b2013-03-04 15:01:40 +0200992 char *trans = strim(ecm_transports);
993
994 if (strcmp("BAM2BAM_IPA", trans))
995 gether_qc_cleanup_name("ecm0");
Ofir Cohen7b155422012-07-31 13:02:49 +0300996}
997
998static ssize_t ecm_ethaddr_show(struct device *dev,
999 struct device_attribute *attr, char *buf)
1000{
1001 struct android_usb_function *f = dev_get_drvdata(dev);
1002 struct ecm_function_config *ecm = f->config;
1003 return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n",
1004 ecm->ethaddr[0], ecm->ethaddr[1], ecm->ethaddr[2],
1005 ecm->ethaddr[3], ecm->ethaddr[4], ecm->ethaddr[5]);
1006}
1007
1008static ssize_t ecm_ethaddr_store(struct device *dev,
1009 struct device_attribute *attr, const char *buf, size_t size)
1010{
1011 struct android_usb_function *f = dev_get_drvdata(dev);
1012 struct ecm_function_config *ecm = f->config;
1013
1014 if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
1015 (int *)&ecm->ethaddr[0], (int *)&ecm->ethaddr[1],
1016 (int *)&ecm->ethaddr[2], (int *)&ecm->ethaddr[3],
1017 (int *)&ecm->ethaddr[4], (int *)&ecm->ethaddr[5]) == 6)
1018 return size;
1019 return -EINVAL;
1020}
1021
1022static DEVICE_ATTR(ecm_ethaddr, S_IRUGO | S_IWUSR, ecm_ethaddr_show,
1023 ecm_ethaddr_store);
1024
Amit Blayf9b352b2013-03-04 15:01:40 +02001025static ssize_t ecm_transports_show(struct device *dev,
1026 struct device_attribute *attr, char *buf)
1027{
1028 return snprintf(buf, PAGE_SIZE, "%s\n", ecm_transports);
1029}
1030
1031static ssize_t ecm_transports_store(struct device *dev,
1032 struct device_attribute *attr, const char *buf, size_t size)
1033{
1034 strlcpy(ecm_transports, buf, sizeof(ecm_transports));
1035 return size;
1036}
1037
1038static DEVICE_ATTR(ecm_transports, S_IRUGO | S_IWUSR, ecm_transports_show,
1039 ecm_transports_store);
1040
Ofir Cohen7b155422012-07-31 13:02:49 +03001041static struct device_attribute *ecm_function_attributes[] = {
Amit Blayf9b352b2013-03-04 15:01:40 +02001042 &dev_attr_ecm_transports,
Ofir Cohen7b155422012-07-31 13:02:49 +03001043 &dev_attr_ecm_ethaddr,
1044 NULL
1045};
1046
1047static struct android_usb_function ecm_qc_function = {
1048 .name = "ecm_qc",
1049 .init = ecm_function_init,
1050 .cleanup = ecm_function_cleanup,
1051 .bind_config = ecm_qc_function_bind_config,
1052 .unbind_config = ecm_qc_function_unbind_config,
1053 .attributes = ecm_function_attributes,
1054};
Anna Perela8c991d2012-04-09 16:44:46 +03001055
1056/* MBIM - used with BAM */
1057#define MAX_MBIM_INSTANCES 1
1058
1059static int mbim_function_init(struct android_usb_function *f,
1060 struct usb_composite_dev *cdev)
1061{
1062 return mbim_init(MAX_MBIM_INSTANCES);
1063}
1064
1065static void mbim_function_cleanup(struct android_usb_function *f)
1066{
1067 fmbim_cleanup();
1068}
1069
Lena Salmandf7e7992013-03-15 09:46:27 +02001070
1071/* mbim transport string */
1072static char mbim_transports[MAX_XPORT_STR_LEN];
1073
Anna Perela8c991d2012-04-09 16:44:46 +03001074static int mbim_function_bind_config(struct android_usb_function *f,
1075 struct usb_configuration *c)
1076{
Lena Salmandf7e7992013-03-15 09:46:27 +02001077 char *trans;
1078
1079 pr_debug("%s: mbim transport is %s", __func__, mbim_transports);
1080 trans = strim(mbim_transports);
1081 return mbim_bind_config(c, 0, trans);
Anna Perela8c991d2012-04-09 16:44:46 +03001082}
1083
Jack Pham2df2f702012-10-11 19:08:24 -07001084static int mbim_function_ctrlrequest(struct android_usb_function *f,
1085 struct usb_composite_dev *cdev,
1086 const struct usb_ctrlrequest *c)
1087{
1088 return mbim_ctrlrequest(cdev, c);
1089}
1090
Lena Salmandf7e7992013-03-15 09:46:27 +02001091static ssize_t mbim_transports_show(struct device *dev,
1092 struct device_attribute *attr, char *buf)
1093{
1094 return snprintf(buf, PAGE_SIZE, "%s\n", mbim_transports);
1095}
1096
1097static ssize_t mbim_transports_store(struct device *dev,
1098 struct device_attribute *attr, const char *buf, size_t size)
1099{
1100 strlcpy(mbim_transports, buf, sizeof(mbim_transports));
1101 return size;
1102}
1103
1104static DEVICE_ATTR(mbim_transports, S_IRUGO | S_IWUSR, mbim_transports_show,
1105 mbim_transports_store);
1106
1107static struct device_attribute *mbim_function_attributes[] = {
1108 &dev_attr_mbim_transports,
1109 NULL
1110};
1111
Anna Perela8c991d2012-04-09 16:44:46 +03001112static struct android_usb_function mbim_function = {
1113 .name = "usb_mbim",
1114 .cleanup = mbim_function_cleanup,
1115 .bind_config = mbim_function_bind_config,
1116 .init = mbim_function_init,
Jack Pham2df2f702012-10-11 19:08:24 -07001117 .ctrlrequest = mbim_function_ctrlrequest,
Lena Salmandf7e7992013-03-15 09:46:27 +02001118 .attributes = mbim_function_attributes,
Anna Perela8c991d2012-04-09 16:44:46 +03001119};
1120
Jack Pham2ec5fdc2012-09-26 10:13:48 -07001121#ifdef CONFIG_SND_PCM
Anna Perel432367a2012-09-20 10:55:32 +03001122/* PERIPHERAL AUDIO */
1123static int audio_function_bind_config(struct android_usb_function *f,
1124 struct usb_configuration *c)
1125{
1126 return audio_bind_config(c);
1127}
1128
1129static struct android_usb_function audio_function = {
1130 .name = "audio",
1131 .bind_config = audio_function_bind_config,
1132};
Jack Pham2ec5fdc2012-09-26 10:13:48 -07001133#endif
Anna Perel432367a2012-09-20 10:55:32 +03001134
Anna Perela8c991d2012-04-09 16:44:46 +03001135
Manu Gautam8e0719b2011-09-26 14:47:55 +05301136/* DIAG */
Manu Gautam2b0234a2011-09-07 16:47:52 +05301137static char diag_clients[32]; /*enabled DIAG clients- "diag[,diag_mdm]" */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001138static ssize_t clients_store(
1139 struct device *device, struct device_attribute *attr,
1140 const char *buff, size_t size)
1141{
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301142 strlcpy(diag_clients, buff, sizeof(diag_clients));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001143
1144 return size;
1145}
1146
1147static DEVICE_ATTR(clients, S_IWUSR, NULL, clients_store);
1148static struct device_attribute *diag_function_attributes[] =
1149 { &dev_attr_clients, NULL };
1150
1151static int diag_function_init(struct android_usb_function *f,
1152 struct usb_composite_dev *cdev)
1153{
1154 return diag_setup();
1155}
1156
1157static void diag_function_cleanup(struct android_usb_function *f)
1158{
1159 diag_cleanup();
1160}
1161
1162static int diag_function_bind_config(struct android_usb_function *f,
1163 struct usb_configuration *c)
1164{
1165 char *name;
1166 char buf[32], *b;
Manu Gautamc5760302011-08-25 14:30:24 +05301167 int once = 0, err = -1;
Jack Phamb830a6c2011-12-12 22:35:27 -08001168 int (*notify)(uint32_t, const char *);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001169 struct android_dev *dev = cdev_to_android_dev(c->cdev);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001170
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301171 strlcpy(buf, diag_clients, sizeof(buf));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001172 b = strim(buf);
1173
1174 while (b) {
Jack Phamb830a6c2011-12-12 22:35:27 -08001175 notify = NULL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001176 name = strsep(&b, ",");
Manu Gautamc5760302011-08-25 14:30:24 +05301177 /* Allow only first diag channel to update pid and serial no */
Manu Gautam43c61a12012-08-22 17:09:37 -07001178 if (!once++) {
1179 if (dev->pdata && dev->pdata->update_pid_and_serial_num)
1180 notify = dev->pdata->update_pid_and_serial_num;
1181 else
1182 notify = usb_diag_update_pid_and_serial_num;
1183 }
Manu Gautamc5760302011-08-25 14:30:24 +05301184
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001185 if (name) {
Manu Gautamc5760302011-08-25 14:30:24 +05301186 err = diag_function_add(c, name, notify);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001187 if (err)
1188 pr_err("diag: Cannot open channel '%s'", name);
1189 }
1190 }
1191
1192 return err;
1193}
1194
1195static struct android_usb_function diag_function = {
1196 .name = "diag",
1197 .init = diag_function_init,
1198 .cleanup = diag_function_cleanup,
1199 .bind_config = diag_function_bind_config,
1200 .attributes = diag_function_attributes,
1201};
1202
Shimrit Malichia00d7322012-08-05 13:56:28 +03001203/* DEBUG */
1204static int qdss_function_init(struct android_usb_function *f,
1205 struct usb_composite_dev *cdev)
1206{
1207 return qdss_setup();
1208}
1209
1210static void qdss_function_cleanup(struct android_usb_function *f)
1211{
1212 qdss_cleanup();
1213}
1214
1215static int qdss_function_bind_config(struct android_usb_function *f,
1216 struct usb_configuration *c)
1217{
1218 int err = -1;
1219
1220 err = qdss_bind_config(c, "qdss");
1221 if (err)
1222 pr_err("qdss: Cannot open channel qdss");
1223
1224 return err;
1225}
1226
1227static struct android_usb_function qdss_function = {
1228 .name = "qdss",
1229 .init = qdss_function_init,
1230 .cleanup = qdss_function_cleanup,
1231 .bind_config = qdss_function_bind_config,
1232};
1233
Manu Gautam8e0719b2011-09-26 14:47:55 +05301234/* SERIAL */
Manu Gautam2b0234a2011-09-07 16:47:52 +05301235static char serial_transports[32]; /*enabled FSERIAL ports - "tty[,sdio]"*/
Manu Gautama4d993f2011-08-30 18:25:55 +05301236static ssize_t serial_transports_store(
1237 struct device *device, struct device_attribute *attr,
1238 const char *buff, size_t size)
1239{
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301240 strlcpy(serial_transports, buff, sizeof(serial_transports));
Manu Gautama4d993f2011-08-30 18:25:55 +05301241
1242 return size;
1243}
1244
Hemant Kumarc2b17782013-02-03 15:56:29 -08001245/*enabled FSERIAL transport names - "serial_hsic[,serial_hsusb]"*/
1246static char serial_xport_names[32];
1247static ssize_t serial_xport_names_store(
1248 struct device *device, struct device_attribute *attr,
1249 const char *buff, size_t size)
1250{
1251 strlcpy(serial_xport_names, buff, sizeof(serial_xport_names));
1252
1253 return size;
1254}
1255
1256static ssize_t serial_xport_names_show(struct device *dev,
1257 struct device_attribute *attr, char *buf)
1258{
1259 return snprintf(buf, PAGE_SIZE, "%s\n", serial_xport_names);
1260}
1261
Manu Gautama4d993f2011-08-30 18:25:55 +05301262static DEVICE_ATTR(transports, S_IWUSR, NULL, serial_transports_store);
Hemant Kumarc2b17782013-02-03 15:56:29 -08001263static struct device_attribute dev_attr_serial_xport_names =
1264 __ATTR(transport_names, S_IRUGO | S_IWUSR,
1265 serial_xport_names_show,
1266 serial_xport_names_store);
1267
1268static struct device_attribute *serial_function_attributes[] = {
1269 &dev_attr_transports,
1270 &dev_attr_serial_xport_names,
1271 NULL };
Manu Gautama4d993f2011-08-30 18:25:55 +05301272
1273static void serial_function_cleanup(struct android_usb_function *f)
1274{
1275 gserial_cleanup();
1276}
1277
1278static int serial_function_bind_config(struct android_usb_function *f,
1279 struct usb_configuration *c)
1280{
Hemant Kumarc2b17782013-02-03 15:56:29 -08001281 char *name, *xport_name = NULL;
1282 char buf[32], *b, xport_name_buf[32], *tb;
Manu Gautama4d993f2011-08-30 18:25:55 +05301283 int err = -1, i;
1284 static int serial_initialized = 0, ports = 0;
1285
1286 if (serial_initialized)
1287 goto bind_config;
1288
1289 serial_initialized = 1;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301290 strlcpy(buf, serial_transports, sizeof(buf));
Manu Gautama4d993f2011-08-30 18:25:55 +05301291 b = strim(buf);
1292
Hemant Kumarc2b17782013-02-03 15:56:29 -08001293 strlcpy(xport_name_buf, serial_xport_names, sizeof(xport_name_buf));
1294 tb = strim(xport_name_buf);
1295
Manu Gautama4d993f2011-08-30 18:25:55 +05301296 while (b) {
1297 name = strsep(&b, ",");
1298
1299 if (name) {
Hemant Kumarc2b17782013-02-03 15:56:29 -08001300 if (tb)
1301 xport_name = strsep(&tb, ",");
1302 err = gserial_init_port(ports, name, xport_name);
Manu Gautama4d993f2011-08-30 18:25:55 +05301303 if (err) {
1304 pr_err("serial: Cannot open port '%s'", name);
1305 goto out;
1306 }
1307 ports++;
1308 }
1309 }
1310 err = gport_setup(c);
1311 if (err) {
1312 pr_err("serial: Cannot setup transports");
1313 goto out;
1314 }
1315
1316bind_config:
Lena Salmand092f2d2012-03-12 17:27:24 +02001317 for (i = 0; i < ports; i++) {
Manu Gautama4d993f2011-08-30 18:25:55 +05301318 err = gser_bind_config(c, i);
1319 if (err) {
1320 pr_err("serial: bind_config failed for port %d", i);
1321 goto out;
1322 }
1323 }
1324
1325out:
1326 return err;
1327}
1328
1329static struct android_usb_function serial_function = {
1330 .name = "serial",
1331 .cleanup = serial_function_cleanup,
1332 .bind_config = serial_function_bind_config,
1333 .attributes = serial_function_attributes,
1334};
1335
Chiranjeevi Velempatie130fd02011-11-29 05:06:13 +05301336/* CCID */
1337static int ccid_function_init(struct android_usb_function *f,
1338 struct usb_composite_dev *cdev)
1339{
1340 return ccid_setup();
1341}
Benoit Goby1e8ce152011-12-12 13:01:23 -08001342
Chiranjeevi Velempatie130fd02011-11-29 05:06:13 +05301343static void ccid_function_cleanup(struct android_usb_function *f)
1344{
1345 ccid_cleanup();
1346}
1347
1348static int ccid_function_bind_config(struct android_usb_function *f,
1349 struct usb_configuration *c)
1350{
1351 return ccid_bind_config(c);
1352}
1353
1354static struct android_usb_function ccid_function = {
1355 .name = "ccid",
1356 .init = ccid_function_init,
1357 .cleanup = ccid_function_cleanup,
1358 .bind_config = ccid_function_bind_config,
1359};
1360
Stephen Boyd83ed8e22013-03-08 17:04:08 -08001361static int
1362mtp_function_init(struct android_usb_function *f,
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001363 struct usb_composite_dev *cdev)
1364{
1365 return mtp_setup();
1366}
1367
1368static void mtp_function_cleanup(struct android_usb_function *f)
1369{
1370 mtp_cleanup();
1371}
1372
Stephen Boyd83ed8e22013-03-08 17:04:08 -08001373static int
1374mtp_function_bind_config(struct android_usb_function *f,
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001375 struct usb_configuration *c)
1376{
1377 return mtp_bind_config(c, false);
1378}
1379
Stephen Boyd83ed8e22013-03-08 17:04:08 -08001380static int
1381ptp_function_init(struct android_usb_function *f,
1382 struct usb_composite_dev *cdev)
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001383{
1384 /* nothing to do - initialization is handled by mtp_function_init */
1385 return 0;
1386}
1387
1388static void ptp_function_cleanup(struct android_usb_function *f)
1389{
1390 /* nothing to do - cleanup is handled by mtp_function_cleanup */
1391}
1392
Stephen Boyd83ed8e22013-03-08 17:04:08 -08001393static int
1394ptp_function_bind_config(struct android_usb_function *f,
1395 struct usb_configuration *c)
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001396{
1397 return mtp_bind_config(c, true);
1398}
1399
1400static int mtp_function_ctrlrequest(struct android_usb_function *f,
1401 struct usb_composite_dev *cdev,
1402 const struct usb_ctrlrequest *c)
1403{
1404 return mtp_ctrlrequest(cdev, c);
1405}
1406
1407static struct android_usb_function mtp_function = {
1408 .name = "mtp",
1409 .init = mtp_function_init,
1410 .cleanup = mtp_function_cleanup,
1411 .bind_config = mtp_function_bind_config,
1412 .ctrlrequest = mtp_function_ctrlrequest,
1413};
1414
1415/* PTP function is same as MTP with slightly different interface descriptor */
1416static struct android_usb_function ptp_function = {
1417 .name = "ptp",
1418 .init = ptp_function_init,
1419 .cleanup = ptp_function_cleanup,
1420 .bind_config = ptp_function_bind_config,
1421};
1422
1423
Benoit Goby1e8ce152011-12-12 13:01:23 -08001424struct rndis_function_config {
1425 u8 ethaddr[ETH_ALEN];
1426 u32 vendorID;
Ofir Cohenaef90b72012-07-31 12:37:04 +02001427 u8 max_pkt_per_xfer;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001428 char manufacturer[256];
1429 /* "Wireless" RNDIS; auto-detected by Windows */
1430 bool wceis;
1431};
1432
1433static int
1434rndis_function_init(struct android_usb_function *f,
1435 struct usb_composite_dev *cdev)
1436{
1437 f->config = kzalloc(sizeof(struct rndis_function_config), GFP_KERNEL);
1438 if (!f->config)
1439 return -ENOMEM;
1440 return 0;
1441}
1442
1443static void rndis_function_cleanup(struct android_usb_function *f)
1444{
1445 kfree(f->config);
1446 f->config = NULL;
1447}
1448
Ofir Cohenaef90b72012-07-31 12:37:04 +02001449static int rndis_qc_function_init(struct android_usb_function *f,
1450 struct usb_composite_dev *cdev)
1451{
1452 f->config = kzalloc(sizeof(struct rndis_function_config), GFP_KERNEL);
1453 if (!f->config)
1454 return -ENOMEM;
1455
1456 return rndis_qc_init();
1457}
1458
1459static void rndis_qc_function_cleanup(struct android_usb_function *f)
1460{
1461 rndis_qc_cleanup();
1462 kfree(f->config);
1463}
1464
Benoit Goby1e8ce152011-12-12 13:01:23 -08001465static int
1466rndis_function_bind_config(struct android_usb_function *f,
1467 struct usb_configuration *c)
1468{
1469 int ret;
1470 struct rndis_function_config *rndis = f->config;
1471
1472 if (!rndis) {
1473 pr_err("%s: rndis_pdata\n", __func__);
1474 return -1;
1475 }
1476
1477 pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
1478 rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
1479 rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
1480
Vijayavardhan Vennapusa5c91df52013-09-04 17:30:43 +05301481 if (rndis->ethaddr[0])
1482 ret = gether_setup_name(c->cdev->gadget, NULL, "rndis");
1483 else
1484 ret = gether_setup_name(c->cdev->gadget, rndis->ethaddr,
1485 "rndis");
Benoit Goby1e8ce152011-12-12 13:01:23 -08001486 if (ret) {
1487 pr_err("%s: gether_setup failed\n", __func__);
1488 return ret;
1489 }
1490
1491 if (rndis->wceis) {
1492 /* "Wireless" RNDIS; auto-detected by Windows */
1493 rndis_iad_descriptor.bFunctionClass =
1494 USB_CLASS_WIRELESS_CONTROLLER;
1495 rndis_iad_descriptor.bFunctionSubClass = 0x01;
1496 rndis_iad_descriptor.bFunctionProtocol = 0x03;
1497 rndis_control_intf.bInterfaceClass =
1498 USB_CLASS_WIRELESS_CONTROLLER;
1499 rndis_control_intf.bInterfaceSubClass = 0x01;
1500 rndis_control_intf.bInterfaceProtocol = 0x03;
1501 }
1502
1503 return rndis_bind_config_vendor(c, rndis->ethaddr, rndis->vendorID,
1504 rndis->manufacturer);
1505}
1506
Ofir Cohenaef90b72012-07-31 12:37:04 +02001507static int rndis_qc_function_bind_config(struct android_usb_function *f,
1508 struct usb_configuration *c)
1509{
1510 int ret;
1511 struct rndis_function_config *rndis = f->config;
1512
1513 if (!rndis) {
1514 pr_err("%s: rndis_pdata\n", __func__);
1515 return -EINVAL;
1516 }
1517
1518 pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
1519 rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
1520 rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
1521
1522 ret = gether_qc_setup_name(c->cdev->gadget, rndis->ethaddr, "rndis");
1523 if (ret) {
1524 pr_err("%s: gether_setup failed\n", __func__);
1525 return ret;
1526 }
1527
1528 if (rndis->wceis) {
1529 /* "Wireless" RNDIS; auto-detected by Windows */
1530 rndis_qc_iad_descriptor.bFunctionClass =
1531 USB_CLASS_WIRELESS_CONTROLLER;
1532 rndis_qc_iad_descriptor.bFunctionSubClass = 0x01;
1533 rndis_qc_iad_descriptor.bFunctionProtocol = 0x03;
1534 rndis_qc_control_intf.bInterfaceClass =
1535 USB_CLASS_WIRELESS_CONTROLLER;
1536 rndis_qc_control_intf.bInterfaceSubClass = 0x01;
1537 rndis_qc_control_intf.bInterfaceProtocol = 0x03;
1538 }
1539
1540 return rndis_qc_bind_config_vendor(c, rndis->ethaddr, rndis->vendorID,
1541 rndis->manufacturer,
1542 rndis->max_pkt_per_xfer);
1543}
1544
Benoit Goby1e8ce152011-12-12 13:01:23 -08001545static void rndis_function_unbind_config(struct android_usb_function *f,
1546 struct usb_configuration *c)
1547{
1548 gether_cleanup();
1549}
1550
Ofir Cohenaef90b72012-07-31 12:37:04 +02001551static void rndis_qc_function_unbind_config(struct android_usb_function *f,
1552 struct usb_configuration *c)
1553{
Amit Blayd6d690a2012-10-16 13:37:42 +02001554 gether_qc_cleanup_name("rndis0");
Ofir Cohenaef90b72012-07-31 12:37:04 +02001555}
1556
Benoit Goby1e8ce152011-12-12 13:01:23 -08001557static ssize_t rndis_manufacturer_show(struct device *dev,
1558 struct device_attribute *attr, char *buf)
1559{
1560 struct android_usb_function *f = dev_get_drvdata(dev);
1561 struct rndis_function_config *config = f->config;
Steve Mucklef132c6c2012-06-06 18:30:57 -07001562
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301563 return snprintf(buf, PAGE_SIZE, "%s\n", config->manufacturer);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001564}
1565
1566static ssize_t rndis_manufacturer_store(struct device *dev,
1567 struct device_attribute *attr, const char *buf, size_t size)
1568{
1569 struct android_usb_function *f = dev_get_drvdata(dev);
1570 struct rndis_function_config *config = f->config;
1571
1572 if (size >= sizeof(config->manufacturer))
1573 return -EINVAL;
Steve Mucklef132c6c2012-06-06 18:30:57 -07001574
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301575 if (sscanf(buf, "%255s", config->manufacturer) == 1)
Benoit Goby1e8ce152011-12-12 13:01:23 -08001576 return size;
1577 return -1;
1578}
1579
1580static DEVICE_ATTR(manufacturer, S_IRUGO | S_IWUSR, rndis_manufacturer_show,
1581 rndis_manufacturer_store);
1582
1583static ssize_t rndis_wceis_show(struct device *dev,
1584 struct device_attribute *attr, char *buf)
1585{
1586 struct android_usb_function *f = dev_get_drvdata(dev);
1587 struct rndis_function_config *config = f->config;
Steve Mucklef132c6c2012-06-06 18:30:57 -07001588
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301589 return snprintf(buf, PAGE_SIZE, "%d\n", config->wceis);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001590}
1591
1592static ssize_t rndis_wceis_store(struct device *dev,
1593 struct device_attribute *attr, const char *buf, size_t size)
1594{
1595 struct android_usb_function *f = dev_get_drvdata(dev);
1596 struct rndis_function_config *config = f->config;
1597 int value;
1598
1599 if (sscanf(buf, "%d", &value) == 1) {
1600 config->wceis = value;
1601 return size;
1602 }
1603 return -EINVAL;
1604}
1605
1606static DEVICE_ATTR(wceis, S_IRUGO | S_IWUSR, rndis_wceis_show,
1607 rndis_wceis_store);
1608
1609static ssize_t rndis_ethaddr_show(struct device *dev,
1610 struct device_attribute *attr, char *buf)
1611{
1612 struct android_usb_function *f = dev_get_drvdata(dev);
1613 struct rndis_function_config *rndis = f->config;
Steve Mucklef132c6c2012-06-06 18:30:57 -07001614
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301615 return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n",
Benoit Goby1e8ce152011-12-12 13:01:23 -08001616 rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
1617 rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
1618}
1619
1620static ssize_t rndis_ethaddr_store(struct device *dev,
1621 struct device_attribute *attr, const char *buf, size_t size)
1622{
1623 struct android_usb_function *f = dev_get_drvdata(dev);
1624 struct rndis_function_config *rndis = f->config;
1625
1626 if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
1627 (int *)&rndis->ethaddr[0], (int *)&rndis->ethaddr[1],
1628 (int *)&rndis->ethaddr[2], (int *)&rndis->ethaddr[3],
1629 (int *)&rndis->ethaddr[4], (int *)&rndis->ethaddr[5]) == 6)
1630 return size;
1631 return -EINVAL;
1632}
1633
1634static DEVICE_ATTR(ethaddr, S_IRUGO | S_IWUSR, rndis_ethaddr_show,
1635 rndis_ethaddr_store);
1636
1637static ssize_t rndis_vendorID_show(struct device *dev,
1638 struct device_attribute *attr, char *buf)
1639{
1640 struct android_usb_function *f = dev_get_drvdata(dev);
1641 struct rndis_function_config *config = f->config;
Steve Mucklef132c6c2012-06-06 18:30:57 -07001642
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301643 return snprintf(buf, PAGE_SIZE, "%04x\n", config->vendorID);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001644}
1645
1646static ssize_t rndis_vendorID_store(struct device *dev,
1647 struct device_attribute *attr, const char *buf, size_t size)
1648{
1649 struct android_usb_function *f = dev_get_drvdata(dev);
1650 struct rndis_function_config *config = f->config;
1651 int value;
1652
1653 if (sscanf(buf, "%04x", &value) == 1) {
1654 config->vendorID = value;
1655 return size;
1656 }
1657 return -EINVAL;
1658}
1659
1660static DEVICE_ATTR(vendorID, S_IRUGO | S_IWUSR, rndis_vendorID_show,
1661 rndis_vendorID_store);
1662
Ofir Cohenaef90b72012-07-31 12:37:04 +02001663static ssize_t rndis_max_pkt_per_xfer_show(struct device *dev,
1664 struct device_attribute *attr, char *buf)
1665{
1666 struct android_usb_function *f = dev_get_drvdata(dev);
1667 struct rndis_function_config *config = f->config;
1668 return snprintf(buf, PAGE_SIZE, "%d\n", config->max_pkt_per_xfer);
1669}
1670
1671static ssize_t rndis_max_pkt_per_xfer_store(struct device *dev,
1672 struct device_attribute *attr, const char *buf, size_t size)
1673{
1674 struct android_usb_function *f = dev_get_drvdata(dev);
1675 struct rndis_function_config *config = f->config;
1676 int value;
1677
1678 if (sscanf(buf, "%d", &value) == 1) {
1679 config->max_pkt_per_xfer = value;
1680 return size;
1681 }
1682 return -EINVAL;
1683}
1684
1685static DEVICE_ATTR(max_pkt_per_xfer, S_IRUGO | S_IWUSR,
1686 rndis_max_pkt_per_xfer_show,
1687 rndis_max_pkt_per_xfer_store);
1688
Benoit Goby1e8ce152011-12-12 13:01:23 -08001689static struct device_attribute *rndis_function_attributes[] = {
1690 &dev_attr_manufacturer,
1691 &dev_attr_wceis,
1692 &dev_attr_ethaddr,
1693 &dev_attr_vendorID,
Ofir Cohenaef90b72012-07-31 12:37:04 +02001694 &dev_attr_max_pkt_per_xfer,
Benoit Goby1e8ce152011-12-12 13:01:23 -08001695 NULL
1696};
1697
1698static struct android_usb_function rndis_function = {
1699 .name = "rndis",
1700 .init = rndis_function_init,
1701 .cleanup = rndis_function_cleanup,
1702 .bind_config = rndis_function_bind_config,
1703 .unbind_config = rndis_function_unbind_config,
1704 .attributes = rndis_function_attributes,
1705};
1706
Ofir Cohenaef90b72012-07-31 12:37:04 +02001707static struct android_usb_function rndis_qc_function = {
1708 .name = "rndis_qc",
1709 .init = rndis_qc_function_init,
1710 .cleanup = rndis_qc_function_cleanup,
1711 .bind_config = rndis_qc_function_bind_config,
1712 .unbind_config = rndis_qc_function_unbind_config,
1713 .attributes = rndis_function_attributes,
1714};
Benoit Goby1e8ce152011-12-12 13:01:23 -08001715
Anna Perelf9d01552012-11-20 15:56:32 +02001716static int ecm_function_bind_config(struct android_usb_function *f,
1717 struct usb_configuration *c)
1718{
1719 int ret;
1720 struct ecm_function_config *ecm = f->config;
1721
1722 if (!ecm) {
1723 pr_err("%s: ecm_pdata\n", __func__);
1724 return -EINVAL;
1725 }
1726
1727 pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
1728 ecm->ethaddr[0], ecm->ethaddr[1], ecm->ethaddr[2],
1729 ecm->ethaddr[3], ecm->ethaddr[4], ecm->ethaddr[5]);
1730
1731 ret = gether_setup_name(c->cdev->gadget, ecm->ethaddr, "ecm");
1732 if (ret) {
1733 pr_err("%s: gether_setup failed\n", __func__);
1734 return ret;
1735 }
1736
1737 ret = ecm_bind_config(c, ecm->ethaddr);
1738 if (ret) {
1739 pr_err("%s: ecm_bind_config failed\n", __func__);
1740 gether_cleanup();
1741 }
1742 return ret;
1743}
1744
1745static void ecm_function_unbind_config(struct android_usb_function *f,
1746 struct usb_configuration *c)
1747{
1748 gether_cleanup();
1749}
1750
1751static struct android_usb_function ecm_function = {
1752 .name = "ecm",
1753 .init = ecm_function_init,
1754 .cleanup = ecm_function_cleanup,
1755 .bind_config = ecm_function_bind_config,
1756 .unbind_config = ecm_function_unbind_config,
1757 .attributes = ecm_function_attributes,
1758};
1759
Benoit Goby1e8ce152011-12-12 13:01:23 -08001760struct mass_storage_function_config {
1761 struct fsg_config fsg;
1762 struct fsg_common *common;
1763};
1764
1765static int mass_storage_function_init(struct android_usb_function *f,
1766 struct usb_composite_dev *cdev)
1767{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001768 struct android_dev *dev = cdev_to_android_dev(cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001769 struct mass_storage_function_config *config;
1770 struct fsg_common *common;
1771 int err;
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301772 int i;
1773 const char *name[2];
Benoit Goby1e8ce152011-12-12 13:01:23 -08001774
1775 config = kzalloc(sizeof(struct mass_storage_function_config),
1776 GFP_KERNEL);
1777 if (!config)
1778 return -ENOMEM;
1779
1780 config->fsg.nluns = 1;
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301781 name[0] = "lun";
Pavankumar Kondeti2043e302012-07-19 08:54:04 +05301782 if (dev->pdata && dev->pdata->cdrom) {
wujin269684c2013-09-02 17:51:38 +08001783 config->fsg.luns[config->fsg.nluns].cdrom = 1;
1784 config->fsg.luns[config->fsg.nluns].ro = 1;
1785 config->fsg.luns[config->fsg.nluns].removable = 0;
1786 name[config->fsg.nluns] = "lun0";
1787 config->fsg.nluns++;
1788 }
1789 if (dev->pdata && dev->pdata->internal_ums) {
1790 config->fsg.luns[config->fsg.nluns].cdrom = 0;
1791 config->fsg.luns[config->fsg.nluns].ro = 0;
1792 config->fsg.luns[config->fsg.nluns].removable = 1;
1793 name[config->fsg.nluns] = "lun1";
1794 config->fsg.nluns++;
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301795 }
1796
Benoit Goby1e8ce152011-12-12 13:01:23 -08001797 config->fsg.luns[0].removable = 1;
1798
1799 common = fsg_common_init(NULL, cdev, &config->fsg);
1800 if (IS_ERR(common)) {
1801 kfree(config);
1802 return PTR_ERR(common);
1803 }
1804
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301805 for (i = 0; i < config->fsg.nluns; i++) {
1806 err = sysfs_create_link(&f->dev->kobj,
1807 &common->luns[i].dev.kobj,
1808 name[i]);
1809 if (err)
1810 goto error;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001811 }
1812
1813 config->common = common;
1814 f->config = config;
1815 return 0;
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301816error:
1817 for (; i > 0 ; i--)
1818 sysfs_remove_link(&f->dev->kobj, name[i-1]);
1819
1820 fsg_common_release(&common->ref);
1821 kfree(config);
1822 return err;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001823}
1824
1825static void mass_storage_function_cleanup(struct android_usb_function *f)
1826{
1827 kfree(f->config);
1828 f->config = NULL;
1829}
1830
1831static int mass_storage_function_bind_config(struct android_usb_function *f,
1832 struct usb_configuration *c)
1833{
1834 struct mass_storage_function_config *config = f->config;
1835 return fsg_bind_config(c->cdev, c, config->common);
1836}
1837
1838static ssize_t mass_storage_inquiry_show(struct device *dev,
1839 struct device_attribute *attr, char *buf)
1840{
1841 struct android_usb_function *f = dev_get_drvdata(dev);
1842 struct mass_storage_function_config *config = f->config;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301843 return snprintf(buf, PAGE_SIZE, "%s\n", config->common->inquiry_string);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001844}
1845
1846static ssize_t mass_storage_inquiry_store(struct device *dev,
1847 struct device_attribute *attr, const char *buf, size_t size)
1848{
1849 struct android_usb_function *f = dev_get_drvdata(dev);
1850 struct mass_storage_function_config *config = f->config;
1851 if (size >= sizeof(config->common->inquiry_string))
1852 return -EINVAL;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301853 if (sscanf(buf, "%28s", config->common->inquiry_string) != 1)
Benoit Goby1e8ce152011-12-12 13:01:23 -08001854 return -EINVAL;
1855 return size;
1856}
1857
1858static DEVICE_ATTR(inquiry_string, S_IRUGO | S_IWUSR,
1859 mass_storage_inquiry_show,
1860 mass_storage_inquiry_store);
1861
1862static struct device_attribute *mass_storage_function_attributes[] = {
1863 &dev_attr_inquiry_string,
1864 NULL
1865};
1866
1867static struct android_usb_function mass_storage_function = {
1868 .name = "mass_storage",
1869 .init = mass_storage_function_init,
1870 .cleanup = mass_storage_function_cleanup,
1871 .bind_config = mass_storage_function_bind_config,
1872 .attributes = mass_storage_function_attributes,
1873};
1874
1875
Benoit Gobycf3fc062011-12-19 14:39:37 -08001876static int accessory_function_init(struct android_usb_function *f,
1877 struct usb_composite_dev *cdev)
1878{
1879 return acc_setup();
1880}
1881
1882static void accessory_function_cleanup(struct android_usb_function *f)
1883{
1884 acc_cleanup();
1885}
1886
1887static int accessory_function_bind_config(struct android_usb_function *f,
1888 struct usb_configuration *c)
1889{
1890 return acc_bind_config(c);
1891}
1892
1893static int accessory_function_ctrlrequest(struct android_usb_function *f,
1894 struct usb_composite_dev *cdev,
1895 const struct usb_ctrlrequest *c)
1896{
1897 return acc_ctrlrequest(cdev, c);
1898}
1899
1900static struct android_usb_function accessory_function = {
1901 .name = "accessory",
1902 .init = accessory_function_init,
1903 .cleanup = accessory_function_cleanup,
1904 .bind_config = accessory_function_bind_config,
1905 .ctrlrequest = accessory_function_ctrlrequest,
1906};
1907
Anna Perel3ee23dd2013-02-26 16:06:40 +02001908#ifdef CONFIG_SND_PCM
Mike Lockwood11874822012-08-27 16:43:53 +05301909static int audio_source_function_init(struct android_usb_function *f,
1910 struct usb_composite_dev *cdev)
1911{
1912 struct audio_source_config *config;
1913
1914 config = kzalloc(sizeof(struct audio_source_config), GFP_KERNEL);
1915 if (!config)
1916 return -ENOMEM;
1917 config->card = -1;
1918 config->device = -1;
1919 f->config = config;
1920 return 0;
1921}
1922
1923static void audio_source_function_cleanup(struct android_usb_function *f)
1924{
1925 kfree(f->config);
1926}
1927
1928static int audio_source_function_bind_config(struct android_usb_function *f,
1929 struct usb_configuration *c)
1930{
1931 struct audio_source_config *config = f->config;
1932
1933 return audio_source_bind_config(c, config);
1934}
1935
1936static void audio_source_function_unbind_config(struct android_usb_function *f,
1937 struct usb_configuration *c)
1938{
1939 struct audio_source_config *config = f->config;
1940
1941 config->card = -1;
1942 config->device = -1;
1943}
1944
1945static ssize_t audio_source_pcm_show(struct device *dev,
1946 struct device_attribute *attr, char *buf)
1947{
1948 struct android_usb_function *f = dev_get_drvdata(dev);
1949 struct audio_source_config *config = f->config;
1950
1951 /* print PCM card and device numbers */
1952 return sprintf(buf, "%d %d\n", config->card, config->device);
1953}
1954
1955static DEVICE_ATTR(pcm, S_IRUGO | S_IWUSR, audio_source_pcm_show, NULL);
1956
1957static struct device_attribute *audio_source_function_attributes[] = {
1958 &dev_attr_pcm,
1959 NULL
1960};
1961
1962static struct android_usb_function audio_source_function = {
1963 .name = "audio_source",
1964 .init = audio_source_function_init,
1965 .cleanup = audio_source_function_cleanup,
1966 .bind_config = audio_source_function_bind_config,
1967 .unbind_config = audio_source_function_unbind_config,
1968 .attributes = audio_source_function_attributes,
1969};
Anna Perel3ee23dd2013-02-26 16:06:40 +02001970#endif
Mike Lockwood11874822012-08-27 16:43:53 +05301971
Pavankumar Kondeti8f6ca4f2012-06-26 09:44:36 +05301972static int android_uasp_connect_cb(bool connect)
1973{
1974 /*
1975 * TODO
1976 * We may have to disable gadget till UASP configfs nodes
1977 * are configured which includes mapping LUN with the
1978 * backing file. It is a fundamental difference between
1979 * f_mass_storage and f_tcp. That means UASP can not be
1980 * in default composition.
1981 *
1982 * For now, assume that UASP configfs nodes are configured
1983 * before enabling android gadget. Or cable should be
1984 * reconnected after mapping the LUN.
1985 *
1986 * Also consider making UASP to respond to Host requests when
1987 * Lun is not mapped.
1988 */
1989 pr_debug("UASP %s\n", connect ? "connect" : "disconnect");
1990
1991 return 0;
1992}
1993
1994static int uasp_function_init(struct android_usb_function *f,
1995 struct usb_composite_dev *cdev)
1996{
1997 return f_tcm_init(&android_uasp_connect_cb);
1998}
1999
2000static void uasp_function_cleanup(struct android_usb_function *f)
2001{
2002 f_tcm_exit();
2003}
2004
2005static int uasp_function_bind_config(struct android_usb_function *f,
2006 struct usb_configuration *c)
2007{
2008 return tcm_bind_config(c);
2009}
2010
2011static struct android_usb_function uasp_function = {
2012 .name = "uasp",
2013 .init = uasp_function_init,
2014 .cleanup = uasp_function_cleanup,
2015 .bind_config = uasp_function_bind_config,
2016};
Benoit Gobycf3fc062011-12-19 14:39:37 -08002017
Benoit Goby1e8ce152011-12-12 13:01:23 -08002018static struct android_usb_function *supported_functions[] = {
Anna Perela8c991d2012-04-09 16:44:46 +03002019 &mbim_function,
Ofir Cohen7b155422012-07-31 13:02:49 +03002020 &ecm_qc_function,
Jack Pham2ec5fdc2012-09-26 10:13:48 -07002021#ifdef CONFIG_SND_PCM
Anna Perel432367a2012-09-20 10:55:32 +03002022 &audio_function,
Jack Pham2ec5fdc2012-09-26 10:13:48 -07002023#endif
Manu Gautam1c8ffd72011-09-02 16:00:49 +05302024 &rmnet_smd_function,
Manu Gautam8e0719b2011-09-26 14:47:55 +05302025 &rmnet_sdio_function,
2026 &rmnet_smd_sdio_function,
Manu Gautam2b0234a2011-09-07 16:47:52 +05302027 &rmnet_function,
Bar Weinered1059e2013-04-16 11:23:55 +03002028 &gps_function,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002029 &diag_function,
Shimrit Malichia00d7322012-08-05 13:56:28 +03002030 &qdss_function,
Manu Gautama4d993f2011-08-30 18:25:55 +05302031 &serial_function,
Benoit Goby2b6862d2011-12-19 14:38:41 -08002032 &adb_function,
Chiranjeevi Velempatie130fd02011-11-29 05:06:13 +05302033 &ccid_function,
Benoit Goby1e8ce152011-12-12 13:01:23 -08002034 &acm_function,
Benoit Gobyf0fbc482011-12-19 14:37:50 -08002035 &mtp_function,
2036 &ptp_function,
Benoit Goby1e8ce152011-12-12 13:01:23 -08002037 &rndis_function,
Ofir Cohenaef90b72012-07-31 12:37:04 +02002038 &rndis_qc_function,
Anna Perelf9d01552012-11-20 15:56:32 +02002039 &ecm_function,
Vamsi Krishna932c9de2013-05-22 12:18:05 -07002040 &ncm_function,
Benoit Goby1e8ce152011-12-12 13:01:23 -08002041 &mass_storage_function,
Benoit Gobycf3fc062011-12-19 14:39:37 -08002042 &accessory_function,
Anna Perel3ee23dd2013-02-26 16:06:40 +02002043#ifdef CONFIG_SND_PCM
Mike Lockwood11874822012-08-27 16:43:53 +05302044 &audio_source_function,
Anna Perel3ee23dd2013-02-26 16:06:40 +02002045#endif
Pavankumar Kondeti8f6ca4f2012-06-26 09:44:36 +05302046 &uasp_function,
Benoit Goby1e8ce152011-12-12 13:01:23 -08002047 NULL
2048};
2049
Lena Salmand092f2d2012-03-12 17:27:24 +02002050static void android_cleanup_functions(struct android_usb_function **functions)
2051{
2052 struct android_usb_function *f;
2053 struct device_attribute **attrs;
2054 struct device_attribute *attr;
2055
2056 while (*functions) {
2057 f = *functions++;
2058
2059 if (f->dev) {
2060 device_destroy(android_class, f->dev->devt);
2061 kfree(f->dev_name);
2062 } else
2063 continue;
2064
2065 if (f->cleanup)
2066 f->cleanup(f);
2067
2068 attrs = f->attributes;
2069 if (attrs) {
2070 while ((attr = *attrs++))
2071 device_remove_file(f->dev, attr);
2072 }
2073 }
2074}
Benoit Goby1e8ce152011-12-12 13:01:23 -08002075
2076static int android_init_functions(struct android_usb_function **functions,
2077 struct usb_composite_dev *cdev)
2078{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002079 struct android_dev *dev = cdev_to_android_dev(cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002080 struct android_usb_function *f;
2081 struct device_attribute **attrs;
2082 struct device_attribute *attr;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302083 int err = 0;
Lena Salmand092f2d2012-03-12 17:27:24 +02002084 int index = 1; /* index 0 is for android0 device */
Benoit Goby1e8ce152011-12-12 13:01:23 -08002085
2086 for (; (f = *functions++); index++) {
2087 f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002088 f->android_dev = NULL;
Lena Salmand092f2d2012-03-12 17:27:24 +02002089 if (!f->dev_name) {
2090 err = -ENOMEM;
2091 goto err_out;
2092 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002093 f->dev = device_create(android_class, dev->dev,
2094 MKDEV(0, index), f, f->dev_name);
2095 if (IS_ERR(f->dev)) {
2096 pr_err("%s: Failed to create dev %s", __func__,
2097 f->dev_name);
2098 err = PTR_ERR(f->dev);
Lena Salmand092f2d2012-03-12 17:27:24 +02002099 f->dev = NULL;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002100 goto err_create;
2101 }
2102
2103 if (f->init) {
2104 err = f->init(f, cdev);
2105 if (err) {
2106 pr_err("%s: Failed to init %s", __func__,
2107 f->name);
Lena Salmand092f2d2012-03-12 17:27:24 +02002108 goto err_init;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002109 }
2110 }
2111
2112 attrs = f->attributes;
2113 if (attrs) {
2114 while ((attr = *attrs++) && !err)
2115 err = device_create_file(f->dev, attr);
2116 }
2117 if (err) {
2118 pr_err("%s: Failed to create function %s attributes",
2119 __func__, f->name);
Lena Salmand092f2d2012-03-12 17:27:24 +02002120 goto err_attrs;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002121 }
2122 }
2123 return 0;
2124
Lena Salmand092f2d2012-03-12 17:27:24 +02002125err_attrs:
2126 for (attr = *(attrs -= 2); attrs != f->attributes; attr = *(attrs--))
2127 device_remove_file(f->dev, attr);
2128 if (f->cleanup)
2129 f->cleanup(f);
2130err_init:
Benoit Goby1e8ce152011-12-12 13:01:23 -08002131 device_destroy(android_class, f->dev->devt);
2132err_create:
Lena Salmand092f2d2012-03-12 17:27:24 +02002133 f->dev = NULL;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002134 kfree(f->dev_name);
Lena Salmand092f2d2012-03-12 17:27:24 +02002135err_out:
2136 android_cleanup_functions(dev->functions);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002137 return err;
2138}
2139
Benoit Goby1e8ce152011-12-12 13:01:23 -08002140static int
2141android_bind_enabled_functions(struct android_dev *dev,
2142 struct usb_configuration *c)
2143{
Ido Shayevitz68557e32012-11-06 12:40:37 +02002144 struct android_usb_function_holder *f_holder;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002145 struct android_configuration *conf =
2146 container_of(c, struct android_configuration, usb_config);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002147 int ret;
2148
Ido Shayevitz68557e32012-11-06 12:40:37 +02002149 list_for_each_entry(f_holder, &conf->enabled_functions, enabled_list) {
2150 ret = f_holder->f->bind_config(f_holder->f, c);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002151 if (ret) {
Vijayavardhan Vennapusa7a4f2452013-07-19 11:04:39 +05302152 pr_err("%s: %s failed\n", __func__, f_holder->f->name);
2153 while (!list_empty(&c->functions)) {
2154 struct usb_function *f;
2155
2156 f = list_first_entry(&c->functions,
2157 struct usb_function, list);
2158 list_del(&f->list);
2159 if (f->unbind)
2160 f->unbind(c, f);
2161 }
2162 if (c->unbind)
2163 c->unbind(c);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002164 return ret;
2165 }
2166 }
2167 return 0;
2168}
2169
2170static void
2171android_unbind_enabled_functions(struct android_dev *dev,
2172 struct usb_configuration *c)
2173{
Ido Shayevitz68557e32012-11-06 12:40:37 +02002174 struct android_usb_function_holder *f_holder;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002175 struct android_configuration *conf =
2176 container_of(c, struct android_configuration, usb_config);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002177
Ido Shayevitz68557e32012-11-06 12:40:37 +02002178 list_for_each_entry(f_holder, &conf->enabled_functions, enabled_list) {
2179 if (f_holder->f->unbind_config)
2180 f_holder->f->unbind_config(f_holder->f, c);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002181 }
2182}
2183
Mayank Rana142fe412013-11-11 14:16:30 +05302184static inline void check_streaming_func(struct usb_gadget *gadget,
2185 struct android_usb_platform_data *pdata,
2186 char *name)
2187{
2188 int i;
2189
2190 for (i = 0; i < pdata->streaming_func_count; i++) {
2191 if (!strcmp(name,
2192 pdata->streaming_func[i])) {
2193 pr_debug("set streaming_enabled to true\n");
2194 gadget->streaming_enabled = true;
2195 break;
2196 }
2197 }
2198}
2199
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002200static int android_enable_function(struct android_dev *dev,
2201 struct android_configuration *conf,
2202 char *name)
Benoit Goby1e8ce152011-12-12 13:01:23 -08002203{
2204 struct android_usb_function **functions = dev->functions;
2205 struct android_usb_function *f;
Ido Shayevitz68557e32012-11-06 12:40:37 +02002206 struct android_usb_function_holder *f_holder;
Mayank Rana142fe412013-11-11 14:16:30 +05302207 struct android_usb_platform_data *pdata = dev->pdata;
2208 struct usb_gadget *gadget = dev->cdev->gadget;
2209
Benoit Goby1e8ce152011-12-12 13:01:23 -08002210 while ((f = *functions++)) {
2211 if (!strcmp(name, f->name)) {
Ido Shayevitz68557e32012-11-06 12:40:37 +02002212 if (f->android_dev && f->android_dev != dev)
2213 pr_err("%s is enabled in other device\n",
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002214 f->name);
2215 else {
Ido Shayevitz68557e32012-11-06 12:40:37 +02002216 f_holder = kzalloc(sizeof(*f_holder),
2217 GFP_KERNEL);
2218 if (!f_holder) {
2219 pr_err("Failed to alloc f_holder\n");
2220 return -ENOMEM;
2221 }
2222
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002223 f->android_dev = dev;
Ido Shayevitz68557e32012-11-06 12:40:37 +02002224 f_holder->f = f;
2225 list_add_tail(&f_holder->enabled_list,
2226 &conf->enabled_functions);
Mayank Rana142fe412013-11-11 14:16:30 +05302227 pr_debug("func:%s is enabled.\n", f->name);
2228 /*
2229 * compare enable function with streaming func
2230 * list and based on the same request streaming.
2231 */
2232 check_streaming_func(gadget, pdata, f->name);
2233
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002234 return 0;
2235 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002236 }
2237 }
2238 return -EINVAL;
2239}
2240
2241/*-------------------------------------------------------------------------*/
2242/* /sys/class/android_usb/android%d/ interface */
2243
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05302244static ssize_t remote_wakeup_show(struct device *pdev,
2245 struct device_attribute *attr, char *buf)
2246{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002247 struct android_dev *dev = dev_get_drvdata(pdev);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002248 struct android_configuration *conf;
2249
2250 /*
2251 * Show the wakeup attribute of the first configuration,
2252 * since all configurations have the same wakeup attribute
2253 */
2254 if (dev->configs_num == 0)
2255 return 0;
2256 conf = list_entry(dev->configs.next,
2257 struct android_configuration,
2258 list_item);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002259
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05302260 return snprintf(buf, PAGE_SIZE, "%d\n",
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002261 !!(conf->usb_config.bmAttributes &
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05302262 USB_CONFIG_ATT_WAKEUP));
2263}
2264
2265static ssize_t remote_wakeup_store(struct device *pdev,
2266 struct device_attribute *attr, const char *buff, size_t size)
2267{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002268 struct android_dev *dev = dev_get_drvdata(pdev);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002269 struct android_configuration *conf;
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05302270 int enable = 0;
2271
2272 sscanf(buff, "%d", &enable);
2273
2274 pr_debug("android_usb: %s remote wakeup\n",
2275 enable ? "enabling" : "disabling");
2276
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002277 list_for_each_entry(conf, &dev->configs, list_item)
2278 if (enable)
2279 conf->usb_config.bmAttributes |=
2280 USB_CONFIG_ATT_WAKEUP;
2281 else
2282 conf->usb_config.bmAttributes &=
2283 ~USB_CONFIG_ATT_WAKEUP;
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05302284
2285 return size;
2286}
2287
Benoit Goby1e8ce152011-12-12 13:01:23 -08002288static ssize_t
2289functions_show(struct device *pdev, struct device_attribute *attr, char *buf)
2290{
2291 struct android_dev *dev = dev_get_drvdata(pdev);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002292 struct android_configuration *conf;
Ido Shayevitz68557e32012-11-06 12:40:37 +02002293 struct android_usb_function_holder *f_holder;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002294 char *buff = buf;
2295
2296 mutex_lock(&dev->mutex);
2297
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002298 list_for_each_entry(conf, &dev->configs, list_item) {
2299 if (buff != buf)
2300 *(buff-1) = ':';
Ido Shayevitz68557e32012-11-06 12:40:37 +02002301 list_for_each_entry(f_holder, &conf->enabled_functions,
2302 enabled_list)
2303 buff += snprintf(buff, PAGE_SIZE, "%s,",
2304 f_holder->f->name);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002305 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002306
2307 mutex_unlock(&dev->mutex);
2308
2309 if (buff != buf)
2310 *(buff-1) = '\n';
2311 return buff - buf;
2312}
2313
2314static ssize_t
2315functions_store(struct device *pdev, struct device_attribute *attr,
2316 const char *buff, size_t size)
2317{
2318 struct android_dev *dev = dev_get_drvdata(pdev);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002319 struct list_head *curr_conf = &dev->configs;
2320 struct android_configuration *conf;
2321 char *conf_str;
Ido Shayevitz68557e32012-11-06 12:40:37 +02002322 struct android_usb_function_holder *f_holder;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002323 char *name;
2324 char buf[256], *b;
2325 int err;
2326
2327 mutex_lock(&dev->mutex);
2328
2329 if (dev->enabled) {
2330 mutex_unlock(&dev->mutex);
2331 return -EBUSY;
2332 }
2333
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002334 /* Clear previous enabled list */
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002335 list_for_each_entry(conf, &dev->configs, list_item) {
Ido Shayevitz68557e32012-11-06 12:40:37 +02002336 while (conf->enabled_functions.next !=
2337 &conf->enabled_functions) {
2338 f_holder = list_entry(conf->enabled_functions.next,
2339 typeof(*f_holder),
2340 enabled_list);
2341 f_holder->f->android_dev = NULL;
2342 list_del(&f_holder->enabled_list);
2343 kfree(f_holder);
2344 }
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002345 INIT_LIST_HEAD(&conf->enabled_functions);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002346 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002347
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302348 strlcpy(buf, buff, sizeof(buf));
Benoit Goby1e8ce152011-12-12 13:01:23 -08002349 b = strim(buf);
2350
2351 while (b) {
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002352 conf_str = strsep(&b, ":");
2353 if (conf_str) {
2354 /* If the next not equal to the head, take it */
2355 if (curr_conf->next != &dev->configs)
2356 conf = list_entry(curr_conf->next,
2357 struct android_configuration,
2358 list_item);
2359 else
2360 conf = alloc_android_config(dev);
2361
2362 curr_conf = curr_conf->next;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002363 }
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002364
2365 while (conf_str) {
2366 name = strsep(&conf_str, ",");
2367 if (name) {
2368 err = android_enable_function(dev, conf, name);
2369 if (err)
2370 pr_err("android_usb: Cannot enable %s",
2371 name);
2372 }
2373 }
2374 }
2375
2376 /* Free uneeded configurations if exists */
2377 while (curr_conf->next != &dev->configs) {
2378 conf = list_entry(curr_conf->next,
2379 struct android_configuration, list_item);
2380 free_android_config(dev, conf);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002381 }
2382
2383 mutex_unlock(&dev->mutex);
2384
2385 return size;
2386}
2387
2388static ssize_t enable_show(struct device *pdev, struct device_attribute *attr,
2389 char *buf)
2390{
2391 struct android_dev *dev = dev_get_drvdata(pdev);
Steve Mucklef132c6c2012-06-06 18:30:57 -07002392
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302393 return snprintf(buf, PAGE_SIZE, "%d\n", dev->enabled);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002394}
2395
2396static ssize_t enable_store(struct device *pdev, struct device_attribute *attr,
2397 const char *buff, size_t size)
2398{
2399 struct android_dev *dev = dev_get_drvdata(pdev);
2400 struct usb_composite_dev *cdev = dev->cdev;
Ido Shayevitz68557e32012-11-06 12:40:37 +02002401 struct android_usb_function_holder *f_holder;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002402 struct android_configuration *conf;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002403 int enabled = 0;
Rajkumar Raghupathya79363b2013-01-02 19:08:49 +05302404 bool audio_enabled = false;
Pavankumar Kondeti19d8bc62013-02-28 10:19:40 +05302405 static DEFINE_RATELIMIT_STATE(rl, 10*HZ, 1);
Vijayavardhan Vennapusa7a4f2452013-07-19 11:04:39 +05302406 int err = 0;
Stephen Boyd42517402013-01-14 16:41:42 -08002407
Benoit Gobycf3fc062011-12-19 14:39:37 -08002408 if (!cdev)
2409 return -ENODEV;
2410
Benoit Goby1e8ce152011-12-12 13:01:23 -08002411 mutex_lock(&dev->mutex);
2412
2413 sscanf(buff, "%d", &enabled);
2414 if (enabled && !dev->enabled) {
Benoit Goby1e8ce152011-12-12 13:01:23 -08002415 /*
2416 * Update values in composite driver's copy of
2417 * device descriptor.
2418 */
2419 cdev->desc.idVendor = device_desc.idVendor;
2420 cdev->desc.idProduct = device_desc.idProduct;
2421 cdev->desc.bcdDevice = device_desc.bcdDevice;
2422 cdev->desc.bDeviceClass = device_desc.bDeviceClass;
2423 cdev->desc.bDeviceSubClass = device_desc.bDeviceSubClass;
2424 cdev->desc.bDeviceProtocol = device_desc.bDeviceProtocol;
Rajkumar Raghupathya79363b2013-01-02 19:08:49 +05302425
2426 /* Audio dock accessory is unable to enumerate device if
2427 * pull-up is enabled immediately. The enumeration is
2428 * reliable with 100 msec delay.
2429 */
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002430 list_for_each_entry(conf, &dev->configs, list_item)
Ido Shayevitz68557e32012-11-06 12:40:37 +02002431 list_for_each_entry(f_holder, &conf->enabled_functions,
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002432 enabled_list) {
Ido Shayevitz68557e32012-11-06 12:40:37 +02002433 if (f_holder->f->enable)
2434 f_holder->f->enable(f_holder->f);
Rajkumar Raghupathya79363b2013-01-02 19:08:49 +05302435 if (!strncmp(f_holder->f->name,
2436 "audio_source", 12))
2437 audio_enabled = true;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002438 }
Rajkumar Raghupathya79363b2013-01-02 19:08:49 +05302439 if (audio_enabled)
2440 msleep(100);
Vijayavardhan Vennapusa7a4f2452013-07-19 11:04:39 +05302441 err = android_enable(dev);
2442 if (err < 0) {
2443 pr_err("%s: android_enable failed\n", __func__);
2444 dev->connected = 0;
2445 dev->enabled = false;
2446 mutex_unlock(&dev->mutex);
2447 return size;
2448 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002449 dev->enabled = true;
2450 } else if (!enabled && dev->enabled) {
Benoit Goby80ba14d2012-03-19 18:56:52 -07002451 android_disable(dev);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002452 list_for_each_entry(conf, &dev->configs, list_item)
Ido Shayevitz68557e32012-11-06 12:40:37 +02002453 list_for_each_entry(f_holder, &conf->enabled_functions,
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002454 enabled_list) {
Ido Shayevitz68557e32012-11-06 12:40:37 +02002455 if (f_holder->f->disable)
2456 f_holder->f->disable(f_holder->f);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002457 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002458 dev->enabled = false;
Pavankumar Kondeti19d8bc62013-02-28 10:19:40 +05302459 } else if (__ratelimit(&rl)) {
Benoit Goby1e8ce152011-12-12 13:01:23 -08002460 pr_err("android_usb: already %s\n",
2461 dev->enabled ? "enabled" : "disabled");
2462 }
2463
2464 mutex_unlock(&dev->mutex);
Steve Mucklef132c6c2012-06-06 18:30:57 -07002465
Benoit Gobyaab96812011-04-19 20:37:33 -07002466 return size;
2467}
2468
Ofir Cohen94213a72012-05-03 14:26:32 +03002469static ssize_t pm_qos_show(struct device *pdev,
2470 struct device_attribute *attr, char *buf)
2471{
2472 struct android_dev *dev = dev_get_drvdata(pdev);
2473
2474 return snprintf(buf, PAGE_SIZE, "%s\n", dev->pm_qos);
2475}
2476
2477static ssize_t pm_qos_store(struct device *pdev,
2478 struct device_attribute *attr,
2479 const char *buff, size_t size)
2480{
2481 struct android_dev *dev = dev_get_drvdata(pdev);
2482
2483 strlcpy(dev->pm_qos, buff, sizeof(dev->pm_qos));
2484
Benoit Goby1e8ce152011-12-12 13:01:23 -08002485 return size;
2486}
2487
2488static ssize_t state_show(struct device *pdev, struct device_attribute *attr,
2489 char *buf)
2490{
2491 struct android_dev *dev = dev_get_drvdata(pdev);
2492 struct usb_composite_dev *cdev = dev->cdev;
2493 char *state = "DISCONNECTED";
2494 unsigned long flags;
2495
2496 if (!cdev)
2497 goto out;
2498
2499 spin_lock_irqsave(&cdev->lock, flags);
2500 if (cdev->config)
2501 state = "CONFIGURED";
2502 else if (dev->connected)
2503 state = "CONNECTED";
2504 spin_unlock_irqrestore(&cdev->lock, flags);
2505out:
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302506 return snprintf(buf, PAGE_SIZE, "%s\n", state);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002507}
2508
2509#define DESCRIPTOR_ATTR(field, format_string) \
2510static ssize_t \
2511field ## _show(struct device *dev, struct device_attribute *attr, \
2512 char *buf) \
2513{ \
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302514 return snprintf(buf, PAGE_SIZE, \
2515 format_string, device_desc.field); \
Benoit Goby1e8ce152011-12-12 13:01:23 -08002516} \
2517static ssize_t \
2518field ## _store(struct device *dev, struct device_attribute *attr, \
2519 const char *buf, size_t size) \
2520{ \
2521 int value; \
2522 if (sscanf(buf, format_string, &value) == 1) { \
2523 device_desc.field = value; \
2524 return size; \
2525 } \
2526 return -1; \
2527} \
2528static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store);
2529
2530#define DESCRIPTOR_STRING_ATTR(field, buffer) \
2531static ssize_t \
2532field ## _show(struct device *dev, struct device_attribute *attr, \
2533 char *buf) \
2534{ \
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302535 return snprintf(buf, PAGE_SIZE, "%s", buffer); \
Benoit Goby1e8ce152011-12-12 13:01:23 -08002536} \
2537static ssize_t \
2538field ## _store(struct device *dev, struct device_attribute *attr, \
2539 const char *buf, size_t size) \
2540{ \
2541 if (size >= sizeof(buffer)) \
2542 return -EINVAL; \
Pavankumar Kondetie02a51a2012-06-20 08:52:37 +05302543 strlcpy(buffer, buf, sizeof(buffer)); \
2544 strim(buffer); \
Pavankumar Kondeti4c22c102012-06-15 10:59:05 +05302545 return size; \
Benoit Goby1e8ce152011-12-12 13:01:23 -08002546} \
2547static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store);
2548
2549
2550DESCRIPTOR_ATTR(idVendor, "%04x\n")
2551DESCRIPTOR_ATTR(idProduct, "%04x\n")
2552DESCRIPTOR_ATTR(bcdDevice, "%04x\n")
2553DESCRIPTOR_ATTR(bDeviceClass, "%d\n")
2554DESCRIPTOR_ATTR(bDeviceSubClass, "%d\n")
2555DESCRIPTOR_ATTR(bDeviceProtocol, "%d\n")
2556DESCRIPTOR_STRING_ATTR(iManufacturer, manufacturer_string)
2557DESCRIPTOR_STRING_ATTR(iProduct, product_string)
2558DESCRIPTOR_STRING_ATTR(iSerial, serial_string)
2559
2560static DEVICE_ATTR(functions, S_IRUGO | S_IWUSR, functions_show,
2561 functions_store);
2562static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store);
Ofir Cohen94213a72012-05-03 14:26:32 +03002563static DEVICE_ATTR(pm_qos, S_IRUGO | S_IWUSR,
2564 pm_qos_show, pm_qos_store);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002565static DEVICE_ATTR(state, S_IRUGO, state_show, NULL);
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05302566static DEVICE_ATTR(remote_wakeup, S_IRUGO | S_IWUSR,
2567 remote_wakeup_show, remote_wakeup_store);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002568
2569static struct device_attribute *android_usb_attributes[] = {
2570 &dev_attr_idVendor,
2571 &dev_attr_idProduct,
2572 &dev_attr_bcdDevice,
2573 &dev_attr_bDeviceClass,
2574 &dev_attr_bDeviceSubClass,
2575 &dev_attr_bDeviceProtocol,
2576 &dev_attr_iManufacturer,
2577 &dev_attr_iProduct,
2578 &dev_attr_iSerial,
2579 &dev_attr_functions,
2580 &dev_attr_enable,
Ofir Cohen94213a72012-05-03 14:26:32 +03002581 &dev_attr_pm_qos,
Benoit Goby1e8ce152011-12-12 13:01:23 -08002582 &dev_attr_state,
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05302583 &dev_attr_remote_wakeup,
Benoit Goby1e8ce152011-12-12 13:01:23 -08002584 NULL
2585};
2586
2587/*-------------------------------------------------------------------------*/
2588/* Composite driver */
2589
2590static int android_bind_config(struct usb_configuration *c)
2591{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002592 struct android_dev *dev = cdev_to_android_dev(c->cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002593 int ret = 0;
2594
2595 ret = android_bind_enabled_functions(dev, c);
2596 if (ret)
2597 return ret;
2598
2599 return 0;
2600}
2601
2602static void android_unbind_config(struct usb_configuration *c)
2603{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002604 struct android_dev *dev = cdev_to_android_dev(c->cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002605
Mayank Rana142fe412013-11-11 14:16:30 +05302606 if (c->cdev->gadget->streaming_enabled) {
2607 c->cdev->gadget->streaming_enabled = false;
2608 pr_debug("setting streaming_enabled to false.\n");
2609 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002610 android_unbind_enabled_functions(dev, c);
2611}
2612
2613static int android_bind(struct usb_composite_dev *cdev)
2614{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002615 struct android_dev *dev;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002616 struct usb_gadget *gadget = cdev->gadget;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002617 struct android_configuration *conf;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002618 int gcnum, id, ret;
2619
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002620 /* Bind to the last android_dev that was probed */
2621 dev = list_entry(android_dev_list.prev, struct android_dev, list_item);
2622
2623 dev->cdev = cdev;
2624
Benoit Goby1e8ce152011-12-12 13:01:23 -08002625 /*
2626 * Start disconnected. Userspace will connect the gadget once
2627 * it is done configuring the functions.
2628 */
2629 usb_gadget_disconnect(gadget);
2630
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002631 /* Init the supported functions only once, on the first android_dev */
2632 if (android_dev_count == 1) {
2633 ret = android_init_functions(dev->functions, cdev);
2634 if (ret)
2635 return ret;
2636 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002637
2638 /* Allocate string descriptor numbers ... note that string
2639 * contents can be overridden by the composite_dev glue.
2640 */
2641 id = usb_string_id(cdev);
2642 if (id < 0)
2643 return id;
2644 strings_dev[STRING_MANUFACTURER_IDX].id = id;
2645 device_desc.iManufacturer = id;
2646
2647 id = usb_string_id(cdev);
2648 if (id < 0)
2649 return id;
2650 strings_dev[STRING_PRODUCT_IDX].id = id;
2651 device_desc.iProduct = id;
2652
2653 /* Default strings - should be updated by userspace */
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302654 strlcpy(manufacturer_string, "Android",
2655 sizeof(manufacturer_string) - 1);
2656 strlcpy(product_string, "Android", sizeof(product_string) - 1);
2657 strlcpy(serial_string, "0123456789ABCDEF", sizeof(serial_string) - 1);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002658
2659 id = usb_string_id(cdev);
2660 if (id < 0)
2661 return id;
2662 strings_dev[STRING_SERIAL_IDX].id = id;
2663 device_desc.iSerialNumber = id;
2664
Vijayavardhan Vennapusa56e60522012-02-16 15:40:16 +05302665 if (gadget_is_otg(cdev->gadget))
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002666 list_for_each_entry(conf, &dev->configs, list_item)
2667 conf->usb_config.descriptors = otg_desc;
Vijayavardhan Vennapusa56e60522012-02-16 15:40:16 +05302668
Benoit Goby1e8ce152011-12-12 13:01:23 -08002669 gcnum = usb_gadget_controller_number(gadget);
2670 if (gcnum >= 0)
2671 device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
2672 else {
2673 pr_warning("%s: controller '%s' not recognized\n",
2674 longname, gadget->name);
2675 device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
2676 }
2677
Benoit Goby1e8ce152011-12-12 13:01:23 -08002678 return 0;
2679}
2680
2681static int android_usb_unbind(struct usb_composite_dev *cdev)
2682{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002683 struct android_dev *dev = cdev_to_android_dev(cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002684
Lena Salmand092f2d2012-03-12 17:27:24 +02002685 manufacturer_string[0] = '\0';
2686 product_string[0] = '\0';
2687 serial_string[0] = '0';
Benoit Goby1e8ce152011-12-12 13:01:23 -08002688 cancel_work_sync(&dev->work);
2689 android_cleanup_functions(dev->functions);
2690 return 0;
2691}
2692
2693static struct usb_composite_driver android_usb_driver = {
2694 .name = "android_usb",
2695 .dev = &device_desc,
2696 .strings = dev_strings,
2697 .unbind = android_usb_unbind,
Tatyana Brokhman3ba28902011-06-29 16:41:49 +03002698 .max_speed = USB_SPEED_SUPER
Benoit Goby1e8ce152011-12-12 13:01:23 -08002699};
2700
2701static int
2702android_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *c)
2703{
Benoit Goby1e8ce152011-12-12 13:01:23 -08002704 struct usb_composite_dev *cdev = get_gadget_data(gadget);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002705 struct android_dev *dev = cdev_to_android_dev(cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002706 struct usb_request *req = cdev->req;
2707 struct android_usb_function *f;
Ido Shayevitz68557e32012-11-06 12:40:37 +02002708 struct android_usb_function_holder *f_holder;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002709 struct android_configuration *conf;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002710 int value = -EOPNOTSUPP;
2711 unsigned long flags;
2712
2713 req->zero = 0;
2714 req->complete = composite_setup_complete;
2715 req->length = 0;
2716 gadget->ep0->driver_data = cdev;
2717
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002718 list_for_each_entry(conf, &dev->configs, list_item)
Ido Shayevitz68557e32012-11-06 12:40:37 +02002719 list_for_each_entry(f_holder,
2720 &conf->enabled_functions,
2721 enabled_list) {
2722 f = f_holder->f;
2723 if (f->ctrlrequest) {
2724 value = f->ctrlrequest(f, cdev, c);
2725 if (value >= 0)
2726 break;
2727 }
2728 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002729
Benoit Gobycf3fc062011-12-19 14:39:37 -08002730 /* Special case the accessory function.
2731 * It needs to handle control requests before it is enabled.
2732 */
2733 if (value < 0)
2734 value = acc_ctrlrequest(cdev, c);
2735
Benoit Goby1e8ce152011-12-12 13:01:23 -08002736 if (value < 0)
2737 value = composite_setup(gadget, c);
2738
2739 spin_lock_irqsave(&cdev->lock, flags);
2740 if (!dev->connected) {
2741 dev->connected = 1;
2742 schedule_work(&dev->work);
2743 } else if (c->bRequest == USB_REQ_SET_CONFIGURATION &&
2744 cdev->config) {
2745 schedule_work(&dev->work);
2746 }
2747 spin_unlock_irqrestore(&cdev->lock, flags);
2748
2749 return value;
2750}
2751
2752static void android_disconnect(struct usb_gadget *gadget)
2753{
Benoit Goby1e8ce152011-12-12 13:01:23 -08002754 struct usb_composite_dev *cdev = get_gadget_data(gadget);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002755 struct android_dev *dev = cdev_to_android_dev(cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002756 unsigned long flags;
2757
2758 composite_disconnect(gadget);
Mike Lockwoode7558bb2012-08-27 16:23:48 +05302759 /* accessory HID support can be active while the
2760 accessory function is not actually enabled,
2761 so we need to inform it when we are disconnected.
2762 */
2763 acc_disconnect();
Benoit Goby1e8ce152011-12-12 13:01:23 -08002764
2765 spin_lock_irqsave(&cdev->lock, flags);
2766 dev->connected = 0;
2767 schedule_work(&dev->work);
2768 spin_unlock_irqrestore(&cdev->lock, flags);
2769}
2770
Ido Shayevitzfb5edfe2012-12-26 14:26:37 +02002771static void android_suspend(struct usb_gadget *gadget)
2772{
2773 struct usb_composite_dev *cdev = get_gadget_data(gadget);
2774 struct android_dev *dev = cdev_to_android_dev(cdev);
2775 unsigned long flags;
2776
2777 spin_lock_irqsave(&cdev->lock, flags);
Vijayavardhan Vennapusa8594e862013-11-01 16:44:31 +05302778 if (!dev->suspended) {
2779 dev->suspended = 1;
2780 schedule_work(&dev->work);
2781 }
Ido Shayevitzfb5edfe2012-12-26 14:26:37 +02002782 spin_unlock_irqrestore(&cdev->lock, flags);
2783
2784 composite_suspend(gadget);
2785}
2786
2787static void android_resume(struct usb_gadget *gadget)
2788{
2789 struct usb_composite_dev *cdev = get_gadget_data(gadget);
2790 struct android_dev *dev = cdev_to_android_dev(cdev);
2791 unsigned long flags;
2792
2793 spin_lock_irqsave(&cdev->lock, flags);
Vijayavardhan Vennapusa8594e862013-11-01 16:44:31 +05302794 if (dev->suspended) {
2795 dev->suspended = 0;
2796 schedule_work(&dev->work);
2797 }
Ido Shayevitzfb5edfe2012-12-26 14:26:37 +02002798 spin_unlock_irqrestore(&cdev->lock, flags);
2799
2800 composite_resume(gadget);
2801}
2802
2803
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002804static int android_create_device(struct android_dev *dev, u8 usb_core_id)
Benoit Goby1e8ce152011-12-12 13:01:23 -08002805{
2806 struct device_attribute **attrs = android_usb_attributes;
2807 struct device_attribute *attr;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002808 char device_node_name[ANDROID_DEVICE_NODE_NAME_LENGTH];
Benoit Goby1e8ce152011-12-12 13:01:23 -08002809 int err;
2810
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002811 /*
2812 * The primary usb core should always have usb_core_id=0, since
2813 * Android user space is currently interested in android0 events.
2814 */
2815 snprintf(device_node_name, ANDROID_DEVICE_NODE_NAME_LENGTH,
2816 "android%d", usb_core_id);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002817 dev->dev = device_create(android_class, NULL,
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002818 MKDEV(0, 0), NULL, device_node_name);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002819 if (IS_ERR(dev->dev))
2820 return PTR_ERR(dev->dev);
2821
2822 dev_set_drvdata(dev->dev, dev);
2823
2824 while ((attr = *attrs++)) {
2825 err = device_create_file(dev->dev, attr);
2826 if (err) {
2827 device_destroy(android_class, dev->dev->devt);
2828 return err;
2829 }
2830 }
2831 return 0;
2832}
2833
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05302834static void android_destroy_device(struct android_dev *dev)
Benoit Goby1e8ce152011-12-12 13:01:23 -08002835{
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05302836 struct device_attribute **attrs = android_usb_attributes;
2837 struct device_attribute *attr;
2838
2839 while ((attr = *attrs++))
2840 device_remove_file(dev->dev, attr);
2841 device_destroy(android_class, dev->dev->devt);
2842}
2843
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002844static struct android_dev *cdev_to_android_dev(struct usb_composite_dev *cdev)
2845{
2846 struct android_dev *dev = NULL;
2847
2848 /* Find the android dev from the list */
2849 list_for_each_entry(dev, &android_dev_list, list_item) {
2850 if (dev->cdev == cdev)
2851 break;
2852 }
2853
2854 return dev;
2855}
2856
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002857static struct android_configuration *alloc_android_config
2858 (struct android_dev *dev)
2859{
2860 struct android_configuration *conf;
2861
2862 conf = kzalloc(sizeof(*conf), GFP_KERNEL);
2863 if (!conf) {
2864 pr_err("%s(): Failed to alloc memory for android conf\n",
2865 __func__);
2866 return ERR_PTR(-ENOMEM);
2867 }
2868
2869 dev->configs_num++;
2870 conf->usb_config.label = dev->name;
2871 conf->usb_config.unbind = android_unbind_config;
2872 conf->usb_config.bConfigurationValue = dev->configs_num;
2873
2874 INIT_LIST_HEAD(&conf->enabled_functions);
2875
2876 list_add_tail(&conf->list_item, &dev->configs);
2877
2878 return conf;
2879}
2880
2881static void free_android_config(struct android_dev *dev,
2882 struct android_configuration *conf)
2883{
2884 list_del(&conf->list_item);
2885 dev->configs_num--;
2886 kfree(conf);
2887}
2888
Manu Gautam43c61a12012-08-22 17:09:37 -07002889static int usb_diag_update_pid_and_serial_num(u32 pid, const char *snum)
2890{
2891 struct dload_struct local_diag_dload = { 0 };
2892 int *src, *dst, i;
2893
2894 if (!diag_dload) {
2895 pr_debug("%s: unable to update PID and serial_no\n", __func__);
2896 return -ENODEV;
2897 }
2898
2899 pr_debug("%s: dload:%p pid:%x serial_num:%s\n",
2900 __func__, diag_dload, pid, snum);
2901
2902 /* update pid */
2903 local_diag_dload.magic_struct.pid = PID_MAGIC_ID;
2904 local_diag_dload.pid = pid;
2905
2906 /* update serial number */
2907 if (!snum) {
2908 local_diag_dload.magic_struct.serial_num = 0;
2909 memset(&local_diag_dload.serial_number, 0,
2910 SERIAL_NUMBER_LENGTH);
2911 } else {
2912 local_diag_dload.magic_struct.serial_num = SERIAL_NUM_MAGIC_ID;
2913 strlcpy((char *)&local_diag_dload.serial_number, snum,
2914 SERIAL_NUMBER_LENGTH);
2915 }
2916
2917 /* Copy to shared struct (accesses need to be 32 bit aligned) */
2918 src = (int *)&local_diag_dload;
2919 dst = (int *)diag_dload;
2920
2921 for (i = 0; i < sizeof(*diag_dload) / 4; i++)
2922 *dst++ = *src++;
2923
2924 return 0;
2925}
2926
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002927static int __devinit android_probe(struct platform_device *pdev)
2928{
Vijayavardhan Vennapusa8ceade82012-11-01 15:11:21 +05302929 struct android_usb_platform_data *pdata;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002930 struct android_dev *android_dev;
Manu Gautam43c61a12012-08-22 17:09:37 -07002931 struct resource *res;
Mayank Rana142fe412013-11-11 14:16:30 +05302932 int ret = 0, i, len = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002933
Vijayavardhan Vennapusa8ceade82012-11-01 15:11:21 +05302934 if (pdev->dev.of_node) {
2935 dev_dbg(&pdev->dev, "device tree enabled\n");
2936 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
2937 if (!pdata) {
2938 pr_err("unable to allocate platform data\n");
2939 return -ENOMEM;
2940 }
2941
2942 of_property_read_u32(pdev->dev.of_node,
2943 "qcom,android-usb-swfi-latency",
2944 &pdata->swfi_latency);
Chiranjeevi Velempati9d797662013-04-22 15:45:38 +05302945 pdata->cdrom = of_property_read_bool(pdev->dev.of_node,
2946 "qcom,android-usb-cdrom");
wujin269684c2013-09-02 17:51:38 +08002947 pdata->internal_ums = of_property_read_bool(pdev->dev.of_node,
2948 "qcom,android-usb-internal-ums");
Mayank Rana142fe412013-11-11 14:16:30 +05302949 len = of_property_count_strings(pdev->dev.of_node,
2950 "qcom,streaming-func");
2951 if (len > MAX_STREAMING_FUNCS) {
2952 pr_err("Invalid number of functions used.\n");
2953 return -EINVAL;
2954 }
2955
2956 for (i = 0; i < len; i++) {
2957 const char *name = NULL;
2958
2959 of_property_read_string_index(pdev->dev.of_node,
2960 "qcom,streaming-func", i, &name);
2961 if (!name)
2962 continue;
2963
2964 if (sizeof(name) > FUNC_NAME_LEN) {
2965 pr_err("Function name is bigger than allowed.\n");
2966 continue;
2967 }
2968
2969 strlcpy(pdata->streaming_func[i], name,
2970 sizeof(pdata->streaming_func[i]));
2971 pr_debug("name of streaming function:%s\n",
2972 pdata->streaming_func[i]);
2973 }
2974
2975 pdata->streaming_func_count = len;
Vijayavardhan Vennapusa8ceade82012-11-01 15:11:21 +05302976 } else {
2977 pdata = pdev->dev.platform_data;
2978 }
2979
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002980 if (!android_class) {
2981 android_class = class_create(THIS_MODULE, "android_usb");
2982 if (IS_ERR(android_class))
2983 return PTR_ERR(android_class);
2984 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002985
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002986 android_dev = kzalloc(sizeof(*android_dev), GFP_KERNEL);
2987 if (!android_dev) {
2988 pr_err("%s(): Failed to alloc memory for android_dev\n",
2989 __func__);
2990 ret = -ENOMEM;
2991 goto err_alloc;
2992 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002993
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002994 android_dev->name = pdev->name;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002995 android_dev->disable_depth = 1;
2996 android_dev->functions = supported_functions;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002997 android_dev->configs_num = 0;
2998 INIT_LIST_HEAD(&android_dev->configs);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002999 INIT_WORK(&android_dev->work, android_work);
3000 mutex_init(&android_dev->mutex);
3001
3002 android_dev->pdata = pdata;
3003
3004 list_add_tail(&android_dev->list_item, &android_dev_list);
3005 android_dev_count++;
3006
3007 if (pdata)
3008 composite_driver.usb_core_id = pdata->usb_core_id;
3009 else
3010 composite_driver.usb_core_id = 0; /*To backward compatibility*/
3011
Manu Gautam43c61a12012-08-22 17:09:37 -07003012 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
3013 if (res) {
3014 diag_dload = devm_ioremap(&pdev->dev, res->start,
3015 resource_size(res));
3016 if (!diag_dload) {
3017 dev_err(&pdev->dev, "ioremap failed\n");
3018 ret = -ENOMEM;
3019 goto err_dev;
3020 }
3021 } else {
3022 dev_dbg(&pdev->dev, "failed to get mem resource\n");
3023 }
3024
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03003025 ret = android_create_device(android_dev, composite_driver.usb_core_id);
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05303026 if (ret) {
3027 pr_err("%s(): android_create_device failed\n", __func__);
3028 goto err_dev;
3029 }
3030
Lena Salmand092f2d2012-03-12 17:27:24 +02003031 ret = usb_composite_probe(&android_usb_driver, android_bind);
3032 if (ret) {
3033 pr_err("%s(): Failed to register android "
3034 "composite driver\n", __func__);
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05303035 goto err_probe;
Lena Salmand092f2d2012-03-12 17:27:24 +02003036 }
3037
Ofir Cohen94213a72012-05-03 14:26:32 +03003038 /* pm qos request to prevent apps idle power collapse */
Manu Gautam94dc6142012-05-08 14:35:24 +05303039 if (pdata && pdata->swfi_latency)
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03003040 pm_qos_add_request(&android_dev->pm_qos_req_dma,
Ofir Cohen94213a72012-05-03 14:26:32 +03003041 PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03003042 strlcpy(android_dev->pm_qos, "high", sizeof(android_dev->pm_qos));
Ofir Cohen94213a72012-05-03 14:26:32 +03003043
Lena Salmand092f2d2012-03-12 17:27:24 +02003044 return ret;
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05303045err_probe:
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03003046 android_destroy_device(android_dev);
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05303047err_dev:
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03003048 list_del(&android_dev->list_item);
3049 android_dev_count--;
3050 kfree(android_dev);
3051err_alloc:
3052 if (list_empty(&android_dev_list)) {
3053 class_destroy(android_class);
3054 android_class = NULL;
3055 }
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05303056 return ret;
Lena Salmand092f2d2012-03-12 17:27:24 +02003057}
3058
3059static int android_remove(struct platform_device *pdev)
3060{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03003061 struct android_dev *dev = NULL;
Ofir Cohen94213a72012-05-03 14:26:32 +03003062 struct android_usb_platform_data *pdata = pdev->dev.platform_data;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03003063 int usb_core_id = 0;
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05303064
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03003065 if (pdata)
3066 usb_core_id = pdata->usb_core_id;
3067
3068 /* Find the android dev from the list */
3069 list_for_each_entry(dev, &android_dev_list, list_item) {
3070 if (!dev->pdata)
3071 break; /*To backward compatibility*/
3072 if (dev->pdata->usb_core_id == usb_core_id)
3073 break;
3074 }
3075
3076 if (dev) {
3077 android_destroy_device(dev);
3078 if (pdata && pdata->swfi_latency)
3079 pm_qos_remove_request(&dev->pm_qos_req_dma);
3080 list_del(&dev->list_item);
3081 android_dev_count--;
3082 kfree(dev);
3083 }
3084
3085 if (list_empty(&android_dev_list)) {
3086 class_destroy(android_class);
3087 android_class = NULL;
3088 usb_composite_unregister(&android_usb_driver);
3089 }
Ofir Cohen94213a72012-05-03 14:26:32 +03003090
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003091 return 0;
3092}
3093
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03003094static const struct platform_device_id android_id_table[] __devinitconst = {
3095 {
3096 .name = "android_usb",
3097 },
3098 {
3099 .name = "android_usb_hsic",
3100 },
3101};
3102
Manu Gautam43c61a12012-08-22 17:09:37 -07003103static struct of_device_id usb_android_dt_match[] = {
3104 { .compatible = "qcom,android-usb",
3105 },
3106 {}
3107};
3108
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003109static struct platform_driver android_platform_driver = {
Manu Gautam43c61a12012-08-22 17:09:37 -07003110 .driver = {
3111 .name = "android_usb",
3112 .of_match_table = usb_android_dt_match,
3113 },
Lena Salmand092f2d2012-03-12 17:27:24 +02003114 .probe = android_probe,
3115 .remove = android_remove,
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03003116 .id_table = android_id_table,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003117};
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05003118
3119static int __init init(void)
3120{
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05303121 int ret;
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05003122
Benoit Goby1e8ce152011-12-12 13:01:23 -08003123 /* Override composite driver functions */
3124 composite_driver.setup = android_setup;
3125 composite_driver.disconnect = android_disconnect;
Ido Shayevitzfb5edfe2012-12-26 14:26:37 +02003126 composite_driver.suspend = android_suspend;
3127 composite_driver.resume = android_resume;
Benoit Goby1e8ce152011-12-12 13:01:23 -08003128
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03003129 INIT_LIST_HEAD(&android_dev_list);
3130 android_dev_count = 0;
3131
Pavankumar Kondeti044914d2012-01-31 12:56:13 +05303132 ret = platform_driver_register(&android_platform_driver);
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05303133 if (ret) {
3134 pr_err("%s(): Failed to register android"
3135 "platform driver\n", __func__);
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05303136 }
Lena Salmand092f2d2012-03-12 17:27:24 +02003137
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05303138 return ret;
Benoit Goby1e8ce152011-12-12 13:01:23 -08003139}
3140module_init(init);
3141
3142static void __exit cleanup(void)
3143{
Lena Salmand092f2d2012-03-12 17:27:24 +02003144 platform_driver_unregister(&android_platform_driver);
Benoit Goby1e8ce152011-12-12 13:01:23 -08003145}
3146module_exit(cleanup);