blob: 6fe4426b5c3059654df7b53446d931c040300380 [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);
Pavankumar Kondetid0f3d432013-04-25 10:35:54 +0530952
953/*enabled ACM transport names - "serial_hsic[,serial_hsusb]"*/
954static char acm_xport_names[32];
955static ssize_t acm_xport_names_store(
956 struct device *device, struct device_attribute *attr,
957 const char *buff, size_t size)
958{
959 strlcpy(acm_xport_names, buff, sizeof(acm_xport_names));
960
961 return size;
962}
963
964static DEVICE_ATTR(acm_transport_names, S_IWUSR, NULL, acm_xport_names_store);
965
Anji jonnala92be1b42011-12-19 09:44:41 +0530966static struct device_attribute *acm_function_attributes[] = {
Pavankumar Kondetid0f3d432013-04-25 10:35:54 +0530967 &dev_attr_acm_transports,
968 &dev_attr_acm_transport_names,
969 NULL };
Anji jonnala92be1b42011-12-19 09:44:41 +0530970
Benoit Goby1e8ce152011-12-12 13:01:23 -0800971static void acm_function_cleanup(struct android_usb_function *f)
972{
973 gserial_cleanup();
Benoit Goby1e8ce152011-12-12 13:01:23 -0800974}
975
Anji jonnala92be1b42011-12-19 09:44:41 +0530976static int acm_function_bind_config(struct android_usb_function *f,
977 struct usb_configuration *c)
Benoit Goby1e8ce152011-12-12 13:01:23 -0800978{
Pavankumar Kondetid0f3d432013-04-25 10:35:54 +0530979 char *name, *xport_name = NULL;
980 char buf[32], *b, xport_name_buf[32], *tb;
Anji jonnala92be1b42011-12-19 09:44:41 +0530981 int err = -1, i;
982 static int acm_initialized, ports;
Benoit Goby1e8ce152011-12-12 13:01:23 -0800983
Anji jonnala92be1b42011-12-19 09:44:41 +0530984 if (acm_initialized)
985 goto bind_config;
986
987 acm_initialized = 1;
988 strlcpy(buf, acm_transports, sizeof(buf));
989 b = strim(buf);
990
Pavankumar Kondetid0f3d432013-04-25 10:35:54 +0530991 strlcpy(xport_name_buf, acm_xport_names, sizeof(xport_name_buf));
992 tb = strim(xport_name_buf);
993
Anji jonnala92be1b42011-12-19 09:44:41 +0530994 while (b) {
995 name = strsep(&b, ",");
996
997 if (name) {
Pavankumar Kondetid0f3d432013-04-25 10:35:54 +0530998 if (tb)
999 xport_name = strsep(&tb, ",");
1000 err = acm_init_port(ports, name, xport_name);
Anji jonnala92be1b42011-12-19 09:44:41 +05301001 if (err) {
1002 pr_err("acm: Cannot open port '%s'", name);
1003 goto out;
1004 }
1005 ports++;
1006 }
1007 }
1008 err = acm_port_setup(c);
1009 if (err) {
1010 pr_err("acm: Cannot setup transports");
1011 goto out;
1012 }
1013
1014bind_config:
1015 for (i = 0; i < ports; i++) {
1016 err = acm_bind_config(c, i);
1017 if (err) {
1018 pr_err("acm: bind_config failed for port %d", i);
1019 goto out;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001020 }
1021 }
1022
Anji jonnala92be1b42011-12-19 09:44:41 +05301023out:
1024 return err;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001025}
Benoit Goby1e8ce152011-12-12 13:01:23 -08001026static struct android_usb_function acm_function = {
1027 .name = "acm",
Benoit Goby1e8ce152011-12-12 13:01:23 -08001028 .cleanup = acm_function_cleanup,
1029 .bind_config = acm_function_bind_config,
1030 .attributes = acm_function_attributes,
1031};
1032
Chiranjeevi Velempatie130fd02011-11-29 05:06:13 +05301033/* CCID */
1034static int ccid_function_init(struct android_usb_function *f,
1035 struct usb_composite_dev *cdev)
1036{
1037 return ccid_setup();
1038}
Benoit Goby1e8ce152011-12-12 13:01:23 -08001039
Chiranjeevi Velempatie130fd02011-11-29 05:06:13 +05301040static void ccid_function_cleanup(struct android_usb_function *f)
1041{
1042 ccid_cleanup();
1043}
1044
1045static int ccid_function_bind_config(struct android_usb_function *f,
1046 struct usb_configuration *c)
1047{
1048 return ccid_bind_config(c);
1049}
1050
1051static struct android_usb_function ccid_function = {
1052 .name = "ccid",
1053 .init = ccid_function_init,
1054 .cleanup = ccid_function_cleanup,
1055 .bind_config = ccid_function_bind_config,
1056};
1057
Steve Mucklef132c6c2012-06-06 18:30:57 -07001058static int mtp_function_init(struct android_usb_function *f,
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001059 struct usb_composite_dev *cdev)
1060{
1061 return mtp_setup();
1062}
1063
1064static void mtp_function_cleanup(struct android_usb_function *f)
1065{
1066 mtp_cleanup();
1067}
1068
Steve Mucklef132c6c2012-06-06 18:30:57 -07001069static int mtp_function_bind_config(struct android_usb_function *f,
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001070 struct usb_configuration *c)
1071{
1072 return mtp_bind_config(c, false);
1073}
1074
Mike Lockwoodcf7addf2011-06-01 22:17:36 -04001075static int ptp_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev)
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001076{
1077 /* nothing to do - initialization is handled by mtp_function_init */
1078 return 0;
1079}
1080
1081static void ptp_function_cleanup(struct android_usb_function *f)
1082{
1083 /* nothing to do - cleanup is handled by mtp_function_cleanup */
1084}
1085
Mike Lockwoodcf7addf2011-06-01 22:17:36 -04001086static int ptp_function_bind_config(struct android_usb_function *f, struct usb_configuration *c)
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001087{
1088 return mtp_bind_config(c, true);
1089}
1090
1091static int mtp_function_ctrlrequest(struct android_usb_function *f,
1092 struct usb_composite_dev *cdev,
1093 const struct usb_ctrlrequest *c)
1094{
1095 return mtp_ctrlrequest(cdev, c);
1096}
1097
1098static struct android_usb_function mtp_function = {
1099 .name = "mtp",
1100 .init = mtp_function_init,
1101 .cleanup = mtp_function_cleanup,
1102 .bind_config = mtp_function_bind_config,
1103 .ctrlrequest = mtp_function_ctrlrequest,
1104};
1105
1106/* PTP function is same as MTP with slightly different interface descriptor */
1107static struct android_usb_function ptp_function = {
1108 .name = "ptp",
1109 .init = ptp_function_init,
1110 .cleanup = ptp_function_cleanup,
1111 .bind_config = ptp_function_bind_config,
1112};
1113
Devin Kim0c5b9ce2012-06-19 21:34:44 -07001114#ifdef CONFIG_USB_ANDROID_CDC_ECM
1115struct ecm_function_config {
1116 u8 ethaddr[ETH_ALEN];
1117 u32 vendorID;
1118 char manufacturer[256];
1119};
1120
1121static int ecm_function_init(struct android_usb_function *f,
1122 struct usb_composite_dev *cdev)
1123{
1124 f->config = kzalloc(sizeof(struct ecm_function_config), GFP_KERNEL);
1125 if (!f->config)
1126 return -ENOMEM;
1127 return 0;
1128}
1129
1130static void ecm_function_cleanup(struct android_usb_function *f)
1131{
1132 kfree(f->config);
1133 f->config = NULL;
1134}
1135
1136static int ecm_function_bind_config(struct android_usb_function *f,
1137 struct usb_configuration *c)
1138{
1139 int ret;
1140 struct ecm_function_config *ecm = f->config;
1141
1142 if (!ecm) {
1143 pr_err("%s: ecm_function_config\n", __func__);
1144 return -1;
1145 }
1146
1147 pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
1148 ecm->ethaddr[0], ecm->ethaddr[1], ecm->ethaddr[2],
1149 ecm->ethaddr[3], ecm->ethaddr[4], ecm->ethaddr[5]);
1150
1151 ret = gether_setup_name(c->cdev->gadget, ecm->ethaddr, "usb");
1152 if (ret) {
1153 pr_err("%s: gether_setup failed\n", __func__);
1154 return ret;
1155 }
1156
1157 return ecm_bind_config(c, ecm->ethaddr);
1158}
1159
1160static void ecm_function_unbind_config(struct android_usb_function *f,
1161 struct usb_configuration *c)
1162{
1163 gether_cleanup();
1164}
1165
1166static ssize_t ecm_manufacturer_show(struct device *dev,
1167 struct device_attribute *attr, char *buf)
1168{
1169 struct android_usb_function *f = dev_get_drvdata(dev);
1170 struct ecm_function_config *config = f->config;
1171
1172 return snprintf(buf, PAGE_SIZE, "%s\n", config->manufacturer);
1173}
1174
1175static ssize_t ecm_manufacturer_store(struct device *dev,
1176 struct device_attribute *attr, const char *buf, size_t size)
1177{
1178 struct android_usb_function *f = dev_get_drvdata(dev);
1179 struct ecm_function_config *config = f->config;
1180
1181 if (size >= sizeof(config->manufacturer))
1182 return -EINVAL;
1183
1184 if (sscanf(buf, "%255s", config->manufacturer) == 1)
1185 return size;
1186 return -1;
1187}
1188
1189static DEVICE_ATTR(manufacturer, S_IRUGO | S_IWUSR, ecm_manufacturer_show,
1190 ecm_manufacturer_store);
1191
1192static ssize_t ecm_ethaddr_show(struct device *dev,
1193 struct device_attribute *attr, char *buf)
1194{
1195 struct android_usb_function *f = dev_get_drvdata(dev);
1196 struct ecm_function_config *ecm = f->config;
1197 return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
1198 ecm->ethaddr[0], ecm->ethaddr[1], ecm->ethaddr[2],
1199 ecm->ethaddr[3], ecm->ethaddr[4], ecm->ethaddr[5]);
1200}
1201
1202static ssize_t ecm_ethaddr_store(struct device *dev,
1203 struct device_attribute *attr, const char *buf, size_t size)
1204{
1205 struct android_usb_function *f = dev_get_drvdata(dev);
1206 struct ecm_function_config *ecm = f->config;
1207
1208 if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
1209 (int *)&ecm->ethaddr[0], (int *)&ecm->ethaddr[1],
1210 (int *)&ecm->ethaddr[2], (int *)&ecm->ethaddr[3],
1211 (int *)&ecm->ethaddr[4], (int *)&ecm->ethaddr[5]) == 6)
1212 return size;
1213 return -EINVAL;
1214}
1215
1216static DEVICE_ATTR(ethaddr, S_IRUGO | S_IWUSR, ecm_ethaddr_show,
1217 ecm_ethaddr_store);
1218
1219static ssize_t ecm_vendorID_show(struct device *dev,
1220 struct device_attribute *attr, char *buf)
1221{
1222 struct android_usb_function *f = dev_get_drvdata(dev);
1223 struct ecm_function_config *config = f->config;
1224
1225 return snprintf(buf, PAGE_SIZE, "%04x\n", config->vendorID);
1226}
1227
1228static ssize_t ecm_vendorID_store(struct device *dev,
1229 struct device_attribute *attr, const char *buf, size_t size)
1230{
1231 struct android_usb_function *f = dev_get_drvdata(dev);
1232 struct ecm_function_config *config = f->config;
1233 int value;
1234
1235 if (sscanf(buf, "%04x", &value) == 1) {
1236 config->vendorID = value;
1237 return size;
1238 }
1239 return -EINVAL;
1240}
1241
1242static DEVICE_ATTR(vendorID, S_IRUGO | S_IWUSR, ecm_vendorID_show,
1243 ecm_vendorID_store);
1244
1245static struct device_attribute *ecm_function_attributes[] = {
1246 &dev_attr_manufacturer,
1247 &dev_attr_ethaddr,
1248 &dev_attr_vendorID,
1249 NULL
1250};
1251
1252static struct android_usb_function ecm_function = {
1253 .name = "ecm",
1254 .init = ecm_function_init,
1255 .cleanup = ecm_function_cleanup,
1256 .bind_config = ecm_function_bind_config,
1257 .unbind_config = ecm_function_unbind_config,
1258 .attributes = ecm_function_attributes,
1259};
1260
1261#else
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001262
Benoit Goby1e8ce152011-12-12 13:01:23 -08001263struct rndis_function_config {
1264 u8 ethaddr[ETH_ALEN];
1265 u32 vendorID;
Ofir Cohenaef90b72012-07-31 12:37:04 +02001266 u8 max_pkt_per_xfer;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001267 char manufacturer[256];
1268 /* "Wireless" RNDIS; auto-detected by Windows */
1269 bool wceis;
1270};
1271
1272static int
1273rndis_function_init(struct android_usb_function *f,
1274 struct usb_composite_dev *cdev)
1275{
1276 f->config = kzalloc(sizeof(struct rndis_function_config), GFP_KERNEL);
1277 if (!f->config)
1278 return -ENOMEM;
1279 return 0;
1280}
1281
1282static void rndis_function_cleanup(struct android_usb_function *f)
1283{
1284 kfree(f->config);
1285 f->config = NULL;
1286}
1287
Ofir Cohenaef90b72012-07-31 12:37:04 +02001288static int rndis_qc_function_init(struct android_usb_function *f,
1289 struct usb_composite_dev *cdev)
1290{
1291 f->config = kzalloc(sizeof(struct rndis_function_config), GFP_KERNEL);
1292 if (!f->config)
1293 return -ENOMEM;
1294
1295 return rndis_qc_init();
1296}
1297
1298static void rndis_qc_function_cleanup(struct android_usb_function *f)
1299{
1300 rndis_qc_cleanup();
1301 kfree(f->config);
1302}
1303
Benoit Goby1e8ce152011-12-12 13:01:23 -08001304static int
1305rndis_function_bind_config(struct android_usb_function *f,
1306 struct usb_configuration *c)
1307{
1308 int ret;
1309 struct rndis_function_config *rndis = f->config;
1310
1311 if (!rndis) {
1312 pr_err("%s: rndis_pdata\n", __func__);
1313 return -1;
1314 }
1315
1316 pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
1317 rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
1318 rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
1319
Devin Kim78e07192012-07-17 08:40:54 -07001320 ret = gether_setup_name(c->cdev->gadget, rndis->ethaddr, "usb");
Benoit Goby1e8ce152011-12-12 13:01:23 -08001321 if (ret) {
1322 pr_err("%s: gether_setup failed\n", __func__);
1323 return ret;
1324 }
1325
1326 if (rndis->wceis) {
1327 /* "Wireless" RNDIS; auto-detected by Windows */
1328 rndis_iad_descriptor.bFunctionClass =
1329 USB_CLASS_WIRELESS_CONTROLLER;
1330 rndis_iad_descriptor.bFunctionSubClass = 0x01;
1331 rndis_iad_descriptor.bFunctionProtocol = 0x03;
1332 rndis_control_intf.bInterfaceClass =
1333 USB_CLASS_WIRELESS_CONTROLLER;
1334 rndis_control_intf.bInterfaceSubClass = 0x01;
1335 rndis_control_intf.bInterfaceProtocol = 0x03;
1336 }
1337
1338 return rndis_bind_config_vendor(c, rndis->ethaddr, rndis->vendorID,
1339 rndis->manufacturer);
1340}
1341
Ofir Cohenaef90b72012-07-31 12:37:04 +02001342static int rndis_qc_function_bind_config(struct android_usb_function *f,
1343 struct usb_configuration *c)
1344{
1345 int ret;
1346 struct rndis_function_config *rndis = f->config;
1347
1348 if (!rndis) {
1349 pr_err("%s: rndis_pdata\n", __func__);
1350 return -EINVAL;
1351 }
1352
1353 pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
1354 rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
1355 rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
1356
1357 ret = gether_qc_setup_name(c->cdev->gadget, rndis->ethaddr, "rndis");
1358 if (ret) {
1359 pr_err("%s: gether_setup failed\n", __func__);
1360 return ret;
1361 }
1362
1363 if (rndis->wceis) {
1364 /* "Wireless" RNDIS; auto-detected by Windows */
1365 rndis_qc_iad_descriptor.bFunctionClass =
1366 USB_CLASS_WIRELESS_CONTROLLER;
1367 rndis_qc_iad_descriptor.bFunctionSubClass = 0x01;
1368 rndis_qc_iad_descriptor.bFunctionProtocol = 0x03;
1369 rndis_qc_control_intf.bInterfaceClass =
1370 USB_CLASS_WIRELESS_CONTROLLER;
1371 rndis_qc_control_intf.bInterfaceSubClass = 0x01;
1372 rndis_qc_control_intf.bInterfaceProtocol = 0x03;
1373 }
1374
1375 return rndis_qc_bind_config_vendor(c, rndis->ethaddr, rndis->vendorID,
1376 rndis->manufacturer,
1377 rndis->max_pkt_per_xfer);
1378}
1379
Benoit Goby1e8ce152011-12-12 13:01:23 -08001380static void rndis_function_unbind_config(struct android_usb_function *f,
1381 struct usb_configuration *c)
1382{
1383 gether_cleanup();
1384}
1385
Ofir Cohenaef90b72012-07-31 12:37:04 +02001386static void rndis_qc_function_unbind_config(struct android_usb_function *f,
1387 struct usb_configuration *c)
1388{
1389 gether_qc_cleanup();
1390}
1391
Benoit Goby1e8ce152011-12-12 13:01:23 -08001392static ssize_t rndis_manufacturer_show(struct device *dev,
1393 struct device_attribute *attr, char *buf)
1394{
1395 struct android_usb_function *f = dev_get_drvdata(dev);
1396 struct rndis_function_config *config = f->config;
Steve Mucklef132c6c2012-06-06 18:30:57 -07001397
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301398 return snprintf(buf, PAGE_SIZE, "%s\n", config->manufacturer);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001399}
1400
1401static ssize_t rndis_manufacturer_store(struct device *dev,
1402 struct device_attribute *attr, const char *buf, size_t size)
1403{
1404 struct android_usb_function *f = dev_get_drvdata(dev);
1405 struct rndis_function_config *config = f->config;
1406
1407 if (size >= sizeof(config->manufacturer))
1408 return -EINVAL;
Steve Mucklef132c6c2012-06-06 18:30:57 -07001409
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301410 if (sscanf(buf, "%255s", config->manufacturer) == 1)
Benoit Goby1e8ce152011-12-12 13:01:23 -08001411 return size;
1412 return -1;
1413}
1414
1415static DEVICE_ATTR(manufacturer, S_IRUGO | S_IWUSR, rndis_manufacturer_show,
1416 rndis_manufacturer_store);
1417
1418static ssize_t rndis_wceis_show(struct device *dev,
1419 struct device_attribute *attr, char *buf)
1420{
1421 struct android_usb_function *f = dev_get_drvdata(dev);
1422 struct rndis_function_config *config = f->config;
Steve Mucklef132c6c2012-06-06 18:30:57 -07001423
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301424 return snprintf(buf, PAGE_SIZE, "%d\n", config->wceis);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001425}
1426
1427static ssize_t rndis_wceis_store(struct device *dev,
1428 struct device_attribute *attr, const char *buf, size_t size)
1429{
1430 struct android_usb_function *f = dev_get_drvdata(dev);
1431 struct rndis_function_config *config = f->config;
1432 int value;
1433
1434 if (sscanf(buf, "%d", &value) == 1) {
1435 config->wceis = value;
1436 return size;
1437 }
1438 return -EINVAL;
1439}
1440
1441static DEVICE_ATTR(wceis, S_IRUGO | S_IWUSR, rndis_wceis_show,
1442 rndis_wceis_store);
1443
1444static ssize_t rndis_ethaddr_show(struct device *dev,
1445 struct device_attribute *attr, char *buf)
1446{
1447 struct android_usb_function *f = dev_get_drvdata(dev);
1448 struct rndis_function_config *rndis = f->config;
Steve Mucklef132c6c2012-06-06 18:30:57 -07001449
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301450 return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n",
Benoit Goby1e8ce152011-12-12 13:01:23 -08001451 rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
1452 rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
1453}
1454
1455static ssize_t rndis_ethaddr_store(struct device *dev,
1456 struct device_attribute *attr, const char *buf, size_t size)
1457{
1458 struct android_usb_function *f = dev_get_drvdata(dev);
1459 struct rndis_function_config *rndis = f->config;
1460
1461 if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
1462 (int *)&rndis->ethaddr[0], (int *)&rndis->ethaddr[1],
1463 (int *)&rndis->ethaddr[2], (int *)&rndis->ethaddr[3],
1464 (int *)&rndis->ethaddr[4], (int *)&rndis->ethaddr[5]) == 6)
1465 return size;
1466 return -EINVAL;
1467}
1468
1469static DEVICE_ATTR(ethaddr, S_IRUGO | S_IWUSR, rndis_ethaddr_show,
1470 rndis_ethaddr_store);
1471
1472static ssize_t rndis_vendorID_show(struct device *dev,
1473 struct device_attribute *attr, char *buf)
1474{
1475 struct android_usb_function *f = dev_get_drvdata(dev);
1476 struct rndis_function_config *config = f->config;
Steve Mucklef132c6c2012-06-06 18:30:57 -07001477
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301478 return snprintf(buf, PAGE_SIZE, "%04x\n", config->vendorID);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001479}
1480
1481static ssize_t rndis_vendorID_store(struct device *dev,
1482 struct device_attribute *attr, const char *buf, size_t size)
1483{
1484 struct android_usb_function *f = dev_get_drvdata(dev);
1485 struct rndis_function_config *config = f->config;
1486 int value;
1487
1488 if (sscanf(buf, "%04x", &value) == 1) {
1489 config->vendorID = value;
1490 return size;
1491 }
1492 return -EINVAL;
1493}
1494
1495static DEVICE_ATTR(vendorID, S_IRUGO | S_IWUSR, rndis_vendorID_show,
1496 rndis_vendorID_store);
1497
Ofir Cohenaef90b72012-07-31 12:37:04 +02001498static ssize_t rndis_max_pkt_per_xfer_show(struct device *dev,
1499 struct device_attribute *attr, char *buf)
1500{
1501 struct android_usb_function *f = dev_get_drvdata(dev);
1502 struct rndis_function_config *config = f->config;
1503 return snprintf(buf, PAGE_SIZE, "%d\n", config->max_pkt_per_xfer);
1504}
1505
1506static ssize_t rndis_max_pkt_per_xfer_store(struct device *dev,
1507 struct device_attribute *attr, const char *buf, size_t size)
1508{
1509 struct android_usb_function *f = dev_get_drvdata(dev);
1510 struct rndis_function_config *config = f->config;
1511 int value;
1512
1513 if (sscanf(buf, "%d", &value) == 1) {
1514 config->max_pkt_per_xfer = value;
1515 return size;
1516 }
1517 return -EINVAL;
1518}
1519
1520static DEVICE_ATTR(max_pkt_per_xfer, S_IRUGO | S_IWUSR,
1521 rndis_max_pkt_per_xfer_show,
1522 rndis_max_pkt_per_xfer_store);
1523
Benoit Goby1e8ce152011-12-12 13:01:23 -08001524static struct device_attribute *rndis_function_attributes[] = {
1525 &dev_attr_manufacturer,
1526 &dev_attr_wceis,
1527 &dev_attr_ethaddr,
1528 &dev_attr_vendorID,
Ofir Cohenaef90b72012-07-31 12:37:04 +02001529 &dev_attr_max_pkt_per_xfer,
Benoit Goby1e8ce152011-12-12 13:01:23 -08001530 NULL
1531};
1532
1533static struct android_usb_function rndis_function = {
1534 .name = "rndis",
1535 .init = rndis_function_init,
1536 .cleanup = rndis_function_cleanup,
1537 .bind_config = rndis_function_bind_config,
1538 .unbind_config = rndis_function_unbind_config,
1539 .attributes = rndis_function_attributes,
1540};
Devin Kim0c5b9ce2012-06-19 21:34:44 -07001541#endif /* CONFIG_USB_ANDROID_CDC_ECM */
Benoit Goby1e8ce152011-12-12 13:01:23 -08001542
Ofir Cohenaef90b72012-07-31 12:37:04 +02001543static struct android_usb_function rndis_qc_function = {
1544 .name = "rndis_qc",
1545 .init = rndis_qc_function_init,
1546 .cleanup = rndis_qc_function_cleanup,
1547 .bind_config = rndis_qc_function_bind_config,
1548 .unbind_config = rndis_qc_function_unbind_config,
1549 .attributes = rndis_function_attributes,
1550};
Benoit Goby1e8ce152011-12-12 13:01:23 -08001551
1552struct mass_storage_function_config {
1553 struct fsg_config fsg;
1554 struct fsg_common *common;
1555};
1556
1557static int mass_storage_function_init(struct android_usb_function *f,
1558 struct usb_composite_dev *cdev)
1559{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001560 struct android_dev *dev = cdev_to_android_dev(cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001561 struct mass_storage_function_config *config;
1562 struct fsg_common *common;
1563 int err;
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301564 int i;
1565 const char *name[2];
Benoit Goby1e8ce152011-12-12 13:01:23 -08001566
1567 config = kzalloc(sizeof(struct mass_storage_function_config),
1568 GFP_KERNEL);
1569 if (!config)
1570 return -ENOMEM;
1571
1572 config->fsg.nluns = 1;
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301573 name[0] = "lun";
Pavankumar Kondeti2043e302012-07-19 08:54:04 +05301574 if (dev->pdata && dev->pdata->cdrom) {
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301575 config->fsg.nluns = 2;
1576 config->fsg.luns[1].cdrom = 1;
1577 config->fsg.luns[1].ro = 1;
1578 config->fsg.luns[1].removable = 1;
1579 name[1] = "lun0";
1580 }
1581
Benoit Goby1e8ce152011-12-12 13:01:23 -08001582 config->fsg.luns[0].removable = 1;
1583
1584 common = fsg_common_init(NULL, cdev, &config->fsg);
1585 if (IS_ERR(common)) {
1586 kfree(config);
1587 return PTR_ERR(common);
1588 }
1589
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301590 for (i = 0; i < config->fsg.nluns; i++) {
1591 err = sysfs_create_link(&f->dev->kobj,
1592 &common->luns[i].dev.kobj,
1593 name[i]);
1594 if (err)
1595 goto error;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001596 }
1597
1598 config->common = common;
1599 f->config = config;
1600 return 0;
Rajkumar Raghupathyc9cb2052012-04-26 13:14:10 +05301601error:
1602 for (; i > 0 ; i--)
1603 sysfs_remove_link(&f->dev->kobj, name[i-1]);
1604
1605 fsg_common_release(&common->ref);
1606 kfree(config);
1607 return err;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001608}
1609
1610static void mass_storage_function_cleanup(struct android_usb_function *f)
1611{
1612 kfree(f->config);
1613 f->config = NULL;
1614}
1615
1616static int mass_storage_function_bind_config(struct android_usb_function *f,
1617 struct usb_configuration *c)
1618{
1619 struct mass_storage_function_config *config = f->config;
1620 return fsg_bind_config(c->cdev, c, config->common);
1621}
1622
1623static ssize_t mass_storage_inquiry_show(struct device *dev,
1624 struct device_attribute *attr, char *buf)
1625{
1626 struct android_usb_function *f = dev_get_drvdata(dev);
1627 struct mass_storage_function_config *config = f->config;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301628 return snprintf(buf, PAGE_SIZE, "%s\n", config->common->inquiry_string);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001629}
1630
1631static ssize_t mass_storage_inquiry_store(struct device *dev,
1632 struct device_attribute *attr, const char *buf, size_t size)
1633{
1634 struct android_usb_function *f = dev_get_drvdata(dev);
1635 struct mass_storage_function_config *config = f->config;
1636 if (size >= sizeof(config->common->inquiry_string))
1637 return -EINVAL;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301638 if (sscanf(buf, "%28s", config->common->inquiry_string) != 1)
Benoit Goby1e8ce152011-12-12 13:01:23 -08001639 return -EINVAL;
1640 return size;
1641}
1642
1643static DEVICE_ATTR(inquiry_string, S_IRUGO | S_IWUSR,
1644 mass_storage_inquiry_show,
1645 mass_storage_inquiry_store);
1646
1647static struct device_attribute *mass_storage_function_attributes[] = {
1648 &dev_attr_inquiry_string,
1649 NULL
1650};
1651
1652static struct android_usb_function mass_storage_function = {
1653 .name = "mass_storage",
1654 .init = mass_storage_function_init,
1655 .cleanup = mass_storage_function_cleanup,
1656 .bind_config = mass_storage_function_bind_config,
1657 .attributes = mass_storage_function_attributes,
1658};
1659
1660
Benoit Gobycf3fc062011-12-19 14:39:37 -08001661static int accessory_function_init(struct android_usb_function *f,
1662 struct usb_composite_dev *cdev)
1663{
1664 return acc_setup();
1665}
1666
1667static void accessory_function_cleanup(struct android_usb_function *f)
1668{
1669 acc_cleanup();
1670}
1671
1672static int accessory_function_bind_config(struct android_usb_function *f,
1673 struct usb_configuration *c)
1674{
1675 return acc_bind_config(c);
1676}
1677
1678static int accessory_function_ctrlrequest(struct android_usb_function *f,
1679 struct usb_composite_dev *cdev,
1680 const struct usb_ctrlrequest *c)
1681{
1682 return acc_ctrlrequest(cdev, c);
1683}
1684
1685static struct android_usb_function accessory_function = {
1686 .name = "accessory",
1687 .init = accessory_function_init,
1688 .cleanup = accessory_function_cleanup,
1689 .bind_config = accessory_function_bind_config,
1690 .ctrlrequest = accessory_function_ctrlrequest,
1691};
1692
Ajay Dudani34b1e302012-08-27 16:43:53 +05301693static int audio_source_function_init(struct android_usb_function *f,
1694 struct usb_composite_dev *cdev)
1695{
1696 struct audio_source_config *config;
1697
1698 config = kzalloc(sizeof(struct audio_source_config), GFP_KERNEL);
1699 if (!config)
1700 return -ENOMEM;
1701 config->card = -1;
1702 config->device = -1;
1703 f->config = config;
1704 return 0;
1705}
1706
1707static void audio_source_function_cleanup(struct android_usb_function *f)
1708{
1709 kfree(f->config);
1710}
1711
1712static int audio_source_function_bind_config(struct android_usb_function *f,
1713 struct usb_configuration *c)
1714{
1715 struct audio_source_config *config = f->config;
1716
1717 return audio_source_bind_config(c, config);
1718}
1719
1720static void audio_source_function_unbind_config(struct android_usb_function *f,
1721 struct usb_configuration *c)
1722{
1723 struct audio_source_config *config = f->config;
1724
1725 config->card = -1;
1726 config->device = -1;
1727}
1728
1729static ssize_t audio_source_pcm_show(struct device *dev,
1730 struct device_attribute *attr, char *buf)
1731{
1732 struct android_usb_function *f = dev_get_drvdata(dev);
1733 struct audio_source_config *config = f->config;
1734
1735 /* print PCM card and device numbers */
1736 return sprintf(buf, "%d %d\n", config->card, config->device);
1737}
1738
1739static DEVICE_ATTR(pcm, S_IRUGO | S_IWUSR, audio_source_pcm_show, NULL);
1740
1741static struct device_attribute *audio_source_function_attributes[] = {
1742 &dev_attr_pcm,
1743 NULL
1744};
1745
1746static struct android_usb_function audio_source_function = {
1747 .name = "audio_source",
1748 .init = audio_source_function_init,
1749 .cleanup = audio_source_function_cleanup,
1750 .bind_config = audio_source_function_bind_config,
1751 .unbind_config = audio_source_function_unbind_config,
1752 .attributes = audio_source_function_attributes,
1753};
1754
Pavankumar Kondeti8f6ca4f2012-06-26 09:44:36 +05301755static int android_uasp_connect_cb(bool connect)
1756{
1757 /*
1758 * TODO
1759 * We may have to disable gadget till UASP configfs nodes
1760 * are configured which includes mapping LUN with the
1761 * backing file. It is a fundamental difference between
1762 * f_mass_storage and f_tcp. That means UASP can not be
1763 * in default composition.
1764 *
1765 * For now, assume that UASP configfs nodes are configured
1766 * before enabling android gadget. Or cable should be
1767 * reconnected after mapping the LUN.
1768 *
1769 * Also consider making UASP to respond to Host requests when
1770 * Lun is not mapped.
1771 */
1772 pr_debug("UASP %s\n", connect ? "connect" : "disconnect");
1773
1774 return 0;
1775}
1776
1777static int uasp_function_init(struct android_usb_function *f,
1778 struct usb_composite_dev *cdev)
1779{
1780 return f_tcm_init(&android_uasp_connect_cb);
1781}
1782
1783static void uasp_function_cleanup(struct android_usb_function *f)
1784{
1785 f_tcm_exit();
1786}
1787
1788static int uasp_function_bind_config(struct android_usb_function *f,
1789 struct usb_configuration *c)
1790{
1791 return tcm_bind_config(c);
1792}
1793
1794static struct android_usb_function uasp_function = {
1795 .name = "uasp",
1796 .init = uasp_function_init,
1797 .cleanup = uasp_function_cleanup,
1798 .bind_config = uasp_function_bind_config,
1799};
Benoit Gobycf3fc062011-12-19 14:39:37 -08001800
Benoit Goby1e8ce152011-12-12 13:01:23 -08001801static struct android_usb_function *supported_functions[] = {
Anna Perela8c991d2012-04-09 16:44:46 +03001802 &mbim_function,
Ofir Cohen7b155422012-07-31 13:02:49 +03001803 &ecm_qc_function,
Manu Gautam1c8ffd72011-09-02 16:00:49 +05301804 &rmnet_smd_function,
Manu Gautam8e0719b2011-09-26 14:47:55 +05301805 &rmnet_sdio_function,
1806 &rmnet_smd_sdio_function,
Manu Gautam2b0234a2011-09-07 16:47:52 +05301807 &rmnet_function,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001808 &diag_function,
Shimrit Malichia00d7322012-08-05 13:56:28 +03001809 &qdss_function,
Manu Gautama4d993f2011-08-30 18:25:55 +05301810 &serial_function,
Benoit Goby2b6862d2011-12-19 14:38:41 -08001811 &adb_function,
Chiranjeevi Velempatie130fd02011-11-29 05:06:13 +05301812 &ccid_function,
Benoit Goby1e8ce152011-12-12 13:01:23 -08001813 &acm_function,
Benoit Gobyf0fbc482011-12-19 14:37:50 -08001814 &mtp_function,
1815 &ptp_function,
Devin Kim0c5b9ce2012-06-19 21:34:44 -07001816#ifdef CONFIG_USB_ANDROID_CDC_ECM
1817 &ecm_function,
1818#else
Benoit Goby1e8ce152011-12-12 13:01:23 -08001819 &rndis_function,
Devin Kim0c5b9ce2012-06-19 21:34:44 -07001820#endif
Ofir Cohenaef90b72012-07-31 12:37:04 +02001821 &rndis_qc_function,
Benoit Goby1e8ce152011-12-12 13:01:23 -08001822 &mass_storage_function,
Benoit Gobycf3fc062011-12-19 14:39:37 -08001823 &accessory_function,
Ajay Dudani34b1e302012-08-27 16:43:53 +05301824 &audio_source_function,
Pavankumar Kondeti8f6ca4f2012-06-26 09:44:36 +05301825 &uasp_function,
Benoit Goby1e8ce152011-12-12 13:01:23 -08001826 NULL
1827};
1828
Lena Salmand092f2d2012-03-12 17:27:24 +02001829static void android_cleanup_functions(struct android_usb_function **functions)
1830{
1831 struct android_usb_function *f;
1832 struct device_attribute **attrs;
1833 struct device_attribute *attr;
1834
1835 while (*functions) {
1836 f = *functions++;
1837
1838 if (f->dev) {
1839 device_destroy(android_class, f->dev->devt);
1840 kfree(f->dev_name);
1841 } else
1842 continue;
1843
1844 if (f->cleanup)
1845 f->cleanup(f);
1846
1847 attrs = f->attributes;
1848 if (attrs) {
1849 while ((attr = *attrs++))
1850 device_remove_file(f->dev, attr);
1851 }
1852 }
1853}
Benoit Goby1e8ce152011-12-12 13:01:23 -08001854
1855static int android_init_functions(struct android_usb_function **functions,
1856 struct usb_composite_dev *cdev)
1857{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001858 struct android_dev *dev = cdev_to_android_dev(cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001859 struct android_usb_function *f;
1860 struct device_attribute **attrs;
1861 struct device_attribute *attr;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301862 int err = 0;
Lena Salmand092f2d2012-03-12 17:27:24 +02001863 int index = 1; /* index 0 is for android0 device */
Benoit Goby1e8ce152011-12-12 13:01:23 -08001864
1865 for (; (f = *functions++); index++) {
1866 f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001867 f->android_dev = NULL;
Lena Salmand092f2d2012-03-12 17:27:24 +02001868 if (!f->dev_name) {
1869 err = -ENOMEM;
1870 goto err_out;
1871 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08001872 f->dev = device_create(android_class, dev->dev,
1873 MKDEV(0, index), f, f->dev_name);
1874 if (IS_ERR(f->dev)) {
1875 pr_err("%s: Failed to create dev %s", __func__,
1876 f->dev_name);
1877 err = PTR_ERR(f->dev);
Lena Salmand092f2d2012-03-12 17:27:24 +02001878 f->dev = NULL;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001879 goto err_create;
1880 }
1881
1882 if (f->init) {
1883 err = f->init(f, cdev);
1884 if (err) {
1885 pr_err("%s: Failed to init %s", __func__,
1886 f->name);
Lena Salmand092f2d2012-03-12 17:27:24 +02001887 goto err_init;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001888 }
1889 }
1890
1891 attrs = f->attributes;
1892 if (attrs) {
1893 while ((attr = *attrs++) && !err)
1894 err = device_create_file(f->dev, attr);
1895 }
1896 if (err) {
1897 pr_err("%s: Failed to create function %s attributes",
1898 __func__, f->name);
Lena Salmand092f2d2012-03-12 17:27:24 +02001899 goto err_attrs;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001900 }
1901 }
1902 return 0;
1903
Lena Salmand092f2d2012-03-12 17:27:24 +02001904err_attrs:
1905 for (attr = *(attrs -= 2); attrs != f->attributes; attr = *(attrs--))
1906 device_remove_file(f->dev, attr);
1907 if (f->cleanup)
1908 f->cleanup(f);
1909err_init:
Benoit Goby1e8ce152011-12-12 13:01:23 -08001910 device_destroy(android_class, f->dev->devt);
1911err_create:
Lena Salmand092f2d2012-03-12 17:27:24 +02001912 f->dev = NULL;
Benoit Goby1e8ce152011-12-12 13:01:23 -08001913 kfree(f->dev_name);
Lena Salmand092f2d2012-03-12 17:27:24 +02001914err_out:
1915 android_cleanup_functions(dev->functions);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001916 return err;
1917}
1918
Benoit Goby1e8ce152011-12-12 13:01:23 -08001919static int
1920android_bind_enabled_functions(struct android_dev *dev,
1921 struct usb_configuration *c)
1922{
1923 struct android_usb_function *f;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001924 struct android_configuration *conf =
1925 container_of(c, struct android_configuration, usb_config);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001926 int ret;
1927
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001928 list_for_each_entry(f, &conf->enabled_functions, enabled_list) {
Benoit Goby1e8ce152011-12-12 13:01:23 -08001929 ret = f->bind_config(f, c);
1930 if (ret) {
1931 pr_err("%s: %s failed", __func__, f->name);
1932 return ret;
1933 }
1934 }
1935 return 0;
1936}
1937
1938static void
1939android_unbind_enabled_functions(struct android_dev *dev,
1940 struct usb_configuration *c)
1941{
1942 struct android_usb_function *f;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001943 struct android_configuration *conf =
1944 container_of(c, struct android_configuration, usb_config);
Benoit Goby1e8ce152011-12-12 13:01:23 -08001945
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001946 list_for_each_entry(f, &conf->enabled_functions, enabled_list) {
Benoit Goby1e8ce152011-12-12 13:01:23 -08001947 if (f->unbind_config)
1948 f->unbind_config(f, c);
1949 }
1950}
1951
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001952static int android_enable_function(struct android_dev *dev,
1953 struct android_configuration *conf,
1954 char *name)
Benoit Goby1e8ce152011-12-12 13:01:23 -08001955{
1956 struct android_usb_function **functions = dev->functions;
1957 struct android_usb_function *f;
1958 while ((f = *functions++)) {
1959 if (!strcmp(name, f->name)) {
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001960 if (f->android_dev)
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001961 pr_err("%s already enabled in other " \
1962 "configuration or device\n",
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001963 f->name);
1964 else {
1965 list_add_tail(&f->enabled_list,
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001966 &conf->enabled_functions);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001967 f->android_dev = dev;
1968 return 0;
1969 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08001970 }
1971 }
1972 return -EINVAL;
1973}
1974
1975/*-------------------------------------------------------------------------*/
1976/* /sys/class/android_usb/android%d/ interface */
1977
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05301978static ssize_t remote_wakeup_show(struct device *pdev,
1979 struct device_attribute *attr, char *buf)
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;
1983
1984 /*
1985 * Show the wakeup attribute of the first configuration,
1986 * since all configurations have the same wakeup attribute
1987 */
1988 if (dev->configs_num == 0)
1989 return 0;
1990 conf = list_entry(dev->configs.next,
1991 struct android_configuration,
1992 list_item);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03001993
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05301994 return snprintf(buf, PAGE_SIZE, "%d\n",
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03001995 !!(conf->usb_config.bmAttributes &
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05301996 USB_CONFIG_ATT_WAKEUP));
1997}
1998
1999static ssize_t remote_wakeup_store(struct device *pdev,
2000 struct device_attribute *attr, const char *buff, size_t size)
2001{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002002 struct android_dev *dev = dev_get_drvdata(pdev);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002003 struct android_configuration *conf;
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05302004 int enable = 0;
2005
2006 sscanf(buff, "%d", &enable);
2007
2008 pr_debug("android_usb: %s remote wakeup\n",
2009 enable ? "enabling" : "disabling");
2010
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002011 list_for_each_entry(conf, &dev->configs, list_item)
2012 if (enable)
2013 conf->usb_config.bmAttributes |=
2014 USB_CONFIG_ATT_WAKEUP;
2015 else
2016 conf->usb_config.bmAttributes &=
2017 ~USB_CONFIG_ATT_WAKEUP;
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05302018
2019 return size;
2020}
2021
Benoit Goby1e8ce152011-12-12 13:01:23 -08002022static ssize_t
2023functions_show(struct device *pdev, struct device_attribute *attr, char *buf)
2024{
2025 struct android_dev *dev = dev_get_drvdata(pdev);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002026 struct android_configuration *conf;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002027 struct android_usb_function *f;
2028 char *buff = buf;
2029
2030 mutex_lock(&dev->mutex);
2031
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002032 list_for_each_entry(conf, &dev->configs, list_item) {
2033 if (buff != buf)
2034 *(buff-1) = ':';
2035 list_for_each_entry(f, &conf->enabled_functions, enabled_list)
2036 buff += snprintf(buff, PAGE_SIZE, "%s,", f->name);
2037 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002038
2039 mutex_unlock(&dev->mutex);
2040
2041 if (buff != buf)
2042 *(buff-1) = '\n';
2043 return buff - buf;
2044}
2045
2046static ssize_t
2047functions_store(struct device *pdev, struct device_attribute *attr,
2048 const char *buff, size_t size)
2049{
2050 struct android_dev *dev = dev_get_drvdata(pdev);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002051 struct android_usb_function *f;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002052 struct list_head *curr_conf = &dev->configs;
2053 struct android_configuration *conf;
2054 char *conf_str;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002055 char *name;
2056 char buf[256], *b;
2057 int err;
2058
2059 mutex_lock(&dev->mutex);
2060
2061 if (dev->enabled) {
2062 mutex_unlock(&dev->mutex);
2063 return -EBUSY;
2064 }
2065
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002066 /* Clear previous enabled list */
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002067 list_for_each_entry(conf, &dev->configs, list_item) {
2068 list_for_each_entry(f, &conf->enabled_functions, enabled_list)
2069 f->android_dev = NULL;
2070 INIT_LIST_HEAD(&conf->enabled_functions);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002071 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002072
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302073 strlcpy(buf, buff, sizeof(buf));
Benoit Goby1e8ce152011-12-12 13:01:23 -08002074 b = strim(buf);
2075
2076 while (b) {
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002077 conf_str = strsep(&b, ":");
2078 if (conf_str) {
2079 /* If the next not equal to the head, take it */
2080 if (curr_conf->next != &dev->configs)
2081 conf = list_entry(curr_conf->next,
2082 struct android_configuration,
2083 list_item);
2084 else
2085 conf = alloc_android_config(dev);
2086
2087 curr_conf = curr_conf->next;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002088 }
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002089
2090 while (conf_str) {
2091 name = strsep(&conf_str, ",");
2092 if (name) {
2093 err = android_enable_function(dev, conf, name);
2094 if (err)
2095 pr_err("android_usb: Cannot enable %s",
2096 name);
2097 }
2098 }
2099 }
2100
2101 /* Free uneeded configurations if exists */
2102 while (curr_conf->next != &dev->configs) {
2103 conf = list_entry(curr_conf->next,
2104 struct android_configuration, list_item);
2105 free_android_config(dev, conf);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002106 }
2107
2108 mutex_unlock(&dev->mutex);
2109
2110 return size;
2111}
2112
2113static ssize_t enable_show(struct device *pdev, struct device_attribute *attr,
2114 char *buf)
2115{
2116 struct android_dev *dev = dev_get_drvdata(pdev);
Steve Mucklef132c6c2012-06-06 18:30:57 -07002117
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302118 return snprintf(buf, PAGE_SIZE, "%d\n", dev->enabled);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002119}
2120
2121static ssize_t enable_store(struct device *pdev, struct device_attribute *attr,
2122 const char *buff, size_t size)
2123{
2124 struct android_dev *dev = dev_get_drvdata(pdev);
2125 struct usb_composite_dev *cdev = dev->cdev;
Benoit Goby80ba14d2012-03-19 18:56:52 -07002126 struct android_usb_function *f;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002127 struct android_configuration *conf;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002128 int enabled = 0;
Pavankumar Kondetia7bb2922013-02-28 10:19:40 +05302129 static DEFINE_RATELIMIT_STATE(rl, 10*HZ, 1);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002130
Benoit Gobycf3fc062011-12-19 14:39:37 -08002131 if (!cdev)
2132 return -ENODEV;
2133
Benoit Goby1e8ce152011-12-12 13:01:23 -08002134 mutex_lock(&dev->mutex);
2135
2136 sscanf(buff, "%d", &enabled);
2137 if (enabled && !dev->enabled) {
Benoit Goby1e8ce152011-12-12 13:01:23 -08002138 /*
2139 * Update values in composite driver's copy of
2140 * device descriptor.
2141 */
2142 cdev->desc.idVendor = device_desc.idVendor;
2143 cdev->desc.idProduct = device_desc.idProduct;
2144 cdev->desc.bcdDevice = device_desc.bcdDevice;
2145 cdev->desc.bDeviceClass = device_desc.bDeviceClass;
2146 cdev->desc.bDeviceSubClass = device_desc.bDeviceSubClass;
2147 cdev->desc.bDeviceProtocol = device_desc.bDeviceProtocol;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002148 list_for_each_entry(conf, &dev->configs, list_item)
2149 list_for_each_entry(f, &conf->enabled_functions,
2150 enabled_list) {
2151 if (f->enable)
2152 f->enable(f);
2153 }
Benoit Goby80ba14d2012-03-19 18:56:52 -07002154 android_enable(dev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002155 dev->enabled = true;
2156 } else if (!enabled && dev->enabled) {
Benoit Goby80ba14d2012-03-19 18:56:52 -07002157 android_disable(dev);
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002158 list_for_each_entry(conf, &dev->configs, list_item)
2159 list_for_each_entry(f, &conf->enabled_functions,
2160 enabled_list) {
2161 if (f->disable)
2162 f->disable(f);
2163 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002164 dev->enabled = false;
Pavankumar Kondetia7bb2922013-02-28 10:19:40 +05302165 } else if (__ratelimit(&rl)) {
Benoit Goby1e8ce152011-12-12 13:01:23 -08002166 pr_err("android_usb: already %s\n",
2167 dev->enabled ? "enabled" : "disabled");
2168 }
2169
2170 mutex_unlock(&dev->mutex);
Steve Mucklef132c6c2012-06-06 18:30:57 -07002171
Benoit Gobyaab96812011-04-19 20:37:33 -07002172 return size;
2173}
2174
Ofir Cohen94213a72012-05-03 14:26:32 +03002175static ssize_t pm_qos_show(struct device *pdev,
2176 struct device_attribute *attr, char *buf)
2177{
2178 struct android_dev *dev = dev_get_drvdata(pdev);
2179
2180 return snprintf(buf, PAGE_SIZE, "%s\n", dev->pm_qos);
2181}
2182
2183static ssize_t pm_qos_store(struct device *pdev,
2184 struct device_attribute *attr,
2185 const char *buff, size_t size)
2186{
2187 struct android_dev *dev = dev_get_drvdata(pdev);
2188
2189 strlcpy(dev->pm_qos, buff, sizeof(dev->pm_qos));
2190
Benoit Goby1e8ce152011-12-12 13:01:23 -08002191 return size;
2192}
2193
2194static ssize_t state_show(struct device *pdev, struct device_attribute *attr,
2195 char *buf)
2196{
2197 struct android_dev *dev = dev_get_drvdata(pdev);
2198 struct usb_composite_dev *cdev = dev->cdev;
2199 char *state = "DISCONNECTED";
2200 unsigned long flags;
2201
2202 if (!cdev)
2203 goto out;
2204
2205 spin_lock_irqsave(&cdev->lock, flags);
2206 if (cdev->config)
2207 state = "CONFIGURED";
2208 else if (dev->connected)
2209 state = "CONNECTED";
2210 spin_unlock_irqrestore(&cdev->lock, flags);
2211out:
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302212 return snprintf(buf, PAGE_SIZE, "%s\n", state);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002213}
2214
2215#define DESCRIPTOR_ATTR(field, format_string) \
2216static ssize_t \
2217field ## _show(struct device *dev, struct device_attribute *attr, \
2218 char *buf) \
2219{ \
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302220 return snprintf(buf, PAGE_SIZE, \
2221 format_string, device_desc.field); \
Benoit Goby1e8ce152011-12-12 13:01:23 -08002222} \
2223static ssize_t \
2224field ## _store(struct device *dev, struct device_attribute *attr, \
2225 const char *buf, size_t size) \
2226{ \
2227 int value; \
2228 if (sscanf(buf, format_string, &value) == 1) { \
2229 device_desc.field = value; \
2230 return size; \
2231 } \
2232 return -1; \
2233} \
2234static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store);
2235
2236#define DESCRIPTOR_STRING_ATTR(field, buffer) \
2237static ssize_t \
2238field ## _show(struct device *dev, struct device_attribute *attr, \
2239 char *buf) \
2240{ \
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302241 return snprintf(buf, PAGE_SIZE, "%s", buffer); \
Benoit Goby1e8ce152011-12-12 13:01:23 -08002242} \
2243static ssize_t \
2244field ## _store(struct device *dev, struct device_attribute *attr, \
2245 const char *buf, size_t size) \
2246{ \
2247 if (size >= sizeof(buffer)) \
2248 return -EINVAL; \
Pavankumar Kondetie02a51a2012-06-20 08:52:37 +05302249 strlcpy(buffer, buf, sizeof(buffer)); \
2250 strim(buffer); \
Pavankumar Kondeti4c22c102012-06-15 10:59:05 +05302251 return size; \
Benoit Goby1e8ce152011-12-12 13:01:23 -08002252} \
2253static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store);
2254
2255
2256DESCRIPTOR_ATTR(idVendor, "%04x\n")
2257DESCRIPTOR_ATTR(idProduct, "%04x\n")
2258DESCRIPTOR_ATTR(bcdDevice, "%04x\n")
2259DESCRIPTOR_ATTR(bDeviceClass, "%d\n")
2260DESCRIPTOR_ATTR(bDeviceSubClass, "%d\n")
2261DESCRIPTOR_ATTR(bDeviceProtocol, "%d\n")
2262DESCRIPTOR_STRING_ATTR(iManufacturer, manufacturer_string)
2263DESCRIPTOR_STRING_ATTR(iProduct, product_string)
2264DESCRIPTOR_STRING_ATTR(iSerial, serial_string)
2265
2266static DEVICE_ATTR(functions, S_IRUGO | S_IWUSR, functions_show,
2267 functions_store);
2268static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store);
Ofir Cohen94213a72012-05-03 14:26:32 +03002269static DEVICE_ATTR(pm_qos, S_IRUGO | S_IWUSR,
2270 pm_qos_show, pm_qos_store);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002271static DEVICE_ATTR(state, S_IRUGO, state_show, NULL);
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05302272static DEVICE_ATTR(remote_wakeup, S_IRUGO | S_IWUSR,
2273 remote_wakeup_show, remote_wakeup_store);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002274
2275static struct device_attribute *android_usb_attributes[] = {
2276 &dev_attr_idVendor,
2277 &dev_attr_idProduct,
2278 &dev_attr_bcdDevice,
2279 &dev_attr_bDeviceClass,
2280 &dev_attr_bDeviceSubClass,
2281 &dev_attr_bDeviceProtocol,
2282 &dev_attr_iManufacturer,
2283 &dev_attr_iProduct,
2284 &dev_attr_iSerial,
2285 &dev_attr_functions,
2286 &dev_attr_enable,
Ofir Cohen94213a72012-05-03 14:26:32 +03002287 &dev_attr_pm_qos,
Benoit Goby1e8ce152011-12-12 13:01:23 -08002288 &dev_attr_state,
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05302289 &dev_attr_remote_wakeup,
Benoit Goby1e8ce152011-12-12 13:01:23 -08002290 NULL
2291};
2292
2293/*-------------------------------------------------------------------------*/
2294/* Composite driver */
2295
2296static int android_bind_config(struct usb_configuration *c)
2297{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002298 struct android_dev *dev = cdev_to_android_dev(c->cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002299 int ret = 0;
2300
2301 ret = android_bind_enabled_functions(dev, c);
2302 if (ret)
2303 return ret;
2304
2305 return 0;
2306}
2307
2308static void android_unbind_config(struct usb_configuration *c)
2309{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002310 struct android_dev *dev = cdev_to_android_dev(c->cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002311
2312 android_unbind_enabled_functions(dev, c);
2313}
2314
2315static int android_bind(struct usb_composite_dev *cdev)
2316{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002317 struct android_dev *dev;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002318 struct usb_gadget *gadget = cdev->gadget;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002319 struct android_configuration *conf;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002320 int gcnum, id, ret;
2321
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002322 /* Bind to the last android_dev that was probed */
2323 dev = list_entry(android_dev_list.prev, struct android_dev, list_item);
2324
2325 dev->cdev = cdev;
2326
Benoit Goby1e8ce152011-12-12 13:01:23 -08002327 /*
2328 * Start disconnected. Userspace will connect the gadget once
2329 * it is done configuring the functions.
2330 */
2331 usb_gadget_disconnect(gadget);
2332
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002333 /* Init the supported functions only once, on the first android_dev */
2334 if (android_dev_count == 1) {
2335 ret = android_init_functions(dev->functions, cdev);
2336 if (ret)
2337 return ret;
2338 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002339
2340 /* Allocate string descriptor numbers ... note that string
2341 * contents can be overridden by the composite_dev glue.
2342 */
2343 id = usb_string_id(cdev);
2344 if (id < 0)
2345 return id;
2346 strings_dev[STRING_MANUFACTURER_IDX].id = id;
2347 device_desc.iManufacturer = id;
2348
2349 id = usb_string_id(cdev);
2350 if (id < 0)
2351 return id;
2352 strings_dev[STRING_PRODUCT_IDX].id = id;
2353 device_desc.iProduct = id;
2354
2355 /* Default strings - should be updated by userspace */
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05302356 strlcpy(manufacturer_string, "Android",
2357 sizeof(manufacturer_string) - 1);
2358 strlcpy(product_string, "Android", sizeof(product_string) - 1);
2359 strlcpy(serial_string, "0123456789ABCDEF", sizeof(serial_string) - 1);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002360
2361 id = usb_string_id(cdev);
2362 if (id < 0)
2363 return id;
2364 strings_dev[STRING_SERIAL_IDX].id = id;
2365 device_desc.iSerialNumber = id;
2366
Vijayavardhan Vennapusa56e60522012-02-16 15:40:16 +05302367 if (gadget_is_otg(cdev->gadget))
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002368 list_for_each_entry(conf, &dev->configs, list_item)
2369 conf->usb_config.descriptors = otg_desc;
Vijayavardhan Vennapusa56e60522012-02-16 15:40:16 +05302370
Benoit Goby1e8ce152011-12-12 13:01:23 -08002371 gcnum = usb_gadget_controller_number(gadget);
2372 if (gcnum >= 0)
2373 device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
2374 else {
2375 pr_warning("%s: controller '%s' not recognized\n",
2376 longname, gadget->name);
2377 device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
2378 }
2379
Benoit Goby1e8ce152011-12-12 13:01:23 -08002380 return 0;
2381}
2382
2383static int android_usb_unbind(struct usb_composite_dev *cdev)
2384{
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
Lena Salmand092f2d2012-03-12 17:27:24 +02002387 manufacturer_string[0] = '\0';
2388 product_string[0] = '\0';
2389 serial_string[0] = '0';
Benoit Goby1e8ce152011-12-12 13:01:23 -08002390 cancel_work_sync(&dev->work);
2391 android_cleanup_functions(dev->functions);
2392 return 0;
2393}
2394
2395static struct usb_composite_driver android_usb_driver = {
2396 .name = "android_usb",
2397 .dev = &device_desc,
2398 .strings = dev_strings,
2399 .unbind = android_usb_unbind,
Tatyana Brokhman3ba28902011-06-29 16:41:49 +03002400 .max_speed = USB_SPEED_SUPER
Benoit Goby1e8ce152011-12-12 13:01:23 -08002401};
2402
2403static int
2404android_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *c)
2405{
Benoit Goby1e8ce152011-12-12 13:01:23 -08002406 struct usb_composite_dev *cdev = get_gadget_data(gadget);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002407 struct android_dev *dev = cdev_to_android_dev(cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002408 struct usb_request *req = cdev->req;
2409 struct android_usb_function *f;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002410 struct android_configuration *conf;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002411 int value = -EOPNOTSUPP;
2412 unsigned long flags;
2413
2414 req->zero = 0;
2415 req->complete = composite_setup_complete;
2416 req->length = 0;
2417 gadget->ep0->driver_data = cdev;
2418
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002419 list_for_each_entry(conf, &dev->configs, list_item)
taeju.park257b5082012-10-09 10:52:01 +09002420 list_for_each_entry(f, &conf->enabled_functions, enabled_list)
2421 if (f->ctrlrequest) {
2422 value = f->ctrlrequest(f, cdev, c);
2423 if (value >= 0)
2424 break;
2425 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002426
Benoit Gobycf3fc062011-12-19 14:39:37 -08002427 /* Special case the accessory function.
2428 * It needs to handle control requests before it is enabled.
2429 */
2430 if (value < 0)
2431 value = acc_ctrlrequest(cdev, c);
2432
Benoit Goby1e8ce152011-12-12 13:01:23 -08002433 if (value < 0)
2434 value = composite_setup(gadget, c);
2435
2436 spin_lock_irqsave(&cdev->lock, flags);
2437 if (!dev->connected) {
2438 dev->connected = 1;
2439 schedule_work(&dev->work);
2440 } else if (c->bRequest == USB_REQ_SET_CONFIGURATION &&
2441 cdev->config) {
2442 schedule_work(&dev->work);
2443 }
2444 spin_unlock_irqrestore(&cdev->lock, flags);
2445
2446 return value;
2447}
2448
2449static void android_disconnect(struct usb_gadget *gadget)
2450{
Benoit Goby1e8ce152011-12-12 13:01:23 -08002451 struct usb_composite_dev *cdev = get_gadget_data(gadget);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002452 struct android_dev *dev = cdev_to_android_dev(cdev);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002453 unsigned long flags;
2454
2455 composite_disconnect(gadget);
Ajay Dudanic2f0cc72012-08-27 16:23:48 +05302456 /* accessory HID support can be active while the
2457 accessory function is not actually enabled,
2458 so we need to inform it when we are disconnected.
2459 */
2460 acc_disconnect();
Benoit Goby1e8ce152011-12-12 13:01:23 -08002461
2462 spin_lock_irqsave(&cdev->lock, flags);
2463 dev->connected = 0;
2464 schedule_work(&dev->work);
2465 spin_unlock_irqrestore(&cdev->lock, flags);
2466}
2467
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002468static int android_create_device(struct android_dev *dev, u8 usb_core_id)
Benoit Goby1e8ce152011-12-12 13:01:23 -08002469{
2470 struct device_attribute **attrs = android_usb_attributes;
2471 struct device_attribute *attr;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002472 char device_node_name[ANDROID_DEVICE_NODE_NAME_LENGTH];
Benoit Goby1e8ce152011-12-12 13:01:23 -08002473 int err;
2474
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002475 /*
2476 * The primary usb core should always have usb_core_id=0, since
2477 * Android user space is currently interested in android0 events.
2478 */
2479 snprintf(device_node_name, ANDROID_DEVICE_NODE_NAME_LENGTH,
2480 "android%d", usb_core_id);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002481 dev->dev = device_create(android_class, NULL,
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002482 MKDEV(0, 0), NULL, device_node_name);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002483 if (IS_ERR(dev->dev))
2484 return PTR_ERR(dev->dev);
2485
2486 dev_set_drvdata(dev->dev, dev);
2487
2488 while ((attr = *attrs++)) {
2489 err = device_create_file(dev->dev, attr);
2490 if (err) {
2491 device_destroy(android_class, dev->dev->devt);
2492 return err;
2493 }
2494 }
2495 return 0;
2496}
2497
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05302498static void android_destroy_device(struct android_dev *dev)
Benoit Goby1e8ce152011-12-12 13:01:23 -08002499{
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05302500 struct device_attribute **attrs = android_usb_attributes;
2501 struct device_attribute *attr;
2502
2503 while ((attr = *attrs++))
2504 device_remove_file(dev->dev, attr);
2505 device_destroy(android_class, dev->dev->devt);
2506}
2507
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002508static struct android_dev *cdev_to_android_dev(struct usb_composite_dev *cdev)
2509{
2510 struct android_dev *dev = NULL;
2511
2512 /* Find the android dev from the list */
2513 list_for_each_entry(dev, &android_dev_list, list_item) {
2514 if (dev->cdev == cdev)
2515 break;
2516 }
2517
2518 return dev;
2519}
2520
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002521static struct android_configuration *alloc_android_config
2522 (struct android_dev *dev)
2523{
2524 struct android_configuration *conf;
2525
2526 conf = kzalloc(sizeof(*conf), GFP_KERNEL);
2527 if (!conf) {
2528 pr_err("%s(): Failed to alloc memory for android conf\n",
2529 __func__);
2530 return ERR_PTR(-ENOMEM);
2531 }
2532
2533 dev->configs_num++;
2534 conf->usb_config.label = dev->name;
2535 conf->usb_config.unbind = android_unbind_config;
2536 conf->usb_config.bConfigurationValue = dev->configs_num;
2537
2538 INIT_LIST_HEAD(&conf->enabled_functions);
2539
2540 list_add_tail(&conf->list_item, &dev->configs);
2541
2542 return conf;
2543}
2544
2545static void free_android_config(struct android_dev *dev,
2546 struct android_configuration *conf)
2547{
2548 list_del(&conf->list_item);
2549 dev->configs_num--;
2550 kfree(conf);
2551}
2552
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002553static int __devinit android_probe(struct platform_device *pdev)
2554{
2555 struct android_usb_platform_data *pdata = pdev->dev.platform_data;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002556 struct android_dev *android_dev;
Lena Salmand092f2d2012-03-12 17:27:24 +02002557 int ret = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002558
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002559 if (!android_class) {
2560 android_class = class_create(THIS_MODULE, "android_usb");
2561 if (IS_ERR(android_class))
2562 return PTR_ERR(android_class);
2563 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002564
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002565 android_dev = kzalloc(sizeof(*android_dev), GFP_KERNEL);
2566 if (!android_dev) {
2567 pr_err("%s(): Failed to alloc memory for android_dev\n",
2568 __func__);
2569 ret = -ENOMEM;
2570 goto err_alloc;
2571 }
Benoit Goby1e8ce152011-12-12 13:01:23 -08002572
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002573 android_dev->name = pdev->name;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002574 android_dev->disable_depth = 1;
2575 android_dev->functions = supported_functions;
Ido Shayevitz2a65e7c2012-08-02 13:34:18 +03002576 android_dev->configs_num = 0;
2577 INIT_LIST_HEAD(&android_dev->configs);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002578 INIT_WORK(&android_dev->work, android_work);
2579 mutex_init(&android_dev->mutex);
2580
2581 android_dev->pdata = pdata;
2582
2583 list_add_tail(&android_dev->list_item, &android_dev_list);
2584 android_dev_count++;
2585
2586 if (pdata)
2587 composite_driver.usb_core_id = pdata->usb_core_id;
2588 else
2589 composite_driver.usb_core_id = 0; /*To backward compatibility*/
2590
2591 ret = android_create_device(android_dev, composite_driver.usb_core_id);
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05302592 if (ret) {
2593 pr_err("%s(): android_create_device failed\n", __func__);
2594 goto err_dev;
2595 }
2596
Lena Salmand092f2d2012-03-12 17:27:24 +02002597 ret = usb_composite_probe(&android_usb_driver, android_bind);
2598 if (ret) {
2599 pr_err("%s(): Failed to register android "
2600 "composite driver\n", __func__);
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05302601 goto err_probe;
Lena Salmand092f2d2012-03-12 17:27:24 +02002602 }
2603
Ofir Cohen94213a72012-05-03 14:26:32 +03002604 /* pm qos request to prevent apps idle power collapse */
Manu Gautam94dc6142012-05-08 14:35:24 +05302605 if (pdata && pdata->swfi_latency)
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002606 pm_qos_add_request(&android_dev->pm_qos_req_dma,
Ofir Cohen94213a72012-05-03 14:26:32 +03002607 PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002608 strlcpy(android_dev->pm_qos, "high", sizeof(android_dev->pm_qos));
Ofir Cohen94213a72012-05-03 14:26:32 +03002609
Lena Salmand092f2d2012-03-12 17:27:24 +02002610 return ret;
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05302611err_probe:
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002612 android_destroy_device(android_dev);
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05302613err_dev:
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002614 list_del(&android_dev->list_item);
2615 android_dev_count--;
2616 kfree(android_dev);
2617err_alloc:
2618 if (list_empty(&android_dev_list)) {
2619 class_destroy(android_class);
2620 android_class = NULL;
2621 }
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05302622 return ret;
Lena Salmand092f2d2012-03-12 17:27:24 +02002623}
2624
2625static int android_remove(struct platform_device *pdev)
2626{
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002627 struct android_dev *dev = NULL;
Ofir Cohen94213a72012-05-03 14:26:32 +03002628 struct android_usb_platform_data *pdata = pdev->dev.platform_data;
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002629 int usb_core_id = 0;
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05302630
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002631 if (pdata)
2632 usb_core_id = pdata->usb_core_id;
2633
2634 /* Find the android dev from the list */
2635 list_for_each_entry(dev, &android_dev_list, list_item) {
2636 if (!dev->pdata)
2637 break; /*To backward compatibility*/
2638 if (dev->pdata->usb_core_id == usb_core_id)
2639 break;
2640 }
2641
2642 if (dev) {
2643 android_destroy_device(dev);
2644 if (pdata && pdata->swfi_latency)
2645 pm_qos_remove_request(&dev->pm_qos_req_dma);
2646 list_del(&dev->list_item);
2647 android_dev_count--;
2648 kfree(dev);
2649 }
2650
2651 if (list_empty(&android_dev_list)) {
2652 class_destroy(android_class);
2653 android_class = NULL;
2654 usb_composite_unregister(&android_usb_driver);
2655 }
Ofir Cohen94213a72012-05-03 14:26:32 +03002656
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002657 return 0;
2658}
2659
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002660static const struct platform_device_id android_id_table[] __devinitconst = {
2661 {
2662 .name = "android_usb",
2663 },
2664 {
2665 .name = "android_usb_hsic",
2666 },
2667};
2668
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002669static struct platform_driver android_platform_driver = {
2670 .driver = { .name = "android_usb"},
Lena Salmand092f2d2012-03-12 17:27:24 +02002671 .probe = android_probe,
2672 .remove = android_remove,
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002673 .id_table = android_id_table,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002674};
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05002675
2676static int __init init(void)
2677{
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05302678 int ret;
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05002679
Benoit Goby1e8ce152011-12-12 13:01:23 -08002680 /* Override composite driver functions */
2681 composite_driver.setup = android_setup;
2682 composite_driver.disconnect = android_disconnect;
2683
Ido Shayevitz23dc77c2012-07-18 16:16:06 +03002684 INIT_LIST_HEAD(&android_dev_list);
2685 android_dev_count = 0;
2686
Pavankumar Kondeti044914d2012-01-31 12:56:13 +05302687 ret = platform_driver_register(&android_platform_driver);
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05302688 if (ret) {
2689 pr_err("%s(): Failed to register android"
2690 "platform driver\n", __func__);
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05302691 }
Lena Salmand092f2d2012-03-12 17:27:24 +02002692
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05302693 return ret;
Benoit Goby1e8ce152011-12-12 13:01:23 -08002694}
2695module_init(init);
2696
2697static void __exit cleanup(void)
2698{
Lena Salmand092f2d2012-03-12 17:27:24 +02002699 platform_driver_unregister(&android_platform_driver);
Benoit Goby1e8ce152011-12-12 13:01:23 -08002700}
2701module_exit(cleanup);