blob: 5b83cb4d59f551c3d64729df5744e4e3d4dd5142 [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>
Benoit Goby1e8ce152011-12-12 13:01:23 -080027
28#include <linux/usb/ch9.h>
29#include <linux/usb/composite.h>
30#include <linux/usb/gadget.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070031#include <linux/usb/android.h>
Benoit Goby1e8ce152011-12-12 13:01:23 -080032
33#include "gadget_chips.h"
Anh Nguyen64376432012-10-17 16:08:48 -070034#ifndef DEBUG
35#define DEBUG 1
36#endif
Benoit Goby1e8ce152011-12-12 13:01:23 -080037/*
38 * Kbuild is not very cooperative with respect to linking separately
39 * compiled library objects into one module. So for now we won't use
40 * separate compilation ... ensuring init/exit sections work to shrink
41 * the runtime footprint, and giving us at least some parts of what
42 * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
43 */
44#include "usbstring.c"
45#include "config.c"
46#include "epautoconf.c"
47#include "composite.c"
48
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070049#include "f_diag.c"
Shimrit Malichia00d7322012-08-05 13:56:28 +030050#include "f_qdss.c"
Manu Gautam1c8ffd72011-09-02 16:00:49 +053051#include "f_rmnet_smd.c"
Manu Gautam8e0719b2011-09-26 14:47:55 +053052#include "f_rmnet_sdio.c"
53#include "f_rmnet_smd_sdio.c"
Manu Gautam2b0234a2011-09-07 16:47:52 +053054#include "f_rmnet.c"
Ajay Dudani34b1e302012-08-27 16:43:53 +053055#include "f_audio_source.c"
Benoit Goby1e8ce152011-12-12 13:01:23 -080056#include "f_mass_storage.c"
57#include "u_serial.c"
Manu Gautama4d993f2011-08-30 18:25:55 +053058#include "u_sdio.c"
59#include "u_smd.c"
60#include "u_bam.c"
Manu Gautam2b0234a2011-09-07 16:47:52 +053061#include "u_rmnet_ctrl_smd.c"
Jack Pham427f6922011-11-23 19:42:00 -080062#include "u_ctrl_hsic.c"
63#include "u_data_hsic.c"
Vijayavardhan Vennapusaeb8d2392012-04-03 18:58:49 +053064#include "u_ctrl_hsuart.c"
65#include "u_data_hsuart.c"
Manu Gautama4d993f2011-08-30 18:25:55 +053066#include "f_serial.c"
Benoit Goby1e8ce152011-12-12 13:01:23 -080067#include "f_acm.c"
Benoit Goby2b6862d2011-12-19 14:38:41 -080068#include "f_adb.c"
Chiranjeevi Velempatie130fd02011-11-29 05:06:13 +053069#include "f_ccid.c"
Benoit Gobyf0fbc482011-12-19 14:37:50 -080070#include "f_mtp.c"
Benoit Gobycf3fc062011-12-19 14:39:37 -080071#include "f_accessory.c"
Devin Kim0c5b9ce2012-06-19 21:34:44 -070072#ifdef CONFIG_USB_ANDROID_CDC_ECM
73#include "f_ecm.c"
74#else
Benoit Goby1e8ce152011-12-12 13:01:23 -080075#define USB_ETH_RNDIS y
76#include "f_rndis.c"
77#include "rndis.c"
Devin Kim0c5b9ce2012-06-19 21:34:44 -070078#endif
Benoit Goby1e8ce152011-12-12 13:01:23 -080079#include "u_ether.c"
Anna Perela8c991d2012-04-09 16:44:46 +030080#include "u_bam_data.c"
81#include "f_mbim.c"
Ofir Cohen7b155422012-07-31 13:02:49 +030082#include "f_qc_ecm.c"
Ofir Cohenaef90b72012-07-31 12:37:04 +020083#include "f_qc_rndis.c"
Ofir Cohen7b155422012-07-31 13:02:49 +030084#include "u_qc_ether.c"
Pavankumar Kondeti8f6ca4f2012-06-26 09:44:36 +053085#ifdef CONFIG_TARGET_CORE
86#include "f_tcm.c"
87#endif
Benoit Goby1e8ce152011-12-12 13:01:23 -080088
89MODULE_AUTHOR("Mike Lockwood");
90MODULE_DESCRIPTION("Android Composite USB Driver");
91MODULE_LICENSE("GPL");
92MODULE_VERSION("1.0");
93
94static const char longname[] = "Gadget Android";
95
96/* Default vendor and product IDs, overridden by userspace */
97#define VENDOR_ID 0x18D1
98#define PRODUCT_ID 0x0001
99
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300100#define ANDROID_DEVICE_NODE_NAME_LENGTH 11
101
Benoit Goby1e8ce152011-12-12 13:01:23 -0800102struct android_usb_function {
103 char *name;
104 void *config;
105
106 struct device *dev;
107 char *dev_name;
108 struct device_attribute **attributes;
109
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300110 /* for android_conf.enabled_functions */
Benoit Goby1e8ce152011-12-12 13:01:23 -0800111 struct list_head enabled_list;
112
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300113 struct android_dev *android_dev;
114
Benoit Goby1e8ce152011-12-12 13:01:23 -0800115 /* Optional: initialization during gadget bind */
116 int (*init)(struct android_usb_function *, struct usb_composite_dev *);
117 /* Optional: cleanup during gadget unbind */
118 void (*cleanup)(struct android_usb_function *);
Benoit Goby80ba14d2012-03-19 18:56:52 -0700119 /* Optional: called when the function is added the list of
120 * enabled functions */
121 void (*enable)(struct android_usb_function *);
122 /* Optional: called when it is removed */
123 void (*disable)(struct android_usb_function *);
Benoit Goby1e8ce152011-12-12 13:01:23 -0800124
125 int (*bind_config)(struct android_usb_function *,
126 struct usb_configuration *);
127
128 /* Optional: called when the configuration is removed */
129 void (*unbind_config)(struct android_usb_function *,
130 struct usb_configuration *);
131 /* Optional: handle ctrl requests before the device is configured */
132 int (*ctrlrequest)(struct android_usb_function *,
133 struct usb_composite_dev *,
134 const struct usb_ctrlrequest *);
135};
136
137struct android_dev {
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300138 const char *name;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800139 struct android_usb_function **functions;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800140 struct usb_composite_dev *cdev;
141 struct device *dev;
142
143 bool enabled;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700144 int disable_depth;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800145 struct mutex mutex;
Steve Mucklef132c6c2012-06-06 18:30:57 -0700146 struct android_usb_platform_data *pdata;
147
Benoit Goby1e8ce152011-12-12 13:01:23 -0800148 bool connected;
149 bool sw_connected;
Ofir Cohen94213a72012-05-03 14:26:32 +0300150 char pm_qos[5];
Steve Mucklef132c6c2012-06-06 18:30:57 -0700151 struct pm_qos_request pm_qos_req_dma;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800152 struct work_struct work;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300153
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300154 /* A list of struct android_configuration */
155 struct list_head configs;
156 int configs_num;
157
158 /* A list node inside the android_dev_list */
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300159 struct list_head list_item;
160
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300161};
162
163struct android_configuration {
164 struct usb_configuration usb_config;
165
166 /* A list of the functions supported by this config */
167 struct list_head enabled_functions;
168
169 /* A list node inside the struct android_dev.configs list */
170 struct list_head list_item;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800171};
172
173static struct class *android_class;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300174static struct list_head android_dev_list;
175static int android_dev_count;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800176static int android_bind_config(struct usb_configuration *c);
177static void android_unbind_config(struct usb_configuration *c);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300178static struct android_dev *cdev_to_android_dev(struct usb_composite_dev *cdev);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300179static struct android_configuration *alloc_android_config
180 (struct android_dev *dev);
181static void free_android_config(struct android_dev *dev,
182 struct android_configuration *conf);
Benoit Goby1e8ce152011-12-12 13:01:23 -0800183
184/* string IDs are assigned dynamically */
185#define STRING_MANUFACTURER_IDX 0
186#define STRING_PRODUCT_IDX 1
187#define STRING_SERIAL_IDX 2
188
189static char manufacturer_string[256];
190static char product_string[256];
191static char serial_string[256];
192
193/* String Table */
194static struct usb_string strings_dev[] = {
195 [STRING_MANUFACTURER_IDX].s = manufacturer_string,
196 [STRING_PRODUCT_IDX].s = product_string,
197 [STRING_SERIAL_IDX].s = serial_string,
198 { } /* end of list */
199};
200
201static struct usb_gadget_strings stringtab_dev = {
202 .language = 0x0409, /* en-us */
203 .strings = strings_dev,
204};
205
206static struct usb_gadget_strings *dev_strings[] = {
207 &stringtab_dev,
208 NULL,
209};
210
211static struct usb_device_descriptor device_desc = {
212 .bLength = sizeof(device_desc),
213 .bDescriptorType = USB_DT_DEVICE,
214 .bcdUSB = __constant_cpu_to_le16(0x0200),
215 .bDeviceClass = USB_CLASS_PER_INTERFACE,
216 .idVendor = __constant_cpu_to_le16(VENDOR_ID),
217 .idProduct = __constant_cpu_to_le16(PRODUCT_ID),
218 .bcdDevice = __constant_cpu_to_le16(0xffff),
219 .bNumConfigurations = 1,
220};
221
Vijayavardhan Vennapusa56e60522012-02-16 15:40:16 +0530222static struct usb_otg_descriptor otg_descriptor = {
223 .bLength = sizeof otg_descriptor,
224 .bDescriptorType = USB_DT_OTG,
225 .bmAttributes = USB_OTG_SRP | USB_OTG_HNP,
226 .bcdOTG = __constant_cpu_to_le16(0x0200),
227};
228
229static const struct usb_descriptor_header *otg_desc[] = {
230 (struct usb_descriptor_header *) &otg_descriptor,
231 NULL,
232};
233
Manu Gautama2b54142012-04-03 14:34:32 +0530234enum android_device_state {
235 USB_DISCONNECTED,
236 USB_CONNECTED,
237 USB_CONFIGURED,
238};
239
Ofir Cohen94213a72012-05-03 14:26:32 +0300240static void android_pm_qos_update_latency(struct android_dev *dev, int vote)
241{
242 struct android_usb_platform_data *pdata = dev->pdata;
243 u32 swfi_latency = 0;
244 static int last_vote = -1;
245
Ofir Cohen56eb7072012-05-20 11:41:39 +0300246 if (!pdata || vote == last_vote
247 || !pdata->swfi_latency)
Ofir Cohen94213a72012-05-03 14:26:32 +0300248 return;
249
250 swfi_latency = pdata->swfi_latency + 1;
251 if (vote)
252 pm_qos_update_request(&dev->pm_qos_req_dma,
253 swfi_latency);
254 else
255 pm_qos_update_request(&dev->pm_qos_req_dma,
256 PM_QOS_DEFAULT_VALUE);
257 last_vote = vote;
258}
259
Benoit Goby1e8ce152011-12-12 13:01:23 -0800260static void android_work(struct work_struct *data)
261{
262 struct android_dev *dev = container_of(data, struct android_dev, work);
263 struct usb_composite_dev *cdev = dev->cdev;
264 char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL };
265 char *connected[2] = { "USB_STATE=CONNECTED", NULL };
266 char *configured[2] = { "USB_STATE=CONFIGURED", NULL };
267 char **uevent_envp = NULL;
Manu Gautama2b54142012-04-03 14:34:32 +0530268 static enum android_device_state last_uevent, next_state;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800269 unsigned long flags;
Ofir Cohenbcbb1a72012-05-20 16:28:15 +0300270 int pm_qos_vote = -1;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800271
272 spin_lock_irqsave(&cdev->lock, flags);
Manu Gautama2b54142012-04-03 14:34:32 +0530273 if (cdev->config) {
Benoit Goby1e8ce152011-12-12 13:01:23 -0800274 uevent_envp = configured;
Manu Gautama2b54142012-04-03 14:34:32 +0530275 next_state = USB_CONFIGURED;
276 } else if (dev->connected != dev->sw_connected) {
Benoit Goby1e8ce152011-12-12 13:01:23 -0800277 uevent_envp = dev->connected ? connected : disconnected;
Manu Gautama2b54142012-04-03 14:34:32 +0530278 next_state = dev->connected ? USB_CONNECTED : USB_DISCONNECTED;
Ofir Cohen94213a72012-05-03 14:26:32 +0300279 if (dev->connected && strncmp(dev->pm_qos, "low", 3))
Ofir Cohenbcbb1a72012-05-20 16:28:15 +0300280 pm_qos_vote = 1;
Ofir Cohen94213a72012-05-03 14:26:32 +0300281 else if (!dev->connected || !strncmp(dev->pm_qos, "low", 3))
Ofir Cohenbcbb1a72012-05-20 16:28:15 +0300282 pm_qos_vote = 0;
Manu Gautama2b54142012-04-03 14:34:32 +0530283 }
Benoit Goby1e8ce152011-12-12 13:01:23 -0800284 dev->sw_connected = dev->connected;
285 spin_unlock_irqrestore(&cdev->lock, flags);
286
Ofir Cohenbcbb1a72012-05-20 16:28:15 +0300287 if (pm_qos_vote != -1)
288 android_pm_qos_update_latency(dev, pm_qos_vote);
289
Benoit Goby1e8ce152011-12-12 13:01:23 -0800290 if (uevent_envp) {
Manu Gautama2b54142012-04-03 14:34:32 +0530291 /*
292 * Some userspace modules, e.g. MTP, work correctly only if
293 * CONFIGURED uevent is preceded by DISCONNECT uevent.
294 * Check if we missed sending out a DISCONNECT uevent. This can
295 * happen if host PC resets and configures device really quick.
296 */
297 if (((uevent_envp == connected) &&
298 (last_uevent != USB_DISCONNECTED)) ||
299 ((uevent_envp == configured) &&
300 (last_uevent == USB_CONFIGURED))) {
301 pr_info("%s: sent missed DISCONNECT event\n", __func__);
302 kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE,
303 disconnected);
304 msleep(20);
305 }
306 /*
307 * Before sending out CONFIGURED uevent give function drivers
308 * a chance to wakeup userspace threads and notify disconnect
309 */
310 if (uevent_envp == configured)
311 msleep(50);
312
Benoit Goby1e8ce152011-12-12 13:01:23 -0800313 kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE, uevent_envp);
Manu Gautama2b54142012-04-03 14:34:32 +0530314 last_uevent = next_state;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800315 pr_info("%s: sent uevent %s\n", __func__, uevent_envp[0]);
316 } else {
317 pr_info("%s: did not send uevent (%d %d %p)\n", __func__,
318 dev->connected, dev->sw_connected, cdev->config);
319 }
320}
321
Benoit Goby80ba14d2012-03-19 18:56:52 -0700322static void android_enable(struct android_dev *dev)
323{
324 struct usb_composite_dev *cdev = dev->cdev;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300325 struct android_configuration *conf;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700326
327 if (WARN_ON(!dev->disable_depth))
328 return;
329
330 if (--dev->disable_depth == 0) {
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300331
332 list_for_each_entry(conf, &dev->configs, list_item)
333 usb_add_config(cdev, &conf->usb_config,
334 android_bind_config);
335
Benoit Goby80ba14d2012-03-19 18:56:52 -0700336 usb_gadget_connect(cdev->gadget);
337 }
338}
339
340static void android_disable(struct android_dev *dev)
341{
342 struct usb_composite_dev *cdev = dev->cdev;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300343 struct android_configuration *conf;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700344
345 if (dev->disable_depth++ == 0) {
346 usb_gadget_disconnect(cdev->gadget);
347 /* Cancel pending control requests */
348 usb_ep_dequeue(cdev->gadget->ep0, cdev->req);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +0300349
350 list_for_each_entry(conf, &dev->configs, list_item)
351 usb_remove_config(cdev, &conf->usb_config);
Benoit Goby80ba14d2012-03-19 18:56:52 -0700352 }
353}
Benoit Goby1e8ce152011-12-12 13:01:23 -0800354
355/*-------------------------------------------------------------------------*/
356/* Supported functions initialization */
357
Benoit Goby80ba14d2012-03-19 18:56:52 -0700358struct adb_data {
359 bool opened;
360 bool enabled;
361};
362
Benoit Goby2b6862d2011-12-19 14:38:41 -0800363static int
364adb_function_init(struct android_usb_function *f,
365 struct usb_composite_dev *cdev)
366{
Benoit Goby80ba14d2012-03-19 18:56:52 -0700367 f->config = kzalloc(sizeof(struct adb_data), GFP_KERNEL);
368 if (!f->config)
369 return -ENOMEM;
370
Benoit Goby2b6862d2011-12-19 14:38:41 -0800371 return adb_setup();
372}
373
374static void adb_function_cleanup(struct android_usb_function *f)
375{
376 adb_cleanup();
Benoit Goby80ba14d2012-03-19 18:56:52 -0700377 kfree(f->config);
Benoit Goby2b6862d2011-12-19 14:38:41 -0800378}
379
380static int
381adb_function_bind_config(struct android_usb_function *f,
382 struct usb_configuration *c)
383{
384 return adb_bind_config(c);
385}
386
Benoit Goby80ba14d2012-03-19 18:56:52 -0700387static void adb_android_function_enable(struct android_usb_function *f)
388{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300389 struct android_dev *dev = f->android_dev;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700390 struct adb_data *data = f->config;
391
392 data->enabled = true;
393
394 /* Disable the gadget until adbd is ready */
395 if (!data->opened)
396 android_disable(dev);
397}
398
399static void adb_android_function_disable(struct android_usb_function *f)
400{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300401 struct android_dev *dev = f->android_dev;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700402 struct adb_data *data = f->config;
403
404 data->enabled = false;
405
406 /* Balance the disable that was called in closed_callback */
407 if (!data->opened)
408 android_enable(dev);
409}
410
Benoit Goby2b6862d2011-12-19 14:38:41 -0800411static struct android_usb_function adb_function = {
412 .name = "adb",
Benoit Goby80ba14d2012-03-19 18:56:52 -0700413 .enable = adb_android_function_enable,
414 .disable = adb_android_function_disable,
Benoit Goby2b6862d2011-12-19 14:38:41 -0800415 .init = adb_function_init,
416 .cleanup = adb_function_cleanup,
417 .bind_config = adb_function_bind_config,
418};
419
Benoit Goby80ba14d2012-03-19 18:56:52 -0700420static void adb_ready_callback(void)
421{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300422 struct android_dev *dev = adb_function.android_dev;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700423 struct adb_data *data = adb_function.config;
424
Benoit Goby80ba14d2012-03-19 18:56:52 -0700425 data->opened = true;
426
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300427 if (data->enabled && dev) {
428 mutex_lock(&dev->mutex);
Benoit Goby80ba14d2012-03-19 18:56:52 -0700429 android_enable(dev);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300430 mutex_unlock(&dev->mutex);
431 }
Benoit Goby80ba14d2012-03-19 18:56:52 -0700432}
433
434static void adb_closed_callback(void)
435{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300436 struct android_dev *dev = adb_function.android_dev;
Benoit Goby80ba14d2012-03-19 18:56:52 -0700437 struct adb_data *data = adb_function.config;
438
Benoit Goby80ba14d2012-03-19 18:56:52 -0700439 data->opened = false;
440
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300441 if (data->enabled) {
442 mutex_lock(&dev->mutex);
Benoit Goby80ba14d2012-03-19 18:56:52 -0700443 android_disable(dev);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300444 mutex_unlock(&dev->mutex);
445 }
Benoit Goby80ba14d2012-03-19 18:56:52 -0700446}
447
Benoit Goby2b6862d2011-12-19 14:38:41 -0800448
Benoit Gobyaab96812011-04-19 20:37:33 -0700449/*-------------------------------------------------------------------------*/
450/* Supported functions initialization */
451
Manu Gautam8e0719b2011-09-26 14:47:55 +0530452/* RMNET_SMD */
Manu Gautam1c8ffd72011-09-02 16:00:49 +0530453static int rmnet_smd_function_bind_config(struct android_usb_function *f,
454 struct usb_configuration *c)
455{
456 return rmnet_smd_bind_config(c);
457}
458
459static struct android_usb_function rmnet_smd_function = {
460 .name = "rmnet_smd",
461 .bind_config = rmnet_smd_function_bind_config,
Benoit Goby1e8ce152011-12-12 13:01:23 -0800462};
463
Manu Gautam8e0719b2011-09-26 14:47:55 +0530464/* RMNET_SDIO */
465static int rmnet_sdio_function_bind_config(struct android_usb_function *f,
466 struct usb_configuration *c)
Benoit Goby1e8ce152011-12-12 13:01:23 -0800467{
Manu Gautam8e0719b2011-09-26 14:47:55 +0530468 return rmnet_sdio_function_add(c);
Benoit Goby1e8ce152011-12-12 13:01:23 -0800469}
470
Manu Gautam8e0719b2011-09-26 14:47:55 +0530471static struct android_usb_function rmnet_sdio_function = {
472 .name = "rmnet_sdio",
473 .bind_config = rmnet_sdio_function_bind_config,
474};
475
476/* RMNET_SMD_SDIO */
477static int rmnet_smd_sdio_function_init(struct android_usb_function *f,
478 struct usb_composite_dev *cdev)
479{
480 return rmnet_smd_sdio_init();
481}
482
483static void rmnet_smd_sdio_function_cleanup(struct android_usb_function *f)
484{
485 rmnet_smd_sdio_cleanup();
486}
487
488static int rmnet_smd_sdio_bind_config(struct android_usb_function *f,
489 struct usb_configuration *c)
490{
491 return rmnet_smd_sdio_function_add(c);
492}
493
494static struct device_attribute *rmnet_smd_sdio_attributes[] = {
495 &dev_attr_transport, NULL };
496
497static struct android_usb_function rmnet_smd_sdio_function = {
498 .name = "rmnet_smd_sdio",
499 .init = rmnet_smd_sdio_function_init,
500 .cleanup = rmnet_smd_sdio_function_cleanup,
501 .bind_config = rmnet_smd_sdio_bind_config,
502 .attributes = rmnet_smd_sdio_attributes,
503};
504
Hemant Kumar1b820d52011-11-03 15:08:28 -0700505/*rmnet transport string format(per port):"ctrl0,data0,ctrl1,data1..." */
506#define MAX_XPORT_STR_LEN 50
507static char rmnet_transports[MAX_XPORT_STR_LEN];
Manu Gautam1c8ffd72011-09-02 16:00:49 +0530508
Hemant Kumar92fe88c2013-02-03 15:56:29 -0800509/*rmnet transport name string - "rmnet_hsic[,rmnet_hsusb]" */
510static char rmnet_xport_names[MAX_XPORT_STR_LEN];
511
Manu Gautame3e897c2011-09-12 17:18:46 +0530512static void rmnet_function_cleanup(struct android_usb_function *f)
513{
514 frmnet_cleanup();
515}
516
Manu Gautam2b0234a2011-09-07 16:47:52 +0530517static int rmnet_function_bind_config(struct android_usb_function *f,
518 struct usb_configuration *c)
519{
520 int i;
Hemant Kumar1b820d52011-11-03 15:08:28 -0700521 int err = 0;
522 char *ctrl_name;
523 char *data_name;
Hemant Kumar92fe88c2013-02-03 15:56:29 -0800524 char *tname = NULL;
Hemant Kumar1b820d52011-11-03 15:08:28 -0700525 char buf[MAX_XPORT_STR_LEN], *b;
Hemant Kumar92fe88c2013-02-03 15:56:29 -0800526 char xport_name_buf[MAX_XPORT_STR_LEN], *tb;
Hemant Kumar1b820d52011-11-03 15:08:28 -0700527 static int rmnet_initialized, ports;
Manu Gautam2b0234a2011-09-07 16:47:52 +0530528
Hemant Kumar1b820d52011-11-03 15:08:28 -0700529 if (!rmnet_initialized) {
530 rmnet_initialized = 1;
531 strlcpy(buf, rmnet_transports, sizeof(buf));
532 b = strim(buf);
Hemant Kumar92fe88c2013-02-03 15:56:29 -0800533
534 strlcpy(xport_name_buf, rmnet_xport_names,
535 sizeof(xport_name_buf));
536 tb = strim(xport_name_buf);
537
Hemant Kumar1b820d52011-11-03 15:08:28 -0700538 while (b) {
539 ctrl_name = strsep(&b, ",");
540 data_name = strsep(&b, ",");
541 if (ctrl_name && data_name) {
Hemant Kumar92fe88c2013-02-03 15:56:29 -0800542 if (tb)
543 tname = strsep(&tb, ",");
544 err = frmnet_init_port(ctrl_name, data_name,
545 tname);
Hemant Kumar1b820d52011-11-03 15:08:28 -0700546 if (err) {
547 pr_err("rmnet: Cannot open ctrl port:"
548 "'%s' data port:'%s'\n",
549 ctrl_name, data_name);
550 goto out;
551 }
552 ports++;
553 }
554 }
555
556 err = rmnet_gport_setup();
557 if (err) {
558 pr_err("rmnet: Cannot setup transports");
559 goto out;
560 }
561 }
562
563 for (i = 0; i < ports; i++) {
564 err = frmnet_bind_config(c, i);
565 if (err) {
Manu Gautam2b0234a2011-09-07 16:47:52 +0530566 pr_err("Could not bind rmnet%u config\n", i);
567 break;
568 }
569 }
Hemant Kumar1b820d52011-11-03 15:08:28 -0700570out:
571 return err;
Manu Gautam2b0234a2011-09-07 16:47:52 +0530572}
573
Hemant Kumar1b820d52011-11-03 15:08:28 -0700574static ssize_t rmnet_transports_show(struct device *dev,
Manu Gautam2b0234a2011-09-07 16:47:52 +0530575 struct device_attribute *attr, char *buf)
576{
Hemant Kumar1b820d52011-11-03 15:08:28 -0700577 return snprintf(buf, PAGE_SIZE, "%s\n", rmnet_transports);
Manu Gautam2b0234a2011-09-07 16:47:52 +0530578}
579
Hemant Kumar1b820d52011-11-03 15:08:28 -0700580static ssize_t rmnet_transports_store(
581 struct device *device, struct device_attribute *attr,
582 const char *buff, size_t size)
Manu Gautam2b0234a2011-09-07 16:47:52 +0530583{
Hemant Kumar1b820d52011-11-03 15:08:28 -0700584 strlcpy(rmnet_transports, buff, sizeof(rmnet_transports));
Manu Gautam2b0234a2011-09-07 16:47:52 +0530585
Manu Gautam2b0234a2011-09-07 16:47:52 +0530586 return size;
587}
588
Hemant Kumar92fe88c2013-02-03 15:56:29 -0800589static ssize_t rmnet_xport_names_show(struct device *dev,
590 struct device_attribute *attr, char *buf)
591{
592 return snprintf(buf, PAGE_SIZE, "%s\n", rmnet_xport_names);
593}
594
595static ssize_t rmnet_xport_names_store(
596 struct device *device, struct device_attribute *attr,
597 const char *buff, size_t size)
598{
599 strlcpy(rmnet_xport_names, buff, sizeof(rmnet_xport_names));
600
601 return size;
602}
603
Hemant Kumar1b820d52011-11-03 15:08:28 -0700604static struct device_attribute dev_attr_rmnet_transports =
605 __ATTR(transports, S_IRUGO | S_IWUSR,
606 rmnet_transports_show,
607 rmnet_transports_store);
Hemant Kumar92fe88c2013-02-03 15:56:29 -0800608
609static struct device_attribute dev_attr_rmnet_xport_names =
610 __ATTR(transport_names, S_IRUGO | S_IWUSR,
611 rmnet_xport_names_show,
612 rmnet_xport_names_store);
613
Manu Gautam2b0234a2011-09-07 16:47:52 +0530614static struct device_attribute *rmnet_function_attributes[] = {
Hemant Kumar1b820d52011-11-03 15:08:28 -0700615 &dev_attr_rmnet_transports,
Hemant Kumar92fe88c2013-02-03 15:56:29 -0800616 &dev_attr_rmnet_xport_names,
Hemant Kumar1b820d52011-11-03 15:08:28 -0700617 NULL };
Manu Gautam2b0234a2011-09-07 16:47:52 +0530618
619static struct android_usb_function rmnet_function = {
620 .name = "rmnet",
Manu Gautame3e897c2011-09-12 17:18:46 +0530621 .cleanup = rmnet_function_cleanup,
Manu Gautam2b0234a2011-09-07 16:47:52 +0530622 .bind_config = rmnet_function_bind_config,
623 .attributes = rmnet_function_attributes,
624};
625
Ofir Cohen7b155422012-07-31 13:02:49 +0300626struct ecm_function_config {
627 u8 ethaddr[ETH_ALEN];
628};
629
630static int ecm_function_init(struct android_usb_function *f,
631 struct usb_composite_dev *cdev)
632{
633 f->config = kzalloc(sizeof(struct ecm_function_config), GFP_KERNEL);
634 if (!f->config)
635 return -ENOMEM;
636 return 0;
637}
638
639static void ecm_function_cleanup(struct android_usb_function *f)
640{
641 kfree(f->config);
642 f->config = NULL;
643}
644
645static int ecm_qc_function_bind_config(struct android_usb_function *f,
646 struct usb_configuration *c)
647{
648 int ret;
649 struct ecm_function_config *ecm = f->config;
650
651 if (!ecm) {
652 pr_err("%s: ecm_pdata\n", __func__);
653 return -EINVAL;
654 }
655
656 pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
657 ecm->ethaddr[0], ecm->ethaddr[1], ecm->ethaddr[2],
658 ecm->ethaddr[3], ecm->ethaddr[4], ecm->ethaddr[5]);
659
660 ret = gether_qc_setup_name(c->cdev->gadget, ecm->ethaddr, "ecm");
661 if (ret) {
662 pr_err("%s: gether_setup failed\n", __func__);
663 return ret;
664 }
665
666 return ecm_qc_bind_config(c, ecm->ethaddr);
667}
668
669static void ecm_qc_function_unbind_config(struct android_usb_function *f,
670 struct usb_configuration *c)
671{
672 gether_qc_cleanup();
673}
674
675static ssize_t ecm_ethaddr_show(struct device *dev,
676 struct device_attribute *attr, char *buf)
677{
678 struct android_usb_function *f = dev_get_drvdata(dev);
679 struct ecm_function_config *ecm = f->config;
680 return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n",
681 ecm->ethaddr[0], ecm->ethaddr[1], ecm->ethaddr[2],
682 ecm->ethaddr[3], ecm->ethaddr[4], ecm->ethaddr[5]);
683}
684
685static ssize_t ecm_ethaddr_store(struct device *dev,
686 struct device_attribute *attr, const char *buf, size_t size)
687{
688 struct android_usb_function *f = dev_get_drvdata(dev);
689 struct ecm_function_config *ecm = f->config;
690
691 if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
692 (int *)&ecm->ethaddr[0], (int *)&ecm->ethaddr[1],
693 (int *)&ecm->ethaddr[2], (int *)&ecm->ethaddr[3],
694 (int *)&ecm->ethaddr[4], (int *)&ecm->ethaddr[5]) == 6)
695 return size;
696 return -EINVAL;
697}
698
699static DEVICE_ATTR(ecm_ethaddr, S_IRUGO | S_IWUSR, ecm_ethaddr_show,
700 ecm_ethaddr_store);
701
702static struct device_attribute *ecm_function_attributes[] = {
703 &dev_attr_ecm_ethaddr,
704 NULL
705};
706
707static struct android_usb_function ecm_qc_function = {
708 .name = "ecm_qc",
709 .init = ecm_function_init,
710 .cleanup = ecm_function_cleanup,
711 .bind_config = ecm_qc_function_bind_config,
712 .unbind_config = ecm_qc_function_unbind_config,
713 .attributes = ecm_function_attributes,
714};
Anna Perela8c991d2012-04-09 16:44:46 +0300715
716/* MBIM - used with BAM */
717#define MAX_MBIM_INSTANCES 1
718
719static int mbim_function_init(struct android_usb_function *f,
720 struct usb_composite_dev *cdev)
721{
722 return mbim_init(MAX_MBIM_INSTANCES);
723}
724
725static void mbim_function_cleanup(struct android_usb_function *f)
726{
727 fmbim_cleanup();
728}
729
730static int mbim_function_bind_config(struct android_usb_function *f,
731 struct usb_configuration *c)
732{
733 return mbim_bind_config(c, 0);
734}
735
736static struct android_usb_function mbim_function = {
737 .name = "usb_mbim",
738 .cleanup = mbim_function_cleanup,
739 .bind_config = mbim_function_bind_config,
740 .init = mbim_function_init,
741};
742
743
Manu Gautam8e0719b2011-09-26 14:47:55 +0530744/* DIAG */
Manu Gautam2b0234a2011-09-07 16:47:52 +0530745static char diag_clients[32]; /*enabled DIAG clients- "diag[,diag_mdm]" */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700746static ssize_t clients_store(
747 struct device *device, struct device_attribute *attr,
748 const char *buff, size_t size)
749{
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +0530750 strlcpy(diag_clients, buff, sizeof(diag_clients));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700751
752 return size;
753}
754
755static DEVICE_ATTR(clients, S_IWUSR, NULL, clients_store);
756static struct device_attribute *diag_function_attributes[] =
757 { &dev_attr_clients, NULL };
758
759static int diag_function_init(struct android_usb_function *f,
760 struct usb_composite_dev *cdev)
761{
762 return diag_setup();
763}
764
765static void diag_function_cleanup(struct android_usb_function *f)
766{
767 diag_cleanup();
768}
769
770static int diag_function_bind_config(struct android_usb_function *f,
771 struct usb_configuration *c)
772{
773 char *name;
774 char buf[32], *b;
Manu Gautamc5760302011-08-25 14:30:24 +0530775 int once = 0, err = -1;
Jack Phamb830a6c2011-12-12 22:35:27 -0800776 int (*notify)(uint32_t, const char *);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300777 struct android_dev *dev = cdev_to_android_dev(c->cdev);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700778
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +0530779 strlcpy(buf, diag_clients, sizeof(buf));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700780 b = strim(buf);
781
782 while (b) {
Jack Phamb830a6c2011-12-12 22:35:27 -0800783 notify = NULL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700784 name = strsep(&b, ",");
Manu Gautamc5760302011-08-25 14:30:24 +0530785 /* Allow only first diag channel to update pid and serial no */
Ido Shayevitz23dc77c2012-07-18 16:16:06 +0300786 if (dev->pdata && !once++)
787 notify = dev->pdata->update_pid_and_serial_num;
Manu Gautamc5760302011-08-25 14:30:24 +0530788
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700789 if (name) {
Manu Gautamc5760302011-08-25 14:30:24 +0530790 err = diag_function_add(c, name, notify);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700791 if (err)
792 pr_err("diag: Cannot open channel '%s'", name);
793 }
794 }
795
796 return err;
797}
798
799static struct android_usb_function diag_function = {
800 .name = "diag",
801 .init = diag_function_init,
802 .cleanup = diag_function_cleanup,
803 .bind_config = diag_function_bind_config,
804 .attributes = diag_function_attributes,
805};
806
Shimrit Malichia00d7322012-08-05 13:56:28 +0300807/* DEBUG */
808static int qdss_function_init(struct android_usb_function *f,
809 struct usb_composite_dev *cdev)
810{
811 return qdss_setup();
812}
813
814static void qdss_function_cleanup(struct android_usb_function *f)
815{
816 qdss_cleanup();
817}
818
819static int qdss_function_bind_config(struct android_usb_function *f,
820 struct usb_configuration *c)
821{
822 int err = -1;
823
824 err = qdss_bind_config(c, "qdss");
825 if (err)
826 pr_err("qdss: Cannot open channel qdss");
827
828 return err;
829}
830
831static struct android_usb_function qdss_function = {
832 .name = "qdss",
833 .init = qdss_function_init,
834 .cleanup = qdss_function_cleanup,
835 .bind_config = qdss_function_bind_config,
836};
837
Manu Gautam8e0719b2011-09-26 14:47:55 +0530838/* SERIAL */
Manu Gautam2b0234a2011-09-07 16:47:52 +0530839static char serial_transports[32]; /*enabled FSERIAL ports - "tty[,sdio]"*/
Manu Gautama4d993f2011-08-30 18:25:55 +0530840static ssize_t serial_transports_store(
841 struct device *device, struct device_attribute *attr,
842 const char *buff, size_t size)
843{
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +0530844 strlcpy(serial_transports, buff, sizeof(serial_transports));
Manu Gautama4d993f2011-08-30 18:25:55 +0530845
846 return size;
847}
848
Hemant Kumar92fe88c2013-02-03 15:56:29 -0800849/*enabled FSERIAL transport names - "serial_hsic[,serial_hsusb]"*/
850static char serial_xport_names[32];
851static ssize_t serial_xport_names_store(
852 struct device *device, struct device_attribute *attr,
853 const char *buff, size_t size)
854{
855 strlcpy(serial_xport_names, buff, sizeof(serial_xport_names));
856
857 return size;
858}
859
860static ssize_t serial_xport_names_show(struct device *dev,
861 struct device_attribute *attr, char *buf)
862{
863 return snprintf(buf, PAGE_SIZE, "%s\n", serial_xport_names);
864}
865
Manu Gautama4d993f2011-08-30 18:25:55 +0530866static DEVICE_ATTR(transports, S_IWUSR, NULL, serial_transports_store);
Hemant Kumar92fe88c2013-02-03 15:56:29 -0800867static struct device_attribute dev_attr_serial_xport_names =
868 __ATTR(transport_names, S_IRUGO | S_IWUSR,
869 serial_xport_names_show,
870 serial_xport_names_store);
871
872static struct device_attribute *serial_function_attributes[] = {
873 &dev_attr_transports,
874 &dev_attr_serial_xport_names,
875 NULL };
Manu Gautama4d993f2011-08-30 18:25:55 +0530876
877static void serial_function_cleanup(struct android_usb_function *f)
878{
879 gserial_cleanup();
880}
881
882static int serial_function_bind_config(struct android_usb_function *f,
883 struct usb_configuration *c)
884{
Hemant Kumar92fe88c2013-02-03 15:56:29 -0800885 char *name, *xport_name = NULL;
886 char buf[32], *b, xport_name_buf[32], *tb;
Manu Gautama4d993f2011-08-30 18:25:55 +0530887 int err = -1, i;
888 static int serial_initialized = 0, ports = 0;
889
890 if (serial_initialized)
891 goto bind_config;
892
893 serial_initialized = 1;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +0530894 strlcpy(buf, serial_transports, sizeof(buf));
Manu Gautama4d993f2011-08-30 18:25:55 +0530895 b = strim(buf);
896
Hemant Kumar92fe88c2013-02-03 15:56:29 -0800897 strlcpy(xport_name_buf, serial_xport_names, sizeof(xport_name_buf));
898 tb = strim(xport_name_buf);
899
Manu Gautama4d993f2011-08-30 18:25:55 +0530900 while (b) {
901 name = strsep(&b, ",");
902
903 if (name) {
Hemant Kumar92fe88c2013-02-03 15:56:29 -0800904 if (tb)
905 xport_name = strsep(&tb, ",");
906 err = gserial_init_port(ports, name, xport_name);
Manu Gautama4d993f2011-08-30 18:25:55 +0530907 if (err) {
908 pr_err("serial: Cannot open port '%s'", name);
909 goto out;
910 }
911 ports++;
912 }
913 }
914 err = gport_setup(c);
915 if (err) {
916 pr_err("serial: Cannot setup transports");
917 goto out;
918 }
919
920bind_config:
Lena Salmand092f2d2012-03-12 17:27:24 +0200921 for (i = 0; i < ports; i++) {
Manu Gautama4d993f2011-08-30 18:25:55 +0530922 err = gser_bind_config(c, i);
923 if (err) {
924 pr_err("serial: bind_config failed for port %d", i);
925 goto out;
926 }
927 }
928
929out:
930 return err;
931}
932
933static struct android_usb_function serial_function = {
934 .name = "serial",
935 .cleanup = serial_function_cleanup,
936 .bind_config = serial_function_bind_config,
937 .attributes = serial_function_attributes,
938};
939
Anji jonnala92be1b42011-12-19 09:44:41 +0530940/* ACM */
941static char acm_transports[32]; /*enabled ACM ports - "tty[,sdio]"*/
942static ssize_t acm_transports_store(
943 struct device *device, struct device_attribute *attr,
944 const char *buff, size_t size)
945{
946 strlcpy(acm_transports, buff, sizeof(acm_transports));
947
948 return size;
949}
950
951static DEVICE_ATTR(acm_transports, S_IWUSR, NULL, acm_transports_store);
952static struct device_attribute *acm_function_attributes[] = {
953 &dev_attr_acm_transports, NULL };
954
Benoit Goby1e8ce152011-12-12 13:01:23 -0800955static void acm_function_cleanup(struct android_usb_function *f)
956{
957 gserial_cleanup();
Benoit Goby1e8ce152011-12-12 13:01:23 -0800958}
959
Anji jonnala92be1b42011-12-19 09:44:41 +0530960static int acm_function_bind_config(struct android_usb_function *f,
961 struct usb_configuration *c)
Benoit Goby1e8ce152011-12-12 13:01:23 -0800962{
Anji jonnala92be1b42011-12-19 09:44:41 +0530963 char *name;
964 char buf[32], *b;
965 int err = -1, i;
966 static int acm_initialized, ports;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800967
Anji jonnala92be1b42011-12-19 09:44:41 +0530968 if (acm_initialized)
969 goto bind_config;
970
971 acm_initialized = 1;
972 strlcpy(buf, acm_transports, sizeof(buf));
973 b = strim(buf);
974
975 while (b) {
976 name = strsep(&b, ",");
977
978 if (name) {
979 err = acm_init_port(ports, name);
980 if (err) {
981 pr_err("acm: Cannot open port '%s'", name);
982 goto out;
983 }
984 ports++;
985 }
986 }
987 err = acm_port_setup(c);
988 if (err) {
989 pr_err("acm: Cannot setup transports");
990 goto out;
991 }
992
993bind_config:
994 for (i = 0; i < ports; i++) {
995 err = acm_bind_config(c, i);
996 if (err) {
997 pr_err("acm: bind_config failed for port %d", i);
998 goto out;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800999 }
1000 }
1001
Anji jonnala92be1b42011-12-19 09:44:41 +05301002out:
1003 return err;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001004}
Benoit Goby1e8ce152011-12-12 13:01:23 -08001005static struct android_usb_function acm_function = {
1006 .name = "acm",
Benoit Goby1e8ce152011-12-12 13:01:23 -08001007 .cleanup = acm_function_cleanup,
1008 .bind_config = acm_function_bind_config,
1009 .attributes = acm_function_attributes,
1010};
1011
Chiranjeevi Velempatie130fd02011-11-29 05:06:13 +05301012/* CCID */
1013static int ccid_function_init(struct android_usb_function *f,
1014 struct usb_composite_dev *cdev)
1015{
1016 return ccid_setup();
1017}
Benoit Goby1e8ce152011-12-12 13:01:23 -08001018
Chiranjeevi Velempatie130fd02011-11-29 05:06:13 +05301019static void ccid_function_cleanup(struct android_usb_function *f)
1020{
1021 ccid_cleanup();
1022}
1023
1024static int ccid_function_bind_config(struct android_usb_function *f,
1025 struct usb_configuration *c)
1026{
1027 return ccid_bind_config(c);
1028}
1029
1030static struct android_usb_function ccid_function = {
1031 .name = "ccid",
1032 .init = ccid_function_init,
1033 .cleanup = ccid_function_cleanup,
1034 .bind_config = ccid_function_bind_config,
1035};
1036
Steve Mucklef132c6c2012-06-06 18:30:57 -07001037static int mtp_function_init(struct android_usb_function *f,
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001038 struct usb_composite_dev *cdev)
1039{
1040 return mtp_setup();
1041}
1042
1043static void mtp_function_cleanup(struct android_usb_function *f)
1044{
1045 mtp_cleanup();
1046}
1047
Steve Mucklef132c6c2012-06-06 18:30:57 -07001048static int mtp_function_bind_config(struct android_usb_function *f,
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001049 struct usb_configuration *c)
1050{
1051 return mtp_bind_config(c, false);
1052}
1053
Mike Lockwoodcf7addf2011-06-01 22:17:36 -04001054static int ptp_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev)
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001055{
1056 /* nothing to do - initialization is handled by mtp_function_init */
1057 return 0;
1058}
1059
1060static void ptp_function_cleanup(struct android_usb_function *f)
1061{
1062 /* nothing to do - cleanup is handled by mtp_function_cleanup */
1063}
1064
Mike Lockwoodcf7addf2011-06-01 22:17:36 -04001065static int ptp_function_bind_config(struct android_usb_function *f, struct usb_configuration *c)
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001066{
1067 return mtp_bind_config(c, true);
1068}
1069
1070static int mtp_function_ctrlrequest(struct android_usb_function *f,
1071 struct usb_composite_dev *cdev,
1072 const struct usb_ctrlrequest *c)
1073{
1074 return mtp_ctrlrequest(cdev, c);
1075}
1076
1077static struct android_usb_function mtp_function = {
1078 .name = "mtp",
1079 .init = mtp_function_init,
1080 .cleanup = mtp_function_cleanup,
1081 .bind_config = mtp_function_bind_config,
1082 .ctrlrequest = mtp_function_ctrlrequest,
1083};
1084
1085/* PTP function is same as MTP with slightly different interface descriptor */
1086static struct android_usb_function ptp_function = {
1087 .name = "ptp",
1088 .init = ptp_function_init,
1089 .cleanup = ptp_function_cleanup,
1090 .bind_config = ptp_function_bind_config,
1091};
1092
Devin Kim0c5b9ce2012-06-19 21:34:44 -07001093#ifdef CONFIG_USB_ANDROID_CDC_ECM
1094struct ecm_function_config {
1095 u8 ethaddr[ETH_ALEN];
1096 u32 vendorID;
1097 char manufacturer[256];
1098};
1099
1100static int ecm_function_init(struct android_usb_function *f,
1101 struct usb_composite_dev *cdev)
1102{
1103 f->config = kzalloc(sizeof(struct ecm_function_config), GFP_KERNEL);
1104 if (!f->config)
1105 return -ENOMEM;
1106 return 0;
1107}
1108
1109static void ecm_function_cleanup(struct android_usb_function *f)
1110{
1111 kfree(f->config);
1112 f->config = NULL;
1113}
1114
1115static int ecm_function_bind_config(struct android_usb_function *f,
1116 struct usb_configuration *c)
1117{
1118 int ret;
1119 struct ecm_function_config *ecm = f->config;
1120
1121 if (!ecm) {
1122 pr_err("%s: ecm_function_config\n", __func__);
1123 return -1;
1124 }
1125
1126 pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
1127 ecm->ethaddr[0], ecm->ethaddr[1], ecm->ethaddr[2],
1128 ecm->ethaddr[3], ecm->ethaddr[4], ecm->ethaddr[5]);
1129
1130 ret = gether_setup_name(c->cdev->gadget, ecm->ethaddr, "usb");
1131 if (ret) {
1132 pr_err("%s: gether_setup failed\n", __func__);
1133 return ret;
1134 }
1135
1136 return ecm_bind_config(c, ecm->ethaddr);
1137}
1138
1139static void ecm_function_unbind_config(struct android_usb_function *f,
1140 struct usb_configuration *c)
1141{
1142 gether_cleanup();
1143}
1144
1145static ssize_t ecm_manufacturer_show(struct device *dev,
1146 struct device_attribute *attr, char *buf)
1147{
1148 struct android_usb_function *f = dev_get_drvdata(dev);
1149 struct ecm_function_config *config = f->config;
1150
1151 return snprintf(buf, PAGE_SIZE, "%s\n", config->manufacturer);
1152}
1153
1154static ssize_t ecm_manufacturer_store(struct device *dev,
1155 struct device_attribute *attr, const char *buf, size_t size)
1156{
1157 struct android_usb_function *f = dev_get_drvdata(dev);
1158 struct ecm_function_config *config = f->config;
1159
1160 if (size >= sizeof(config->manufacturer))
1161 return -EINVAL;
1162
1163 if (sscanf(buf, "%255s", config->manufacturer) == 1)
1164 return size;
1165 return -1;
1166}
1167
1168static DEVICE_ATTR(manufacturer, S_IRUGO | S_IWUSR, ecm_manufacturer_show,
1169 ecm_manufacturer_store);
1170
1171static ssize_t ecm_ethaddr_show(struct device *dev,
1172 struct device_attribute *attr, char *buf)
1173{
1174 struct android_usb_function *f = dev_get_drvdata(dev);
1175 struct ecm_function_config *ecm = f->config;
1176 return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
1177 ecm->ethaddr[0], ecm->ethaddr[1], ecm->ethaddr[2],
1178 ecm->ethaddr[3], ecm->ethaddr[4], ecm->ethaddr[5]);
1179}
1180
1181static ssize_t ecm_ethaddr_store(struct device *dev,
1182 struct device_attribute *attr, const char *buf, size_t size)
1183{
1184 struct android_usb_function *f = dev_get_drvdata(dev);
1185 struct ecm_function_config *ecm = f->config;
1186
1187 if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
1188 (int *)&ecm->ethaddr[0], (int *)&ecm->ethaddr[1],
1189 (int *)&ecm->ethaddr[2], (int *)&ecm->ethaddr[3],
1190 (int *)&ecm->ethaddr[4], (int *)&ecm->ethaddr[5]) == 6)
1191 return size;
1192 return -EINVAL;
1193}
1194
1195static DEVICE_ATTR(ethaddr, S_IRUGO | S_IWUSR, ecm_ethaddr_show,
1196 ecm_ethaddr_store);
1197
1198static ssize_t ecm_vendorID_show(struct device *dev,
1199 struct device_attribute *attr, char *buf)
1200{
1201 struct android_usb_function *f = dev_get_drvdata(dev);
1202 struct ecm_function_config *config = f->config;
1203
1204 return snprintf(buf, PAGE_SIZE, "%04x\n", config->vendorID);
1205}
1206
1207static ssize_t ecm_vendorID_store(struct device *dev,
1208 struct device_attribute *attr, const char *buf, size_t size)
1209{
1210 struct android_usb_function *f = dev_get_drvdata(dev);
1211 struct ecm_function_config *config = f->config;
1212 int value;
1213
1214 if (sscanf(buf, "%04x", &value) == 1) {
1215 config->vendorID = value;
1216 return size;
1217 }
1218 return -EINVAL;
1219}
1220
1221static DEVICE_ATTR(vendorID, S_IRUGO | S_IWUSR, ecm_vendorID_show,
1222 ecm_vendorID_store);
1223
1224static struct device_attribute *ecm_function_attributes[] = {
1225 &dev_attr_manufacturer,
1226 &dev_attr_ethaddr,
1227 &dev_attr_vendorID,
1228 NULL
1229};
1230
1231static struct android_usb_function ecm_function = {
1232 .name = "ecm",
1233 .init = ecm_function_init,
1234 .cleanup = ecm_function_cleanup,
1235 .bind_config = ecm_function_bind_config,
1236 .unbind_config = ecm_function_unbind_config,
1237 .attributes = ecm_function_attributes,
1238};
1239
1240#else
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001241
Benoit Goby1e8ce152011-12-12 13:01:23 -08001242struct rndis_function_config {
1243 u8 ethaddr[ETH_ALEN];
1244 u32 vendorID;
Ofir Cohenaef90b72012-07-31 12:37:04 +02001245 u8 max_pkt_per_xfer;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001246 char manufacturer[256];
1247 /* "Wireless" RNDIS; auto-detected by Windows */
1248 bool wceis;
1249};
1250
1251static int
1252rndis_function_init(struct android_usb_function *f,
1253 struct usb_composite_dev *cdev)
1254{
1255 f->config = kzalloc(sizeof(struct rndis_function_config), GFP_KERNEL);
1256 if (!f->config)
1257 return -ENOMEM;
1258 return 0;
1259}
1260
1261static void rndis_function_cleanup(struct android_usb_function *f)
1262{
1263 kfree(f->config);
1264 f->config = NULL;
1265}
1266
Ofir Cohenaef90b72012-07-31 12:37:04 +02001267static int rndis_qc_function_init(struct android_usb_function *f,
1268 struct usb_composite_dev *cdev)
1269{
1270 f->config = kzalloc(sizeof(struct rndis_function_config), GFP_KERNEL);
1271 if (!f->config)
1272 return -ENOMEM;
1273
1274 return rndis_qc_init();
1275}
1276
1277static void rndis_qc_function_cleanup(struct android_usb_function *f)
1278{
1279 rndis_qc_cleanup();
1280 kfree(f->config);
1281}
1282
Benoit Goby1e8ce152011-12-12 13:01:23 -08001283static int
1284rndis_function_bind_config(struct android_usb_function *f,
1285 struct usb_configuration *c)
1286{
1287 int ret;
1288 struct rndis_function_config *rndis = f->config;
1289
1290 if (!rndis) {
1291 pr_err("%s: rndis_pdata\n", __func__);
1292 return -1;
1293 }
1294
1295 pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
1296 rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
1297 rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
1298
Devin Kim78e07192012-07-17 08:40:54 -07001299 ret = gether_setup_name(c->cdev->gadget, rndis->ethaddr, "usb");
Benoit Goby1e8ce152011-12-12 13:01:23 -08001300 if (ret) {
1301 pr_err("%s: gether_setup failed\n", __func__);
1302 return ret;
1303 }
1304
1305 if (rndis->wceis) {
1306 /* "Wireless" RNDIS; auto-detected by Windows */
1307 rndis_iad_descriptor.bFunctionClass =
1308 USB_CLASS_WIRELESS_CONTROLLER;
1309 rndis_iad_descriptor.bFunctionSubClass = 0x01;
1310 rndis_iad_descriptor.bFunctionProtocol = 0x03;
1311 rndis_control_intf.bInterfaceClass =
1312 USB_CLASS_WIRELESS_CONTROLLER;
1313 rndis_control_intf.bInterfaceSubClass = 0x01;
1314 rndis_control_intf.bInterfaceProtocol = 0x03;
1315 }
1316
1317 return rndis_bind_config_vendor(c, rndis->ethaddr, rndis->vendorID,
1318 rndis->manufacturer);
1319}
1320
Ofir Cohenaef90b72012-07-31 12:37:04 +02001321static int rndis_qc_function_bind_config(struct android_usb_function *f,
1322 struct usb_configuration *c)
1323{
1324 int ret;
1325 struct rndis_function_config *rndis = f->config;
1326
1327 if (!rndis) {
1328 pr_err("%s: rndis_pdata\n", __func__);
1329 return -EINVAL;
1330 }
1331
1332 pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
1333 rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
1334 rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
1335
1336 ret = gether_qc_setup_name(c->cdev->gadget, rndis->ethaddr, "rndis");
1337 if (ret) {
1338 pr_err("%s: gether_setup failed\n", __func__);
1339 return ret;
1340 }
1341
1342 if (rndis->wceis) {
1343 /* "Wireless" RNDIS; auto-detected by Windows */
1344 rndis_qc_iad_descriptor.bFunctionClass =
1345 USB_CLASS_WIRELESS_CONTROLLER;
1346 rndis_qc_iad_descriptor.bFunctionSubClass = 0x01;
1347 rndis_qc_iad_descriptor.bFunctionProtocol = 0x03;
1348 rndis_qc_control_intf.bInterfaceClass =
1349 USB_CLASS_WIRELESS_CONTROLLER;
1350 rndis_qc_control_intf.bInterfaceSubClass = 0x01;
1351 rndis_qc_control_intf.bInterfaceProtocol = 0x03;
1352 }
1353
1354 return rndis_qc_bind_config_vendor(c, rndis->ethaddr, rndis->vendorID,
1355 rndis->manufacturer,
1356 rndis->max_pkt_per_xfer);
1357}
1358
Benoit Goby1e8ce152011-12-12 13:01:23 -08001359static void rndis_function_unbind_config(struct android_usb_function *f,
1360 struct usb_configuration *c)
1361{
1362 gether_cleanup();
1363}
1364
Ofir Cohenaef90b72012-07-31 12:37:04 +02001365static void rndis_qc_function_unbind_config(struct android_usb_function *f,
1366 struct usb_configuration *c)
1367{
1368 gether_qc_cleanup();
1369}
1370
Benoit Goby1e8ce152011-12-12 13:01:23 -08001371static ssize_t rndis_manufacturer_show(struct device *dev,
1372 struct device_attribute *attr, char *buf)
1373{
1374 struct android_usb_function *f = dev_get_drvdata(dev);
1375 struct rndis_function_config *config = f->config;
Steve Mucklef132c6c2012-06-06 18:30:57 -07001376
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301377 return snprintf(buf, PAGE_SIZE, "%s\n", config->manufacturer);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001378}
1379
1380static ssize_t rndis_manufacturer_store(struct device *dev,
1381 struct device_attribute *attr, const char *buf, size_t size)
1382{
1383 struct android_usb_function *f = dev_get_drvdata(dev);
1384 struct rndis_function_config *config = f->config;
1385
1386 if (size >= sizeof(config->manufacturer))
1387 return -EINVAL;
Steve Mucklef132c6c2012-06-06 18:30:57 -07001388
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301389 if (sscanf(buf, "%255s", config->manufacturer) == 1)
Benoit Goby1e8ce152011-12-12 13:01:23 -08001390 return size;
1391 return -1;
1392}
1393
1394static DEVICE_ATTR(manufacturer, S_IRUGO | S_IWUSR, rndis_manufacturer_show,
1395 rndis_manufacturer_store);
1396
1397static ssize_t rndis_wceis_show(struct device *dev,
1398 struct device_attribute *attr, char *buf)
1399{
1400 struct android_usb_function *f = dev_get_drvdata(dev);
1401 struct rndis_function_config *config = f->config;
Steve Mucklef132c6c2012-06-06 18:30:57 -07001402
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301403 return snprintf(buf, PAGE_SIZE, "%d\n", config->wceis);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001404}
1405
1406static ssize_t rndis_wceis_store(struct device *dev,
1407 struct device_attribute *attr, const char *buf, size_t size)
1408{
1409 struct android_usb_function *f = dev_get_drvdata(dev);
1410 struct rndis_function_config *config = f->config;
1411 int value;
1412
1413 if (sscanf(buf, "%d", &value) == 1) {
1414 config->wceis = value;
1415 return size;
1416 }
1417 return -EINVAL;
1418}
1419
1420static DEVICE_ATTR(wceis, S_IRUGO | S_IWUSR, rndis_wceis_show,
1421 rndis_wceis_store);
1422
1423static ssize_t rndis_ethaddr_show(struct device *dev,
1424 struct device_attribute *attr, char *buf)
1425{
1426 struct android_usb_function *f = dev_get_drvdata(dev);
1427 struct rndis_function_config *rndis = f->config;
Steve Mucklef132c6c2012-06-06 18:30:57 -07001428
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301429 return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n",
Benoit Goby1e8ce152011-12-12 13:01:23 -08001430 rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
1431 rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
1432}
1433
1434static ssize_t rndis_ethaddr_store(struct device *dev,
1435 struct device_attribute *attr, const char *buf, size_t size)
1436{
1437 struct android_usb_function *f = dev_get_drvdata(dev);
1438 struct rndis_function_config *rndis = f->config;
1439
1440 if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
1441 (int *)&rndis->ethaddr[0], (int *)&rndis->ethaddr[1],
1442 (int *)&rndis->ethaddr[2], (int *)&rndis->ethaddr[3],
1443 (int *)&rndis->ethaddr[4], (int *)&rndis->ethaddr[5]) == 6)
1444 return size;
1445 return -EINVAL;
1446}
1447
1448static DEVICE_ATTR(ethaddr, S_IRUGO | S_IWUSR, rndis_ethaddr_show,
1449 rndis_ethaddr_store);
1450
1451static ssize_t rndis_vendorID_show(struct device *dev,
1452 struct device_attribute *attr, char *buf)
1453{
1454 struct android_usb_function *f = dev_get_drvdata(dev);
1455 struct rndis_function_config *config = f->config;
Steve Mucklef132c6c2012-06-06 18:30:57 -07001456
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301457 return snprintf(buf, PAGE_SIZE, "%04x\n", config->vendorID);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001458}
1459
1460static ssize_t rndis_vendorID_store(struct device *dev,
1461 struct device_attribute *attr, const char *buf, size_t size)
1462{
1463 struct android_usb_function *f = dev_get_drvdata(dev);
1464 struct rndis_function_config *config = f->config;
1465 int value;
1466
1467 if (sscanf(buf, "%04x", &value) == 1) {
1468 config->vendorID = value;
1469 return size;
1470 }
1471 return -EINVAL;
1472}
1473
1474static DEVICE_ATTR(vendorID, S_IRUGO | S_IWUSR, rndis_vendorID_show,
1475 rndis_vendorID_store);
1476
Ofir Cohenaef90b72012-07-31 12:37:04 +02001477static ssize_t rndis_max_pkt_per_xfer_show(struct device *dev,
1478 struct device_attribute *attr, char *buf)
1479{
1480 struct android_usb_function *f = dev_get_drvdata(dev);
1481 struct rndis_function_config *config = f->config;
1482 return snprintf(buf, PAGE_SIZE, "%d\n", config->max_pkt_per_xfer);
1483}
1484
1485static ssize_t rndis_max_pkt_per_xfer_store(struct device *dev,
1486 struct device_attribute *attr, const char *buf, size_t size)
1487{
1488 struct android_usb_function *f = dev_get_drvdata(dev);
1489 struct rndis_function_config *config = f->config;
1490 int value;
1491
1492 if (sscanf(buf, "%d", &value) == 1) {
1493 config->max_pkt_per_xfer = value;
1494 return size;
1495 }
1496 return -EINVAL;
1497}
1498
1499static DEVICE_ATTR(max_pkt_per_xfer, S_IRUGO | S_IWUSR,
1500 rndis_max_pkt_per_xfer_show,
1501 rndis_max_pkt_per_xfer_store);
1502
Benoit Goby1e8ce152011-12-12 13:01:23 -08001503static struct device_attribute *rndis_function_attributes[] = {
1504 &dev_attr_manufacturer,
1505 &dev_attr_wceis,
1506 &dev_attr_ethaddr,
1507 &dev_attr_vendorID,
Ofir Cohenaef90b72012-07-31 12:37:04 +02001508 &dev_attr_max_pkt_per_xfer,
Benoit Goby1e8ce152011-12-12 13:01:23 -08001509 NULL
1510};
1511
1512static struct android_usb_function rndis_function = {
1513 .name = "rndis",
1514 .init = rndis_function_init,
1515 .cleanup = rndis_function_cleanup,
1516 .bind_config = rndis_function_bind_config,
1517 .unbind_config = rndis_function_unbind_config,
1518 .attributes = rndis_function_attributes,
1519};
Devin Kim0c5b9ce2012-06-19 21:34:44 -07001520#endif /* CONFIG_USB_ANDROID_CDC_ECM */
Benoit Goby1e8ce152011-12-12 13:01:23 -08001521
Ofir Cohenaef90b72012-07-31 12:37:04 +02001522static struct android_usb_function rndis_qc_function = {
1523 .name = "rndis_qc",
1524 .init = rndis_qc_function_init,
1525 .cleanup = rndis_qc_function_cleanup,
1526 .bind_config = rndis_qc_function_bind_config,
1527 .unbind_config = rndis_qc_function_unbind_config,
1528 .attributes = rndis_function_attributes,
1529};
Benoit Goby1e8ce152011-12-12 13:01:23 -08001530
1531struct mass_storage_function_config {
1532 struct fsg_config fsg;
1533 struct fsg_common *common;
1534};
1535
1536static int mass_storage_function_init(struct android_usb_function *f,
1537 struct usb_composite_dev *cdev)
1538{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001539 struct android_dev *dev = cdev_to_android_dev(cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001540 struct mass_storage_function_config *config;
1541 struct fsg_common *common;
1542 int err;
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301543 int i;
1544 const char *name[2];
Benoit Goby1e8ce152011-12-12 13:01:23 -08001545
1546 config = kzalloc(sizeof(struct mass_storage_function_config),
1547 GFP_KERNEL);
1548 if (!config)
1549 return -ENOMEM;
1550
1551 config->fsg.nluns = 1;
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301552 name[0] = "lun";
Pavankumar Kondeti2043e302012-07-19 08:54:04 +05301553 if (dev->pdata && dev->pdata->cdrom) {
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301554 config->fsg.nluns = 2;
1555 config->fsg.luns[1].cdrom = 1;
1556 config->fsg.luns[1].ro = 1;
1557 config->fsg.luns[1].removable = 1;
1558 name[1] = "lun0";
1559 }
1560
Benoit Goby1e8ce152011-12-12 13:01:23 -08001561 config->fsg.luns[0].removable = 1;
1562
1563 common = fsg_common_init(NULL, cdev, &config->fsg);
1564 if (IS_ERR(common)) {
1565 kfree(config);
1566 return PTR_ERR(common);
1567 }
1568
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301569 for (i = 0; i < config->fsg.nluns; i++) {
1570 err = sysfs_create_link(&f->dev->kobj,
1571 &common->luns[i].dev.kobj,
1572 name[i]);
1573 if (err)
1574 goto error;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001575 }
1576
1577 config->common = common;
1578 f->config = config;
1579 return 0;
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301580error:
1581 for (; i > 0 ; i--)
1582 sysfs_remove_link(&f->dev->kobj, name[i-1]);
1583
1584 fsg_common_release(&common->ref);
1585 kfree(config);
1586 return err;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001587}
1588
1589static void mass_storage_function_cleanup(struct android_usb_function *f)
1590{
1591 kfree(f->config);
1592 f->config = NULL;
1593}
1594
1595static int mass_storage_function_bind_config(struct android_usb_function *f,
1596 struct usb_configuration *c)
1597{
1598 struct mass_storage_function_config *config = f->config;
1599 return fsg_bind_config(c->cdev, c, config->common);
1600}
1601
1602static ssize_t mass_storage_inquiry_show(struct device *dev,
1603 struct device_attribute *attr, char *buf)
1604{
1605 struct android_usb_function *f = dev_get_drvdata(dev);
1606 struct mass_storage_function_config *config = f->config;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301607 return snprintf(buf, PAGE_SIZE, "%s\n", config->common->inquiry_string);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001608}
1609
1610static ssize_t mass_storage_inquiry_store(struct device *dev,
1611 struct device_attribute *attr, const char *buf, size_t size)
1612{
1613 struct android_usb_function *f = dev_get_drvdata(dev);
1614 struct mass_storage_function_config *config = f->config;
1615 if (size >= sizeof(config->common->inquiry_string))
1616 return -EINVAL;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301617 if (sscanf(buf, "%28s", config->common->inquiry_string) != 1)
Benoit Goby1e8ce152011-12-12 13:01:23 -08001618 return -EINVAL;
1619 return size;
1620}
1621
1622static DEVICE_ATTR(inquiry_string, S_IRUGO | S_IWUSR,
1623 mass_storage_inquiry_show,
1624 mass_storage_inquiry_store);
1625
1626static struct device_attribute *mass_storage_function_attributes[] = {
1627 &dev_attr_inquiry_string,
1628 NULL
1629};
1630
1631static struct android_usb_function mass_storage_function = {
1632 .name = "mass_storage",
1633 .init = mass_storage_function_init,
1634 .cleanup = mass_storage_function_cleanup,
1635 .bind_config = mass_storage_function_bind_config,
1636 .attributes = mass_storage_function_attributes,
1637};
1638
1639
Benoit Gobycf3fc062011-12-19 14:39:37 -08001640static int accessory_function_init(struct android_usb_function *f,
1641 struct usb_composite_dev *cdev)
1642{
1643 return acc_setup();
1644}
1645
1646static void accessory_function_cleanup(struct android_usb_function *f)
1647{
1648 acc_cleanup();
1649}
1650
1651static int accessory_function_bind_config(struct android_usb_function *f,
1652 struct usb_configuration *c)
1653{
1654 return acc_bind_config(c);
1655}
1656
1657static int accessory_function_ctrlrequest(struct android_usb_function *f,
1658 struct usb_composite_dev *cdev,
1659 const struct usb_ctrlrequest *c)
1660{
1661 return acc_ctrlrequest(cdev, c);
1662}
1663
1664static struct android_usb_function accessory_function = {
1665 .name = "accessory",
1666 .init = accessory_function_init,
1667 .cleanup = accessory_function_cleanup,
1668 .bind_config = accessory_function_bind_config,
1669 .ctrlrequest = accessory_function_ctrlrequest,
1670};
1671
Ajay Dudani34b1e302012-08-27 16:43:53 +05301672static int audio_source_function_init(struct android_usb_function *f,
1673 struct usb_composite_dev *cdev)
1674{
1675 struct audio_source_config *config;
1676
1677 config = kzalloc(sizeof(struct audio_source_config), GFP_KERNEL);
1678 if (!config)
1679 return -ENOMEM;
1680 config->card = -1;
1681 config->device = -1;
1682 f->config = config;
1683 return 0;
1684}
1685
1686static void audio_source_function_cleanup(struct android_usb_function *f)
1687{
1688 kfree(f->config);
1689}
1690
1691static int audio_source_function_bind_config(struct android_usb_function *f,
1692 struct usb_configuration *c)
1693{
1694 struct audio_source_config *config = f->config;
1695
1696 return audio_source_bind_config(c, config);
1697}
1698
1699static void audio_source_function_unbind_config(struct android_usb_function *f,
1700 struct usb_configuration *c)
1701{
1702 struct audio_source_config *config = f->config;
1703
1704 config->card = -1;
1705 config->device = -1;
1706}
1707
1708static ssize_t audio_source_pcm_show(struct device *dev,
1709 struct device_attribute *attr, char *buf)
1710{
1711 struct android_usb_function *f = dev_get_drvdata(dev);
1712 struct audio_source_config *config = f->config;
1713
1714 /* print PCM card and device numbers */
1715 return sprintf(buf, "%d %d\n", config->card, config->device);
1716}
1717
1718static DEVICE_ATTR(pcm, S_IRUGO | S_IWUSR, audio_source_pcm_show, NULL);
1719
1720static struct device_attribute *audio_source_function_attributes[] = {
1721 &dev_attr_pcm,
1722 NULL
1723};
1724
1725static struct android_usb_function audio_source_function = {
1726 .name = "audio_source",
1727 .init = audio_source_function_init,
1728 .cleanup = audio_source_function_cleanup,
1729 .bind_config = audio_source_function_bind_config,
1730 .unbind_config = audio_source_function_unbind_config,
1731 .attributes = audio_source_function_attributes,
1732};
1733
Pavankumar Kondeti8f6ca4f2012-06-26 09:44:36 +05301734static int android_uasp_connect_cb(bool connect)
1735{
1736 /*
1737 * TODO
1738 * We may have to disable gadget till UASP configfs nodes
1739 * are configured which includes mapping LUN with the
1740 * backing file. It is a fundamental difference between
1741 * f_mass_storage and f_tcp. That means UASP can not be
1742 * in default composition.
1743 *
1744 * For now, assume that UASP configfs nodes are configured
1745 * before enabling android gadget. Or cable should be
1746 * reconnected after mapping the LUN.
1747 *
1748 * Also consider making UASP to respond to Host requests when
1749 * Lun is not mapped.
1750 */
1751 pr_debug("UASP %s\n", connect ? "connect" : "disconnect");
1752
1753 return 0;
1754}
1755
1756static int uasp_function_init(struct android_usb_function *f,
1757 struct usb_composite_dev *cdev)
1758{
1759 return f_tcm_init(&android_uasp_connect_cb);
1760}
1761
1762static void uasp_function_cleanup(struct android_usb_function *f)
1763{
1764 f_tcm_exit();
1765}
1766
1767static int uasp_function_bind_config(struct android_usb_function *f,
1768 struct usb_configuration *c)
1769{
1770 return tcm_bind_config(c);
1771}
1772
1773static struct android_usb_function uasp_function = {
1774 .name = "uasp",
1775 .init = uasp_function_init,
1776 .cleanup = uasp_function_cleanup,
1777 .bind_config = uasp_function_bind_config,
1778};
Benoit Gobycf3fc062011-12-19 14:39:37 -08001779
Benoit Goby1e8ce152011-12-12 13:01:23 -08001780static struct android_usb_function *supported_functions[] = {
Anna Perela8c991d2012-04-09 16:44:46 +03001781 &mbim_function,
Ofir Cohen7b155422012-07-31 13:02:49 +03001782 &ecm_qc_function,
Manu Gautam1c8ffd72011-09-02 16:00:49 +05301783 &rmnet_smd_function,
Manu Gautam8e0719b2011-09-26 14:47:55 +05301784 &rmnet_sdio_function,
1785 &rmnet_smd_sdio_function,
Manu Gautam2b0234a2011-09-07 16:47:52 +05301786 &rmnet_function,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001787 &diag_function,
Shimrit Malichia00d7322012-08-05 13:56:28 +03001788 &qdss_function,
Manu Gautama4d993f2011-08-30 18:25:55 +05301789 &serial_function,
Benoit Goby2b6862d2011-12-19 14:38:41 -08001790 &adb_function,
Chiranjeevi Velempatie130fd02011-11-29 05:06:13 +05301791 &ccid_function,
Benoit Goby1e8ce152011-12-12 13:01:23 -08001792 &acm_function,
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001793 &mtp_function,
1794 &ptp_function,
Devin Kim0c5b9ce2012-06-19 21:34:44 -07001795#ifdef CONFIG_USB_ANDROID_CDC_ECM
1796 &ecm_function,
1797#else
Benoit Goby1e8ce152011-12-12 13:01:23 -08001798 &rndis_function,
Devin Kim0c5b9ce2012-06-19 21:34:44 -07001799#endif
Ofir Cohenaef90b72012-07-31 12:37:04 +02001800 &rndis_qc_function,
Benoit Goby1e8ce152011-12-12 13:01:23 -08001801 &mass_storage_function,
Benoit Gobycf3fc062011-12-19 14:39:37 -08001802 &accessory_function,
Ajay Dudani34b1e302012-08-27 16:43:53 +05301803 &audio_source_function,
Pavankumar Kondeti8f6ca4f2012-06-26 09:44:36 +05301804 &uasp_function,
Benoit Goby1e8ce152011-12-12 13:01:23 -08001805 NULL
1806};
1807
Lena Salmand092f2d2012-03-12 17:27:24 +02001808static void android_cleanup_functions(struct android_usb_function **functions)
1809{
1810 struct android_usb_function *f;
1811 struct device_attribute **attrs;
1812 struct device_attribute *attr;
1813
1814 while (*functions) {
1815 f = *functions++;
1816
1817 if (f->dev) {
1818 device_destroy(android_class, f->dev->devt);
1819 kfree(f->dev_name);
1820 } else
1821 continue;
1822
1823 if (f->cleanup)
1824 f->cleanup(f);
1825
1826 attrs = f->attributes;
1827 if (attrs) {
1828 while ((attr = *attrs++))
1829 device_remove_file(f->dev, attr);
1830 }
1831 }
1832}
Benoit Goby1e8ce152011-12-12 13:01:23 -08001833
1834static int android_init_functions(struct android_usb_function **functions,
1835 struct usb_composite_dev *cdev)
1836{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001837 struct android_dev *dev = cdev_to_android_dev(cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001838 struct android_usb_function *f;
1839 struct device_attribute **attrs;
1840 struct device_attribute *attr;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301841 int err = 0;
Lena Salmand092f2d2012-03-12 17:27:24 +02001842 int index = 1; /* index 0 is for android0 device */
Benoit Goby1e8ce152011-12-12 13:01:23 -08001843
1844 for (; (f = *functions++); index++) {
1845 f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001846 f->android_dev = NULL;
Lena Salmand092f2d2012-03-12 17:27:24 +02001847 if (!f->dev_name) {
1848 err = -ENOMEM;
1849 goto err_out;
1850 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08001851 f->dev = device_create(android_class, dev->dev,
1852 MKDEV(0, index), f, f->dev_name);
1853 if (IS_ERR(f->dev)) {
1854 pr_err("%s: Failed to create dev %s", __func__,
1855 f->dev_name);
1856 err = PTR_ERR(f->dev);
Lena Salmand092f2d2012-03-12 17:27:24 +02001857 f->dev = NULL;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001858 goto err_create;
1859 }
1860
1861 if (f->init) {
1862 err = f->init(f, cdev);
1863 if (err) {
1864 pr_err("%s: Failed to init %s", __func__,
1865 f->name);
Lena Salmand092f2d2012-03-12 17:27:24 +02001866 goto err_init;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001867 }
1868 }
1869
1870 attrs = f->attributes;
1871 if (attrs) {
1872 while ((attr = *attrs++) && !err)
1873 err = device_create_file(f->dev, attr);
1874 }
1875 if (err) {
1876 pr_err("%s: Failed to create function %s attributes",
1877 __func__, f->name);
Lena Salmand092f2d2012-03-12 17:27:24 +02001878 goto err_attrs;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001879 }
1880 }
1881 return 0;
1882
Lena Salmand092f2d2012-03-12 17:27:24 +02001883err_attrs:
1884 for (attr = *(attrs -= 2); attrs != f->attributes; attr = *(attrs--))
1885 device_remove_file(f->dev, attr);
1886 if (f->cleanup)
1887 f->cleanup(f);
1888err_init:
Benoit Goby1e8ce152011-12-12 13:01:23 -08001889 device_destroy(android_class, f->dev->devt);
1890err_create:
Lena Salmand092f2d2012-03-12 17:27:24 +02001891 f->dev = NULL;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001892 kfree(f->dev_name);
Lena Salmand092f2d2012-03-12 17:27:24 +02001893err_out:
1894 android_cleanup_functions(dev->functions);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001895 return err;
1896}
1897
Benoit Goby1e8ce152011-12-12 13:01:23 -08001898static int
1899android_bind_enabled_functions(struct android_dev *dev,
1900 struct usb_configuration *c)
1901{
1902 struct android_usb_function *f;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001903 struct android_configuration *conf =
1904 container_of(c, struct android_configuration, usb_config);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001905 int ret;
1906
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001907 list_for_each_entry(f, &conf->enabled_functions, enabled_list) {
Benoit Goby1e8ce152011-12-12 13:01:23 -08001908 ret = f->bind_config(f, c);
1909 if (ret) {
1910 pr_err("%s: %s failed", __func__, f->name);
1911 return ret;
1912 }
1913 }
1914 return 0;
1915}
1916
1917static void
1918android_unbind_enabled_functions(struct android_dev *dev,
1919 struct usb_configuration *c)
1920{
1921 struct android_usb_function *f;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001922 struct android_configuration *conf =
1923 container_of(c, struct android_configuration, usb_config);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001924
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001925 list_for_each_entry(f, &conf->enabled_functions, enabled_list) {
Benoit Goby1e8ce152011-12-12 13:01:23 -08001926 if (f->unbind_config)
1927 f->unbind_config(f, c);
1928 }
1929}
1930
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001931static int android_enable_function(struct android_dev *dev,
1932 struct android_configuration *conf,
1933 char *name)
Benoit Goby1e8ce152011-12-12 13:01:23 -08001934{
1935 struct android_usb_function **functions = dev->functions;
1936 struct android_usb_function *f;
1937 while ((f = *functions++)) {
1938 if (!strcmp(name, f->name)) {
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001939 if (f->android_dev)
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001940 pr_err("%s already enabled in other " \
1941 "configuration or device\n",
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001942 f->name);
1943 else {
1944 list_add_tail(&f->enabled_list,
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001945 &conf->enabled_functions);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001946 f->android_dev = dev;
1947 return 0;
1948 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08001949 }
1950 }
1951 return -EINVAL;
1952}
1953
1954/*-------------------------------------------------------------------------*/
1955/* /sys/class/android_usb/android%d/ interface */
1956
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05301957static ssize_t remote_wakeup_show(struct device *pdev,
1958 struct device_attribute *attr, char *buf)
1959{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001960 struct android_dev *dev = dev_get_drvdata(pdev);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001961 struct android_configuration *conf;
1962
1963 /*
1964 * Show the wakeup attribute of the first configuration,
1965 * since all configurations have the same wakeup attribute
1966 */
1967 if (dev->configs_num == 0)
1968 return 0;
1969 conf = list_entry(dev->configs.next,
1970 struct android_configuration,
1971 list_item);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001972
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05301973 return snprintf(buf, PAGE_SIZE, "%d\n",
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001974 !!(conf->usb_config.bmAttributes &
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05301975 USB_CONFIG_ATT_WAKEUP));
1976}
1977
1978static ssize_t remote_wakeup_store(struct device *pdev,
1979 struct device_attribute *attr, const char *buff, size_t size)
1980{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001981 struct android_dev *dev = dev_get_drvdata(pdev);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001982 struct android_configuration *conf;
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05301983 int enable = 0;
1984
1985 sscanf(buff, "%d", &enable);
1986
1987 pr_debug("android_usb: %s remote wakeup\n",
1988 enable ? "enabling" : "disabling");
1989
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001990 list_for_each_entry(conf, &dev->configs, list_item)
1991 if (enable)
1992 conf->usb_config.bmAttributes |=
1993 USB_CONFIG_ATT_WAKEUP;
1994 else
1995 conf->usb_config.bmAttributes &=
1996 ~USB_CONFIG_ATT_WAKEUP;
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05301997
1998 return size;
1999}
2000
Benoit Goby1e8ce152011-12-12 13:01:23 -08002001static ssize_t
2002functions_show(struct device *pdev, struct device_attribute *attr, char *buf)
2003{
2004 struct android_dev *dev = dev_get_drvdata(pdev);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002005 struct android_configuration *conf;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002006 struct android_usb_function *f;
2007 char *buff = buf;
2008
2009 mutex_lock(&dev->mutex);
2010
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002011 list_for_each_entry(conf, &dev->configs, list_item) {
2012 if (buff != buf)
2013 *(buff-1) = ':';
2014 list_for_each_entry(f, &conf->enabled_functions, enabled_list)
2015 buff += snprintf(buff, PAGE_SIZE, "%s,", f->name);
2016 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002017
2018 mutex_unlock(&dev->mutex);
2019
2020 if (buff != buf)
2021 *(buff-1) = '\n';
2022 return buff - buf;
2023}
2024
2025static ssize_t
2026functions_store(struct device *pdev, struct device_attribute *attr,
2027 const char *buff, size_t size)
2028{
2029 struct android_dev *dev = dev_get_drvdata(pdev);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002030 struct android_usb_function *f;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002031 struct list_head *curr_conf = &dev->configs;
2032 struct android_configuration *conf;
2033 char *conf_str;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002034 char *name;
2035 char buf[256], *b;
2036 int err;
2037
2038 mutex_lock(&dev->mutex);
2039
2040 if (dev->enabled) {
2041 mutex_unlock(&dev->mutex);
2042 return -EBUSY;
2043 }
2044
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002045 /* Clear previous enabled list */
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002046 list_for_each_entry(conf, &dev->configs, list_item) {
2047 list_for_each_entry(f, &conf->enabled_functions, enabled_list)
2048 f->android_dev = NULL;
2049 INIT_LIST_HEAD(&conf->enabled_functions);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002050 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002051
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302052 strlcpy(buf, buff, sizeof(buf));
Benoit Goby1e8ce152011-12-12 13:01:23 -08002053 b = strim(buf);
2054
2055 while (b) {
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002056 conf_str = strsep(&b, ":");
2057 if (conf_str) {
2058 /* If the next not equal to the head, take it */
2059 if (curr_conf->next != &dev->configs)
2060 conf = list_entry(curr_conf->next,
2061 struct android_configuration,
2062 list_item);
2063 else
2064 conf = alloc_android_config(dev);
2065
2066 curr_conf = curr_conf->next;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002067 }
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002068
2069 while (conf_str) {
2070 name = strsep(&conf_str, ",");
2071 if (name) {
2072 err = android_enable_function(dev, conf, name);
2073 if (err)
2074 pr_err("android_usb: Cannot enable %s",
2075 name);
2076 }
2077 }
2078 }
2079
2080 /* Free uneeded configurations if exists */
2081 while (curr_conf->next != &dev->configs) {
2082 conf = list_entry(curr_conf->next,
2083 struct android_configuration, list_item);
2084 free_android_config(dev, conf);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002085 }
2086
2087 mutex_unlock(&dev->mutex);
2088
2089 return size;
2090}
2091
2092static ssize_t enable_show(struct device *pdev, struct device_attribute *attr,
2093 char *buf)
2094{
2095 struct android_dev *dev = dev_get_drvdata(pdev);
Steve Mucklef132c6c2012-06-06 18:30:57 -07002096
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302097 return snprintf(buf, PAGE_SIZE, "%d\n", dev->enabled);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002098}
2099
2100static ssize_t enable_store(struct device *pdev, struct device_attribute *attr,
2101 const char *buff, size_t size)
2102{
2103 struct android_dev *dev = dev_get_drvdata(pdev);
2104 struct usb_composite_dev *cdev = dev->cdev;
Benoit Goby80ba14d2012-03-19 18:56:52 -07002105 struct android_usb_function *f;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002106 struct android_configuration *conf;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002107 int enabled = 0;
2108
Benoit Gobycf3fc062011-12-19 14:39:37 -08002109 if (!cdev)
2110 return -ENODEV;
2111
Benoit Goby1e8ce152011-12-12 13:01:23 -08002112 mutex_lock(&dev->mutex);
2113
2114 sscanf(buff, "%d", &enabled);
2115 if (enabled && !dev->enabled) {
Benoit Goby1e8ce152011-12-12 13:01:23 -08002116 /*
2117 * Update values in composite driver's copy of
2118 * device descriptor.
2119 */
2120 cdev->desc.idVendor = device_desc.idVendor;
2121 cdev->desc.idProduct = device_desc.idProduct;
2122 cdev->desc.bcdDevice = device_desc.bcdDevice;
2123 cdev->desc.bDeviceClass = device_desc.bDeviceClass;
2124 cdev->desc.bDeviceSubClass = device_desc.bDeviceSubClass;
2125 cdev->desc.bDeviceProtocol = device_desc.bDeviceProtocol;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002126 list_for_each_entry(conf, &dev->configs, list_item)
2127 list_for_each_entry(f, &conf->enabled_functions,
2128 enabled_list) {
2129 if (f->enable)
2130 f->enable(f);
2131 }
Benoit Goby80ba14d2012-03-19 18:56:52 -07002132 android_enable(dev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002133 dev->enabled = true;
2134 } else if (!enabled && dev->enabled) {
Benoit Goby80ba14d2012-03-19 18:56:52 -07002135 android_disable(dev);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002136 list_for_each_entry(conf, &dev->configs, list_item)
2137 list_for_each_entry(f, &conf->enabled_functions,
2138 enabled_list) {
2139 if (f->disable)
2140 f->disable(f);
2141 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002142 dev->enabled = false;
2143 } else {
2144 pr_err("android_usb: already %s\n",
2145 dev->enabled ? "enabled" : "disabled");
2146 }
2147
2148 mutex_unlock(&dev->mutex);
Steve Mucklef132c6c2012-06-06 18:30:57 -07002149
Benoit Gobyaab96812011-04-19 20:37:33 -07002150 return size;
2151}
2152
Ofir Cohen94213a72012-05-03 14:26:32 +03002153static ssize_t pm_qos_show(struct device *pdev,
2154 struct device_attribute *attr, char *buf)
2155{
2156 struct android_dev *dev = dev_get_drvdata(pdev);
2157
2158 return snprintf(buf, PAGE_SIZE, "%s\n", dev->pm_qos);
2159}
2160
2161static ssize_t pm_qos_store(struct device *pdev,
2162 struct device_attribute *attr,
2163 const char *buff, size_t size)
2164{
2165 struct android_dev *dev = dev_get_drvdata(pdev);
2166
2167 strlcpy(dev->pm_qos, buff, sizeof(dev->pm_qos));
2168
Benoit Goby1e8ce152011-12-12 13:01:23 -08002169 return size;
2170}
2171
2172static ssize_t state_show(struct device *pdev, struct device_attribute *attr,
2173 char *buf)
2174{
2175 struct android_dev *dev = dev_get_drvdata(pdev);
2176 struct usb_composite_dev *cdev = dev->cdev;
2177 char *state = "DISCONNECTED";
2178 unsigned long flags;
2179
2180 if (!cdev)
2181 goto out;
2182
2183 spin_lock_irqsave(&cdev->lock, flags);
2184 if (cdev->config)
2185 state = "CONFIGURED";
2186 else if (dev->connected)
2187 state = "CONNECTED";
2188 spin_unlock_irqrestore(&cdev->lock, flags);
2189out:
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302190 return snprintf(buf, PAGE_SIZE, "%s\n", state);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002191}
2192
2193#define DESCRIPTOR_ATTR(field, format_string) \
2194static ssize_t \
2195field ## _show(struct device *dev, struct device_attribute *attr, \
2196 char *buf) \
2197{ \
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302198 return snprintf(buf, PAGE_SIZE, \
2199 format_string, device_desc.field); \
Benoit Goby1e8ce152011-12-12 13:01:23 -08002200} \
2201static ssize_t \
2202field ## _store(struct device *dev, struct device_attribute *attr, \
2203 const char *buf, size_t size) \
2204{ \
2205 int value; \
2206 if (sscanf(buf, format_string, &value) == 1) { \
2207 device_desc.field = value; \
2208 return size; \
2209 } \
2210 return -1; \
2211} \
2212static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store);
2213
2214#define DESCRIPTOR_STRING_ATTR(field, buffer) \
2215static ssize_t \
2216field ## _show(struct device *dev, struct device_attribute *attr, \
2217 char *buf) \
2218{ \
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302219 return snprintf(buf, PAGE_SIZE, "%s", buffer); \
Benoit Goby1e8ce152011-12-12 13:01:23 -08002220} \
2221static ssize_t \
2222field ## _store(struct device *dev, struct device_attribute *attr, \
2223 const char *buf, size_t size) \
2224{ \
2225 if (size >= sizeof(buffer)) \
2226 return -EINVAL; \
Pavankumar Kondetie02a51a2012-06-20 08:52:37 +05302227 strlcpy(buffer, buf, sizeof(buffer)); \
2228 strim(buffer); \
Pavankumar Kondeti4c22c102012-06-15 10:59:05 +05302229 return size; \
Benoit Goby1e8ce152011-12-12 13:01:23 -08002230} \
2231static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store);
2232
2233
2234DESCRIPTOR_ATTR(idVendor, "%04x\n")
2235DESCRIPTOR_ATTR(idProduct, "%04x\n")
2236DESCRIPTOR_ATTR(bcdDevice, "%04x\n")
2237DESCRIPTOR_ATTR(bDeviceClass, "%d\n")
2238DESCRIPTOR_ATTR(bDeviceSubClass, "%d\n")
2239DESCRIPTOR_ATTR(bDeviceProtocol, "%d\n")
2240DESCRIPTOR_STRING_ATTR(iManufacturer, manufacturer_string)
2241DESCRIPTOR_STRING_ATTR(iProduct, product_string)
2242DESCRIPTOR_STRING_ATTR(iSerial, serial_string)
2243
2244static DEVICE_ATTR(functions, S_IRUGO | S_IWUSR, functions_show,
2245 functions_store);
2246static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store);
Ofir Cohen94213a72012-05-03 14:26:32 +03002247static DEVICE_ATTR(pm_qos, S_IRUGO | S_IWUSR,
2248 pm_qos_show, pm_qos_store);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002249static DEVICE_ATTR(state, S_IRUGO, state_show, NULL);
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05302250static DEVICE_ATTR(remote_wakeup, S_IRUGO | S_IWUSR,
2251 remote_wakeup_show, remote_wakeup_store);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002252
2253static struct device_attribute *android_usb_attributes[] = {
2254 &dev_attr_idVendor,
2255 &dev_attr_idProduct,
2256 &dev_attr_bcdDevice,
2257 &dev_attr_bDeviceClass,
2258 &dev_attr_bDeviceSubClass,
2259 &dev_attr_bDeviceProtocol,
2260 &dev_attr_iManufacturer,
2261 &dev_attr_iProduct,
2262 &dev_attr_iSerial,
2263 &dev_attr_functions,
2264 &dev_attr_enable,
Ofir Cohen94213a72012-05-03 14:26:32 +03002265 &dev_attr_pm_qos,
Benoit Goby1e8ce152011-12-12 13:01:23 -08002266 &dev_attr_state,
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05302267 &dev_attr_remote_wakeup,
Benoit Goby1e8ce152011-12-12 13:01:23 -08002268 NULL
2269};
2270
2271/*-------------------------------------------------------------------------*/
2272/* Composite driver */
2273
2274static int android_bind_config(struct usb_configuration *c)
2275{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002276 struct android_dev *dev = cdev_to_android_dev(c->cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002277 int ret = 0;
2278
2279 ret = android_bind_enabled_functions(dev, c);
2280 if (ret)
2281 return ret;
2282
2283 return 0;
2284}
2285
2286static void android_unbind_config(struct usb_configuration *c)
2287{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002288 struct android_dev *dev = cdev_to_android_dev(c->cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002289
2290 android_unbind_enabled_functions(dev, c);
2291}
2292
2293static int android_bind(struct usb_composite_dev *cdev)
2294{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002295 struct android_dev *dev;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002296 struct usb_gadget *gadget = cdev->gadget;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002297 struct android_configuration *conf;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002298 int gcnum, id, ret;
2299
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002300 /* Bind to the last android_dev that was probed */
2301 dev = list_entry(android_dev_list.prev, struct android_dev, list_item);
2302
2303 dev->cdev = cdev;
2304
Benoit Goby1e8ce152011-12-12 13:01:23 -08002305 /*
2306 * Start disconnected. Userspace will connect the gadget once
2307 * it is done configuring the functions.
2308 */
2309 usb_gadget_disconnect(gadget);
2310
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002311 /* Init the supported functions only once, on the first android_dev */
2312 if (android_dev_count == 1) {
2313 ret = android_init_functions(dev->functions, cdev);
2314 if (ret)
2315 return ret;
2316 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002317
2318 /* Allocate string descriptor numbers ... note that string
2319 * contents can be overridden by the composite_dev glue.
2320 */
2321 id = usb_string_id(cdev);
2322 if (id < 0)
2323 return id;
2324 strings_dev[STRING_MANUFACTURER_IDX].id = id;
2325 device_desc.iManufacturer = id;
2326
2327 id = usb_string_id(cdev);
2328 if (id < 0)
2329 return id;
2330 strings_dev[STRING_PRODUCT_IDX].id = id;
2331 device_desc.iProduct = id;
2332
2333 /* Default strings - should be updated by userspace */
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302334 strlcpy(manufacturer_string, "Android",
2335 sizeof(manufacturer_string) - 1);
2336 strlcpy(product_string, "Android", sizeof(product_string) - 1);
2337 strlcpy(serial_string, "0123456789ABCDEF", sizeof(serial_string) - 1);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002338
2339 id = usb_string_id(cdev);
2340 if (id < 0)
2341 return id;
2342 strings_dev[STRING_SERIAL_IDX].id = id;
2343 device_desc.iSerialNumber = id;
2344
Vijayavardhan Vennapusa56e60522012-02-16 15:40:16 +05302345 if (gadget_is_otg(cdev->gadget))
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002346 list_for_each_entry(conf, &dev->configs, list_item)
2347 conf->usb_config.descriptors = otg_desc;
Vijayavardhan Vennapusa56e60522012-02-16 15:40:16 +05302348
Benoit Goby1e8ce152011-12-12 13:01:23 -08002349 gcnum = usb_gadget_controller_number(gadget);
2350 if (gcnum >= 0)
2351 device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
2352 else {
2353 pr_warning("%s: controller '%s' not recognized\n",
2354 longname, gadget->name);
2355 device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
2356 }
2357
Benoit Goby1e8ce152011-12-12 13:01:23 -08002358 return 0;
2359}
2360
2361static int android_usb_unbind(struct usb_composite_dev *cdev)
2362{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002363 struct android_dev *dev = cdev_to_android_dev(cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002364
Lena Salmand092f2d2012-03-12 17:27:24 +02002365 manufacturer_string[0] = '\0';
2366 product_string[0] = '\0';
2367 serial_string[0] = '0';
Benoit Goby1e8ce152011-12-12 13:01:23 -08002368 cancel_work_sync(&dev->work);
2369 android_cleanup_functions(dev->functions);
2370 return 0;
2371}
2372
2373static struct usb_composite_driver android_usb_driver = {
2374 .name = "android_usb",
2375 .dev = &device_desc,
2376 .strings = dev_strings,
2377 .unbind = android_usb_unbind,
Tatyana Brokhman3ba28902011-06-29 16:41:49 +03002378 .max_speed = USB_SPEED_SUPER
Benoit Goby1e8ce152011-12-12 13:01:23 -08002379};
2380
2381static int
2382android_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *c)
2383{
Benoit Goby1e8ce152011-12-12 13:01:23 -08002384 struct usb_composite_dev *cdev = get_gadget_data(gadget);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002385 struct android_dev *dev = cdev_to_android_dev(cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002386 struct usb_request *req = cdev->req;
2387 struct android_usb_function *f;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002388 struct android_configuration *conf;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002389 int value = -EOPNOTSUPP;
2390 unsigned long flags;
2391
2392 req->zero = 0;
2393 req->complete = composite_setup_complete;
2394 req->length = 0;
2395 gadget->ep0->driver_data = cdev;
2396
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002397 list_for_each_entry(conf, &dev->configs, list_item)
taeju.park257b5082012-10-09 10:52:01 +09002398 list_for_each_entry(f, &conf->enabled_functions, enabled_list)
2399 if (f->ctrlrequest) {
2400 value = f->ctrlrequest(f, cdev, c);
2401 if (value >= 0)
2402 break;
2403 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002404
Benoit Gobycf3fc062011-12-19 14:39:37 -08002405 /* Special case the accessory function.
2406 * It needs to handle control requests before it is enabled.
2407 */
2408 if (value < 0)
2409 value = acc_ctrlrequest(cdev, c);
2410
Benoit Goby1e8ce152011-12-12 13:01:23 -08002411 if (value < 0)
2412 value = composite_setup(gadget, c);
2413
2414 spin_lock_irqsave(&cdev->lock, flags);
2415 if (!dev->connected) {
2416 dev->connected = 1;
2417 schedule_work(&dev->work);
2418 } else if (c->bRequest == USB_REQ_SET_CONFIGURATION &&
2419 cdev->config) {
2420 schedule_work(&dev->work);
2421 }
2422 spin_unlock_irqrestore(&cdev->lock, flags);
2423
2424 return value;
2425}
2426
2427static void android_disconnect(struct usb_gadget *gadget)
2428{
Benoit Goby1e8ce152011-12-12 13:01:23 -08002429 struct usb_composite_dev *cdev = get_gadget_data(gadget);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002430 struct android_dev *dev = cdev_to_android_dev(cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002431 unsigned long flags;
2432
2433 composite_disconnect(gadget);
Ajay Dudanic2f0cc72012-08-27 16:23:48 +05302434 /* accessory HID support can be active while the
2435 accessory function is not actually enabled,
2436 so we need to inform it when we are disconnected.
2437 */
2438 acc_disconnect();
Benoit Goby1e8ce152011-12-12 13:01:23 -08002439
2440 spin_lock_irqsave(&cdev->lock, flags);
2441 dev->connected = 0;
2442 schedule_work(&dev->work);
2443 spin_unlock_irqrestore(&cdev->lock, flags);
2444}
2445
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002446static int android_create_device(struct android_dev *dev, u8 usb_core_id)
Benoit Goby1e8ce152011-12-12 13:01:23 -08002447{
2448 struct device_attribute **attrs = android_usb_attributes;
2449 struct device_attribute *attr;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002450 char device_node_name[ANDROID_DEVICE_NODE_NAME_LENGTH];
Benoit Goby1e8ce152011-12-12 13:01:23 -08002451 int err;
2452
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002453 /*
2454 * The primary usb core should always have usb_core_id=0, since
2455 * Android user space is currently interested in android0 events.
2456 */
2457 snprintf(device_node_name, ANDROID_DEVICE_NODE_NAME_LENGTH,
2458 "android%d", usb_core_id);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002459 dev->dev = device_create(android_class, NULL,
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002460 MKDEV(0, 0), NULL, device_node_name);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002461 if (IS_ERR(dev->dev))
2462 return PTR_ERR(dev->dev);
2463
2464 dev_set_drvdata(dev->dev, dev);
2465
2466 while ((attr = *attrs++)) {
2467 err = device_create_file(dev->dev, attr);
2468 if (err) {
2469 device_destroy(android_class, dev->dev->devt);
2470 return err;
2471 }
2472 }
2473 return 0;
2474}
2475
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05302476static void android_destroy_device(struct android_dev *dev)
Benoit Goby1e8ce152011-12-12 13:01:23 -08002477{
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05302478 struct device_attribute **attrs = android_usb_attributes;
2479 struct device_attribute *attr;
2480
2481 while ((attr = *attrs++))
2482 device_remove_file(dev->dev, attr);
2483 device_destroy(android_class, dev->dev->devt);
2484}
2485
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002486static struct android_dev *cdev_to_android_dev(struct usb_composite_dev *cdev)
2487{
2488 struct android_dev *dev = NULL;
2489
2490 /* Find the android dev from the list */
2491 list_for_each_entry(dev, &android_dev_list, list_item) {
2492 if (dev->cdev == cdev)
2493 break;
2494 }
2495
2496 return dev;
2497}
2498
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002499static struct android_configuration *alloc_android_config
2500 (struct android_dev *dev)
2501{
2502 struct android_configuration *conf;
2503
2504 conf = kzalloc(sizeof(*conf), GFP_KERNEL);
2505 if (!conf) {
2506 pr_err("%s(): Failed to alloc memory for android conf\n",
2507 __func__);
2508 return ERR_PTR(-ENOMEM);
2509 }
2510
2511 dev->configs_num++;
2512 conf->usb_config.label = dev->name;
2513 conf->usb_config.unbind = android_unbind_config;
2514 conf->usb_config.bConfigurationValue = dev->configs_num;
2515
2516 INIT_LIST_HEAD(&conf->enabled_functions);
2517
2518 list_add_tail(&conf->list_item, &dev->configs);
2519
2520 return conf;
2521}
2522
2523static void free_android_config(struct android_dev *dev,
2524 struct android_configuration *conf)
2525{
2526 list_del(&conf->list_item);
2527 dev->configs_num--;
2528 kfree(conf);
2529}
2530
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002531static int __devinit android_probe(struct platform_device *pdev)
2532{
2533 struct android_usb_platform_data *pdata = pdev->dev.platform_data;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002534 struct android_dev *android_dev;
Lena Salmand092f2d2012-03-12 17:27:24 +02002535 int ret = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002536
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002537 if (!android_class) {
2538 android_class = class_create(THIS_MODULE, "android_usb");
2539 if (IS_ERR(android_class))
2540 return PTR_ERR(android_class);
2541 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002542
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002543 android_dev = kzalloc(sizeof(*android_dev), GFP_KERNEL);
2544 if (!android_dev) {
2545 pr_err("%s(): Failed to alloc memory for android_dev\n",
2546 __func__);
2547 ret = -ENOMEM;
2548 goto err_alloc;
2549 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002550
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002551 android_dev->name = pdev->name;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002552 android_dev->disable_depth = 1;
2553 android_dev->functions = supported_functions;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002554 android_dev->configs_num = 0;
2555 INIT_LIST_HEAD(&android_dev->configs);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002556 INIT_WORK(&android_dev->work, android_work);
2557 mutex_init(&android_dev->mutex);
2558
2559 android_dev->pdata = pdata;
2560
2561 list_add_tail(&android_dev->list_item, &android_dev_list);
2562 android_dev_count++;
2563
2564 if (pdata)
2565 composite_driver.usb_core_id = pdata->usb_core_id;
2566 else
2567 composite_driver.usb_core_id = 0; /*To backward compatibility*/
2568
2569 ret = android_create_device(android_dev, composite_driver.usb_core_id);
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05302570 if (ret) {
2571 pr_err("%s(): android_create_device failed\n", __func__);
2572 goto err_dev;
2573 }
2574
Lena Salmand092f2d2012-03-12 17:27:24 +02002575 ret = usb_composite_probe(&android_usb_driver, android_bind);
2576 if (ret) {
2577 pr_err("%s(): Failed to register android "
2578 "composite driver\n", __func__);
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05302579 goto err_probe;
Lena Salmand092f2d2012-03-12 17:27:24 +02002580 }
2581
Ofir Cohen94213a72012-05-03 14:26:32 +03002582 /* pm qos request to prevent apps idle power collapse */
Manu Gautam94dc6142012-05-08 14:35:24 +05302583 if (pdata && pdata->swfi_latency)
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002584 pm_qos_add_request(&android_dev->pm_qos_req_dma,
Ofir Cohen94213a72012-05-03 14:26:32 +03002585 PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002586 strlcpy(android_dev->pm_qos, "high", sizeof(android_dev->pm_qos));
Ofir Cohen94213a72012-05-03 14:26:32 +03002587
Lena Salmand092f2d2012-03-12 17:27:24 +02002588 return ret;
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05302589err_probe:
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002590 android_destroy_device(android_dev);
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05302591err_dev:
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002592 list_del(&android_dev->list_item);
2593 android_dev_count--;
2594 kfree(android_dev);
2595err_alloc:
2596 if (list_empty(&android_dev_list)) {
2597 class_destroy(android_class);
2598 android_class = NULL;
2599 }
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05302600 return ret;
Lena Salmand092f2d2012-03-12 17:27:24 +02002601}
2602
2603static int android_remove(struct platform_device *pdev)
2604{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002605 struct android_dev *dev = NULL;
Ofir Cohen94213a72012-05-03 14:26:32 +03002606 struct android_usb_platform_data *pdata = pdev->dev.platform_data;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002607 int usb_core_id = 0;
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05302608
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002609 if (pdata)
2610 usb_core_id = pdata->usb_core_id;
2611
2612 /* Find the android dev from the list */
2613 list_for_each_entry(dev, &android_dev_list, list_item) {
2614 if (!dev->pdata)
2615 break; /*To backward compatibility*/
2616 if (dev->pdata->usb_core_id == usb_core_id)
2617 break;
2618 }
2619
2620 if (dev) {
2621 android_destroy_device(dev);
2622 if (pdata && pdata->swfi_latency)
2623 pm_qos_remove_request(&dev->pm_qos_req_dma);
2624 list_del(&dev->list_item);
2625 android_dev_count--;
2626 kfree(dev);
2627 }
2628
2629 if (list_empty(&android_dev_list)) {
2630 class_destroy(android_class);
2631 android_class = NULL;
2632 usb_composite_unregister(&android_usb_driver);
2633 }
Ofir Cohen94213a72012-05-03 14:26:32 +03002634
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002635 return 0;
2636}
2637
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002638static const struct platform_device_id android_id_table[] __devinitconst = {
2639 {
2640 .name = "android_usb",
2641 },
2642 {
2643 .name = "android_usb_hsic",
2644 },
2645};
2646
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002647static struct platform_driver android_platform_driver = {
2648 .driver = { .name = "android_usb"},
Lena Salmand092f2d2012-03-12 17:27:24 +02002649 .probe = android_probe,
2650 .remove = android_remove,
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002651 .id_table = android_id_table,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002652};
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05002653
2654static int __init init(void)
2655{
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05302656 int ret;
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05002657
Benoit Goby1e8ce152011-12-12 13:01:23 -08002658 /* Override composite driver functions */
2659 composite_driver.setup = android_setup;
2660 composite_driver.disconnect = android_disconnect;
2661
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002662 INIT_LIST_HEAD(&android_dev_list);
2663 android_dev_count = 0;
2664
Pavankumar Kondeti044914d2012-01-31 12:56:13 +05302665 ret = platform_driver_register(&android_platform_driver);
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05302666 if (ret) {
2667 pr_err("%s(): Failed to register android"
2668 "platform driver\n", __func__);
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05302669 }
Lena Salmand092f2d2012-03-12 17:27:24 +02002670
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05302671 return ret;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002672}
2673module_init(init);
2674
2675static void __exit cleanup(void)
2676{
Lena Salmand092f2d2012-03-12 17:27:24 +02002677 platform_driver_unregister(&android_platform_driver);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002678}
2679module_exit(cleanup);