blob: fd119c606f3f480ad96feb7b94f10d6c528faa63 [file] [log] [blame]
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05001/*
2 * Gadget Driver for Android
3 *
4 * Copyright (C) 2008 Google, Inc.
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05305 * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05006 * Author: Mike Lockwood <lockwood@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/* #define DEBUG */
20/* #define VERBOSE_DEBUG */
21
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/fs.h>
25
26#include <linux/delay.h>
27#include <linux/kernel.h>
28#include <linux/utsname.h>
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -050029#include <linux/platform_device.h>
30
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -050031#include <linux/usb/ch9.h>
32#include <linux/usb/composite.h>
33#include <linux/usb/gadget.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070034#include <linux/usb/android.h>
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -050035
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -050036#include "gadget_chips.h"
37
38/*
39 * Kbuild is not very cooperative with respect to linking separately
40 * compiled library objects into one module. So for now we won't use
41 * separate compilation ... ensuring init/exit sections work to shrink
42 * the runtime footprint, and giving us at least some parts of what
43 * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
44 */
45#include "usbstring.c"
46#include "config.c"
47#include "epautoconf.c"
48#include "composite.c"
49
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070050#include "f_diag.c"
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"
Benoit Gobyaab96812011-04-19 20:37:33 -070055#include "f_mass_storage.c"
Manu Gautama4d993f2011-08-30 18:25:55 +053056#include "u_serial.c"
57#include "u_sdio.c"
58#include "u_smd.c"
59#include "u_bam.c"
Manu Gautam2b0234a2011-09-07 16:47:52 +053060#include "u_rmnet_ctrl_smd.c"
Jack Pham427f6922011-11-23 19:42:00 -080061#include "u_ctrl_hsic.c"
62#include "u_data_hsic.c"
Manu Gautama4d993f2011-08-30 18:25:55 +053063#include "f_serial.c"
Anji jonnala92be1b42011-12-19 09:44:41 +053064#include "f_acm.c"
Benoit Gobyaab96812011-04-19 20:37:33 -070065#include "f_adb.c"
Chiranjeevi Velempatie130fd02011-11-29 05:06:13 +053066#include "f_ccid.c"
Benoit Gobyaab96812011-04-19 20:37:33 -070067#include "f_mtp.c"
68#include "f_accessory.c"
69#define USB_ETH_RNDIS y
70#include "f_rndis.c"
71#include "rndis.c"
72#include "u_ether.c"
Anna Perela8c991d2012-04-09 16:44:46 +030073#include "u_bam_data.c"
74#include "f_mbim.c"
Benoit Gobyaab96812011-04-19 20:37:33 -070075
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -050076MODULE_AUTHOR("Mike Lockwood");
77MODULE_DESCRIPTION("Android Composite USB Driver");
78MODULE_LICENSE("GPL");
79MODULE_VERSION("1.0");
80
81static const char longname[] = "Gadget Android";
82
Benoit Gobyaab96812011-04-19 20:37:33 -070083/* Default vendor and product IDs, overridden by userspace */
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -050084#define VENDOR_ID 0x18D1
85#define PRODUCT_ID 0x0001
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -050086
Benoit Gobyaab96812011-04-19 20:37:33 -070087struct android_usb_function {
88 char *name;
89 void *config;
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -050090
Benoit Gobyaab96812011-04-19 20:37:33 -070091 struct device *dev;
92 char *dev_name;
93 struct device_attribute **attributes;
94
95 /* for android_dev.enabled_functions */
96 struct list_head enabled_list;
97
98 /* Optional: initialization during gadget bind */
99 int (*init)(struct android_usb_function *, struct usb_composite_dev *);
100 /* Optional: cleanup during gadget unbind */
101 void (*cleanup)(struct android_usb_function *);
102
103 int (*bind_config)(struct android_usb_function *, struct usb_configuration *);
104
105 /* Optional: called when the configuration is removed */
106 void (*unbind_config)(struct android_usb_function *, struct usb_configuration *);
Mike Lockwood686d33a2011-09-07 09:55:12 -0700107 /* Optional: handle ctrl requests before the device is configured */
Benoit Gobyaab96812011-04-19 20:37:33 -0700108 int (*ctrlrequest)(struct android_usb_function *,
109 struct usb_composite_dev *,
110 const struct usb_ctrlrequest *);
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -0500111};
112
Benoit Gobyaab96812011-04-19 20:37:33 -0700113struct android_dev {
114 struct android_usb_function **functions;
115 struct list_head enabled_functions;
116 struct usb_composite_dev *cdev;
117 struct device *dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700118 struct android_usb_platform_data *pdata;
Benoit Gobyaab96812011-04-19 20:37:33 -0700119
120 bool enabled;
Benoit Gobydc1b6342011-12-09 18:05:00 -0800121 struct mutex mutex;
Benoit Gobyaab96812011-04-19 20:37:33 -0700122 bool connected;
123 bool sw_connected;
124 struct work_struct work;
125};
126
127static struct class *android_class;
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -0500128static struct android_dev *_android_dev;
Benoit Gobyaab96812011-04-19 20:37:33 -0700129static int android_bind_config(struct usb_configuration *c);
130static void android_unbind_config(struct usb_configuration *c);
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -0500131
132/* string IDs are assigned dynamically */
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -0500133#define STRING_MANUFACTURER_IDX 0
134#define STRING_PRODUCT_IDX 1
135#define STRING_SERIAL_IDX 2
136
Benoit Gobyaab96812011-04-19 20:37:33 -0700137static char manufacturer_string[256];
138static char product_string[256];
139static char serial_string[256];
140
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -0500141/* String Table */
142static struct usb_string strings_dev[] = {
Benoit Gobyaab96812011-04-19 20:37:33 -0700143 [STRING_MANUFACTURER_IDX].s = manufacturer_string,
144 [STRING_PRODUCT_IDX].s = product_string,
145 [STRING_SERIAL_IDX].s = serial_string,
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -0500146 { } /* end of list */
147};
148
149static struct usb_gadget_strings stringtab_dev = {
150 .language = 0x0409, /* en-us */
151 .strings = strings_dev,
152};
153
154static struct usb_gadget_strings *dev_strings[] = {
155 &stringtab_dev,
156 NULL,
157};
158
159static struct usb_device_descriptor device_desc = {
160 .bLength = sizeof(device_desc),
161 .bDescriptorType = USB_DT_DEVICE,
162 .bcdUSB = __constant_cpu_to_le16(0x0200),
163 .bDeviceClass = USB_CLASS_PER_INTERFACE,
164 .idVendor = __constant_cpu_to_le16(VENDOR_ID),
165 .idProduct = __constant_cpu_to_le16(PRODUCT_ID),
166 .bcdDevice = __constant_cpu_to_le16(0xffff),
167 .bNumConfigurations = 1,
168};
169
Vijayavardhan Vennapusa56e60522012-02-16 15:40:16 +0530170static struct usb_otg_descriptor otg_descriptor = {
171 .bLength = sizeof otg_descriptor,
172 .bDescriptorType = USB_DT_OTG,
173 .bmAttributes = USB_OTG_SRP | USB_OTG_HNP,
174 .bcdOTG = __constant_cpu_to_le16(0x0200),
175};
176
177static const struct usb_descriptor_header *otg_desc[] = {
178 (struct usb_descriptor_header *) &otg_descriptor,
179 NULL,
180};
181
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -0500182static struct usb_configuration android_config_driver = {
183 .label = "android",
Benoit Gobyaab96812011-04-19 20:37:33 -0700184 .unbind = android_unbind_config,
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -0500185 .bConfigurationValue = 1,
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -0500186};
187
Manu Gautama2b54142012-04-03 14:34:32 +0530188enum android_device_state {
189 USB_DISCONNECTED,
190 USB_CONNECTED,
191 USB_CONFIGURED,
192};
193
Benoit Gobyaab96812011-04-19 20:37:33 -0700194static void android_work(struct work_struct *data)
195{
196 struct android_dev *dev = container_of(data, struct android_dev, work);
197 struct usb_composite_dev *cdev = dev->cdev;
198 char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL };
199 char *connected[2] = { "USB_STATE=CONNECTED", NULL };
200 char *configured[2] = { "USB_STATE=CONFIGURED", NULL };
Dima Zavinfc753492011-09-14 11:52:45 -0700201 char **uevent_envp = NULL;
Manu Gautama2b54142012-04-03 14:34:32 +0530202 static enum android_device_state last_uevent, next_state;
Benoit Gobyaab96812011-04-19 20:37:33 -0700203 unsigned long flags;
204
205 spin_lock_irqsave(&cdev->lock, flags);
Manu Gautama2b54142012-04-03 14:34:32 +0530206 if (cdev->config) {
Dima Zavinfc753492011-09-14 11:52:45 -0700207 uevent_envp = configured;
Manu Gautama2b54142012-04-03 14:34:32 +0530208 next_state = USB_CONFIGURED;
209 } else if (dev->connected != dev->sw_connected) {
Dima Zavinf85cf4f2011-09-14 15:12:45 -0700210 uevent_envp = dev->connected ? connected : disconnected;
Manu Gautama2b54142012-04-03 14:34:32 +0530211 next_state = dev->connected ? USB_CONNECTED : USB_DISCONNECTED;
212 }
Dima Zavinf85cf4f2011-09-14 15:12:45 -0700213 dev->sw_connected = dev->connected;
Dima Zavinfc753492011-09-14 11:52:45 -0700214 spin_unlock_irqrestore(&cdev->lock, flags);
215
216 if (uevent_envp) {
Manu Gautama2b54142012-04-03 14:34:32 +0530217 /*
218 * Some userspace modules, e.g. MTP, work correctly only if
219 * CONFIGURED uevent is preceded by DISCONNECT uevent.
220 * Check if we missed sending out a DISCONNECT uevent. This can
221 * happen if host PC resets and configures device really quick.
222 */
223 if (((uevent_envp == connected) &&
224 (last_uevent != USB_DISCONNECTED)) ||
225 ((uevent_envp == configured) &&
226 (last_uevent == USB_CONFIGURED))) {
227 pr_info("%s: sent missed DISCONNECT event\n", __func__);
228 kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE,
229 disconnected);
230 msleep(20);
231 }
232 /*
233 * Before sending out CONFIGURED uevent give function drivers
234 * a chance to wakeup userspace threads and notify disconnect
235 */
236 if (uevent_envp == configured)
237 msleep(50);
238
Dima Zavinfc753492011-09-14 11:52:45 -0700239 kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE, uevent_envp);
Manu Gautama2b54142012-04-03 14:34:32 +0530240 last_uevent = next_state;
Dima Zavinfc753492011-09-14 11:52:45 -0700241 pr_info("%s: sent uevent %s\n", __func__, uevent_envp[0]);
Benoit Gobyaab96812011-04-19 20:37:33 -0700242 } else {
Dima Zavinfc753492011-09-14 11:52:45 -0700243 pr_info("%s: did not send uevent (%d %d %p)\n", __func__,
244 dev->connected, dev->sw_connected, cdev->config);
Benoit Gobyaab96812011-04-19 20:37:33 -0700245 }
246}
247
248
249/*-------------------------------------------------------------------------*/
250/* Supported functions initialization */
251
Manu Gautam8e0719b2011-09-26 14:47:55 +0530252/* RMNET_SMD */
Manu Gautam1c8ffd72011-09-02 16:00:49 +0530253static int rmnet_smd_function_bind_config(struct android_usb_function *f,
254 struct usb_configuration *c)
255{
256 return rmnet_smd_bind_config(c);
257}
258
259static struct android_usb_function rmnet_smd_function = {
260 .name = "rmnet_smd",
261 .bind_config = rmnet_smd_function_bind_config,
262};
263
Manu Gautam8e0719b2011-09-26 14:47:55 +0530264/* RMNET_SDIO */
265static int rmnet_sdio_function_bind_config(struct android_usb_function *f,
266 struct usb_configuration *c)
267{
268 return rmnet_sdio_function_add(c);
269}
270
271static struct android_usb_function rmnet_sdio_function = {
272 .name = "rmnet_sdio",
273 .bind_config = rmnet_sdio_function_bind_config,
274};
275
276/* RMNET_SMD_SDIO */
277static int rmnet_smd_sdio_function_init(struct android_usb_function *f,
278 struct usb_composite_dev *cdev)
279{
280 return rmnet_smd_sdio_init();
281}
282
283static void rmnet_smd_sdio_function_cleanup(struct android_usb_function *f)
284{
285 rmnet_smd_sdio_cleanup();
286}
287
288static int rmnet_smd_sdio_bind_config(struct android_usb_function *f,
289 struct usb_configuration *c)
290{
291 return rmnet_smd_sdio_function_add(c);
292}
293
294static struct device_attribute *rmnet_smd_sdio_attributes[] = {
295 &dev_attr_transport, NULL };
296
297static struct android_usb_function rmnet_smd_sdio_function = {
298 .name = "rmnet_smd_sdio",
299 .init = rmnet_smd_sdio_function_init,
300 .cleanup = rmnet_smd_sdio_function_cleanup,
301 .bind_config = rmnet_smd_sdio_bind_config,
302 .attributes = rmnet_smd_sdio_attributes,
303};
304
Hemant Kumar1b820d52011-11-03 15:08:28 -0700305/*rmnet transport string format(per port):"ctrl0,data0,ctrl1,data1..." */
306#define MAX_XPORT_STR_LEN 50
307static char rmnet_transports[MAX_XPORT_STR_LEN];
Manu Gautam1c8ffd72011-09-02 16:00:49 +0530308
Manu Gautame3e897c2011-09-12 17:18:46 +0530309static void rmnet_function_cleanup(struct android_usb_function *f)
310{
311 frmnet_cleanup();
312}
313
Manu Gautam2b0234a2011-09-07 16:47:52 +0530314static int rmnet_function_bind_config(struct android_usb_function *f,
315 struct usb_configuration *c)
316{
317 int i;
Hemant Kumar1b820d52011-11-03 15:08:28 -0700318 int err = 0;
319 char *ctrl_name;
320 char *data_name;
321 char buf[MAX_XPORT_STR_LEN], *b;
322 static int rmnet_initialized, ports;
Manu Gautam2b0234a2011-09-07 16:47:52 +0530323
Hemant Kumar1b820d52011-11-03 15:08:28 -0700324 if (!rmnet_initialized) {
325 rmnet_initialized = 1;
326 strlcpy(buf, rmnet_transports, sizeof(buf));
327 b = strim(buf);
328 while (b) {
329 ctrl_name = strsep(&b, ",");
330 data_name = strsep(&b, ",");
331 if (ctrl_name && data_name) {
332 err = frmnet_init_port(ctrl_name, data_name);
333 if (err) {
334 pr_err("rmnet: Cannot open ctrl port:"
335 "'%s' data port:'%s'\n",
336 ctrl_name, data_name);
337 goto out;
338 }
339 ports++;
340 }
341 }
342
343 err = rmnet_gport_setup();
344 if (err) {
345 pr_err("rmnet: Cannot setup transports");
346 goto out;
347 }
348 }
349
350 for (i = 0; i < ports; i++) {
351 err = frmnet_bind_config(c, i);
352 if (err) {
Manu Gautam2b0234a2011-09-07 16:47:52 +0530353 pr_err("Could not bind rmnet%u config\n", i);
354 break;
355 }
356 }
Hemant Kumar1b820d52011-11-03 15:08:28 -0700357out:
358 return err;
Manu Gautam2b0234a2011-09-07 16:47:52 +0530359}
360
Hemant Kumar1b820d52011-11-03 15:08:28 -0700361static ssize_t rmnet_transports_show(struct device *dev,
Manu Gautam2b0234a2011-09-07 16:47:52 +0530362 struct device_attribute *attr, char *buf)
363{
Hemant Kumar1b820d52011-11-03 15:08:28 -0700364 return snprintf(buf, PAGE_SIZE, "%s\n", rmnet_transports);
Manu Gautam2b0234a2011-09-07 16:47:52 +0530365}
366
Hemant Kumar1b820d52011-11-03 15:08:28 -0700367static ssize_t rmnet_transports_store(
368 struct device *device, struct device_attribute *attr,
369 const char *buff, size_t size)
Manu Gautam2b0234a2011-09-07 16:47:52 +0530370{
Hemant Kumar1b820d52011-11-03 15:08:28 -0700371 strlcpy(rmnet_transports, buff, sizeof(rmnet_transports));
Manu Gautam2b0234a2011-09-07 16:47:52 +0530372
Manu Gautam2b0234a2011-09-07 16:47:52 +0530373 return size;
374}
375
Hemant Kumar1b820d52011-11-03 15:08:28 -0700376static struct device_attribute dev_attr_rmnet_transports =
377 __ATTR(transports, S_IRUGO | S_IWUSR,
378 rmnet_transports_show,
379 rmnet_transports_store);
Manu Gautam2b0234a2011-09-07 16:47:52 +0530380static struct device_attribute *rmnet_function_attributes[] = {
Hemant Kumar1b820d52011-11-03 15:08:28 -0700381 &dev_attr_rmnet_transports,
382 NULL };
Manu Gautam2b0234a2011-09-07 16:47:52 +0530383
384static struct android_usb_function rmnet_function = {
385 .name = "rmnet",
Manu Gautame3e897c2011-09-12 17:18:46 +0530386 .cleanup = rmnet_function_cleanup,
Manu Gautam2b0234a2011-09-07 16:47:52 +0530387 .bind_config = rmnet_function_bind_config,
388 .attributes = rmnet_function_attributes,
389};
390
Anna Perela8c991d2012-04-09 16:44:46 +0300391
392/* MBIM - used with BAM */
393#define MAX_MBIM_INSTANCES 1
394
395static int mbim_function_init(struct android_usb_function *f,
396 struct usb_composite_dev *cdev)
397{
398 return mbim_init(MAX_MBIM_INSTANCES);
399}
400
401static void mbim_function_cleanup(struct android_usb_function *f)
402{
403 fmbim_cleanup();
404}
405
406static int mbim_function_bind_config(struct android_usb_function *f,
407 struct usb_configuration *c)
408{
409 return mbim_bind_config(c, 0);
410}
411
412static struct android_usb_function mbim_function = {
413 .name = "usb_mbim",
414 .cleanup = mbim_function_cleanup,
415 .bind_config = mbim_function_bind_config,
416 .init = mbim_function_init,
417};
418
419
Manu Gautam8e0719b2011-09-26 14:47:55 +0530420/* DIAG */
Manu Gautam2b0234a2011-09-07 16:47:52 +0530421static char diag_clients[32]; /*enabled DIAG clients- "diag[,diag_mdm]" */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700422static ssize_t clients_store(
423 struct device *device, struct device_attribute *attr,
424 const char *buff, size_t size)
425{
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +0530426 strlcpy(diag_clients, buff, sizeof(diag_clients));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700427
428 return size;
429}
430
431static DEVICE_ATTR(clients, S_IWUSR, NULL, clients_store);
432static struct device_attribute *diag_function_attributes[] =
433 { &dev_attr_clients, NULL };
434
435static int diag_function_init(struct android_usb_function *f,
436 struct usb_composite_dev *cdev)
437{
438 return diag_setup();
439}
440
441static void diag_function_cleanup(struct android_usb_function *f)
442{
443 diag_cleanup();
444}
445
446static int diag_function_bind_config(struct android_usb_function *f,
447 struct usb_configuration *c)
448{
449 char *name;
450 char buf[32], *b;
Manu Gautamc5760302011-08-25 14:30:24 +0530451 int once = 0, err = -1;
Jack Phamb830a6c2011-12-12 22:35:27 -0800452 int (*notify)(uint32_t, const char *);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700453
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +0530454 strlcpy(buf, diag_clients, sizeof(buf));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700455 b = strim(buf);
456
457 while (b) {
Jack Phamb830a6c2011-12-12 22:35:27 -0800458 notify = NULL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700459 name = strsep(&b, ",");
Manu Gautamc5760302011-08-25 14:30:24 +0530460 /* Allow only first diag channel to update pid and serial no */
Hemant Kumar1136c002011-10-18 22:04:06 -0700461 if (_android_dev->pdata && !once++)
Manu Gautamc5760302011-08-25 14:30:24 +0530462 notify = _android_dev->pdata->update_pid_and_serial_num;
Manu Gautamc5760302011-08-25 14:30:24 +0530463
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700464 if (name) {
Manu Gautamc5760302011-08-25 14:30:24 +0530465 err = diag_function_add(c, name, notify);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700466 if (err)
467 pr_err("diag: Cannot open channel '%s'", name);
468 }
469 }
470
471 return err;
472}
473
474static struct android_usb_function diag_function = {
475 .name = "diag",
476 .init = diag_function_init,
477 .cleanup = diag_function_cleanup,
478 .bind_config = diag_function_bind_config,
479 .attributes = diag_function_attributes,
480};
481
Manu Gautam8e0719b2011-09-26 14:47:55 +0530482/* SERIAL */
Manu Gautam2b0234a2011-09-07 16:47:52 +0530483static char serial_transports[32]; /*enabled FSERIAL ports - "tty[,sdio]"*/
Manu Gautama4d993f2011-08-30 18:25:55 +0530484static ssize_t serial_transports_store(
485 struct device *device, struct device_attribute *attr,
486 const char *buff, size_t size)
487{
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +0530488 strlcpy(serial_transports, buff, sizeof(serial_transports));
Manu Gautama4d993f2011-08-30 18:25:55 +0530489
490 return size;
491}
492
493static DEVICE_ATTR(transports, S_IWUSR, NULL, serial_transports_store);
494static struct device_attribute *serial_function_attributes[] =
495 { &dev_attr_transports, NULL };
496
497static void serial_function_cleanup(struct android_usb_function *f)
498{
499 gserial_cleanup();
500}
501
502static int serial_function_bind_config(struct android_usb_function *f,
503 struct usb_configuration *c)
504{
505 char *name;
506 char buf[32], *b;
507 int err = -1, i;
508 static int serial_initialized = 0, ports = 0;
509
510 if (serial_initialized)
511 goto bind_config;
512
513 serial_initialized = 1;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +0530514 strlcpy(buf, serial_transports, sizeof(buf));
Manu Gautama4d993f2011-08-30 18:25:55 +0530515 b = strim(buf);
516
517 while (b) {
518 name = strsep(&b, ",");
519
520 if (name) {
521 err = gserial_init_port(ports, name);
522 if (err) {
523 pr_err("serial: Cannot open port '%s'", name);
524 goto out;
525 }
526 ports++;
527 }
528 }
529 err = gport_setup(c);
530 if (err) {
531 pr_err("serial: Cannot setup transports");
532 goto out;
533 }
534
535bind_config:
Lena Salmand092f2d2012-03-12 17:27:24 +0200536 for (i = 0; i < ports; i++) {
Manu Gautama4d993f2011-08-30 18:25:55 +0530537 err = gser_bind_config(c, i);
538 if (err) {
539 pr_err("serial: bind_config failed for port %d", i);
540 goto out;
541 }
542 }
543
544out:
545 return err;
546}
547
548static struct android_usb_function serial_function = {
549 .name = "serial",
550 .cleanup = serial_function_cleanup,
551 .bind_config = serial_function_bind_config,
552 .attributes = serial_function_attributes,
553};
554
Anji jonnala92be1b42011-12-19 09:44:41 +0530555/* ACM */
556static char acm_transports[32]; /*enabled ACM ports - "tty[,sdio]"*/
557static ssize_t acm_transports_store(
558 struct device *device, struct device_attribute *attr,
559 const char *buff, size_t size)
560{
561 strlcpy(acm_transports, buff, sizeof(acm_transports));
562
563 return size;
564}
565
566static DEVICE_ATTR(acm_transports, S_IWUSR, NULL, acm_transports_store);
567static struct device_attribute *acm_function_attributes[] = {
568 &dev_attr_acm_transports, NULL };
569
570static void acm_function_cleanup(struct android_usb_function *f)
571{
572 gserial_cleanup();
573}
574
575static int acm_function_bind_config(struct android_usb_function *f,
576 struct usb_configuration *c)
577{
578 char *name;
579 char buf[32], *b;
580 int err = -1, i;
581 static int acm_initialized, ports;
582
583 if (acm_initialized)
584 goto bind_config;
585
586 acm_initialized = 1;
587 strlcpy(buf, acm_transports, sizeof(buf));
588 b = strim(buf);
589
590 while (b) {
591 name = strsep(&b, ",");
592
593 if (name) {
594 err = acm_init_port(ports, name);
595 if (err) {
596 pr_err("acm: Cannot open port '%s'", name);
597 goto out;
598 }
599 ports++;
600 }
601 }
602 err = acm_port_setup(c);
603 if (err) {
604 pr_err("acm: Cannot setup transports");
605 goto out;
606 }
607
608bind_config:
609 for (i = 0; i < ports; i++) {
610 err = acm_bind_config(c, i);
611 if (err) {
612 pr_err("acm: bind_config failed for port %d", i);
613 goto out;
614 }
615 }
616
617out:
618 return err;
619}
620static struct android_usb_function acm_function = {
621 .name = "acm",
622 .cleanup = acm_function_cleanup,
623 .bind_config = acm_function_bind_config,
624 .attributes = acm_function_attributes,
625};
Manu Gautama4d993f2011-08-30 18:25:55 +0530626
Manu Gautam8e0719b2011-09-26 14:47:55 +0530627/* ADB */
Benoit Gobyaab96812011-04-19 20:37:33 -0700628static int adb_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev)
629{
630 return adb_setup();
631}
632
633static void adb_function_cleanup(struct android_usb_function *f)
634{
635 adb_cleanup();
636}
637
638static int adb_function_bind_config(struct android_usb_function *f, struct usb_configuration *c)
639{
640 return adb_bind_config(c);
641}
642
643static struct android_usb_function adb_function = {
644 .name = "adb",
645 .init = adb_function_init,
646 .cleanup = adb_function_cleanup,
647 .bind_config = adb_function_bind_config,
648};
649
Chiranjeevi Velempatie130fd02011-11-29 05:06:13 +0530650/* CCID */
651static int ccid_function_init(struct android_usb_function *f,
652 struct usb_composite_dev *cdev)
653{
654 return ccid_setup();
655}
656
657static void ccid_function_cleanup(struct android_usb_function *f)
658{
659 ccid_cleanup();
660}
661
662static int ccid_function_bind_config(struct android_usb_function *f,
663 struct usb_configuration *c)
664{
665 return ccid_bind_config(c);
666}
667
668static struct android_usb_function ccid_function = {
669 .name = "ccid",
670 .init = ccid_function_init,
671 .cleanup = ccid_function_cleanup,
672 .bind_config = ccid_function_bind_config,
673};
674
Benoit Gobyaab96812011-04-19 20:37:33 -0700675static int mtp_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev)
676{
677 return mtp_setup();
678}
679
680static void mtp_function_cleanup(struct android_usb_function *f)
681{
682 mtp_cleanup();
683}
684
685static int mtp_function_bind_config(struct android_usb_function *f, struct usb_configuration *c)
686{
Mike Lockwoodcf7addf2011-06-01 22:17:36 -0400687 return mtp_bind_config(c, false);
688}
689
690static int ptp_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev)
691{
692 /* nothing to do - initialization is handled by mtp_function_init */
693 return 0;
694}
695
696static void ptp_function_cleanup(struct android_usb_function *f)
697{
698 /* nothing to do - cleanup is handled by mtp_function_cleanup */
699}
700
701static int ptp_function_bind_config(struct android_usb_function *f, struct usb_configuration *c)
702{
703 return mtp_bind_config(c, true);
Benoit Gobyaab96812011-04-19 20:37:33 -0700704}
705
706static int mtp_function_ctrlrequest(struct android_usb_function *f,
707 struct usb_composite_dev *cdev,
708 const struct usb_ctrlrequest *c)
709{
710 return mtp_ctrlrequest(cdev, c);
711}
712
713static struct android_usb_function mtp_function = {
714 .name = "mtp",
715 .init = mtp_function_init,
716 .cleanup = mtp_function_cleanup,
717 .bind_config = mtp_function_bind_config,
718 .ctrlrequest = mtp_function_ctrlrequest,
719};
720
Mike Lockwoodcf7addf2011-06-01 22:17:36 -0400721/* PTP function is same as MTP with slightly different interface descriptor */
722static struct android_usb_function ptp_function = {
723 .name = "ptp",
724 .init = ptp_function_init,
725 .cleanup = ptp_function_cleanup,
726 .bind_config = ptp_function_bind_config,
727};
728
Benoit Gobyaab96812011-04-19 20:37:33 -0700729
730struct rndis_function_config {
731 u8 ethaddr[ETH_ALEN];
732 u32 vendorID;
733 char manufacturer[256];
734 bool wceis;
735};
736
737static int rndis_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev)
738{
739 f->config = kzalloc(sizeof(struct rndis_function_config), GFP_KERNEL);
740 if (!f->config)
741 return -ENOMEM;
742 return 0;
743}
744
745static void rndis_function_cleanup(struct android_usb_function *f)
746{
747 kfree(f->config);
748 f->config = NULL;
749}
750
751static int rndis_function_bind_config(struct android_usb_function *f,
752 struct usb_configuration *c)
753{
Manu Gautamf4741132011-11-25 09:08:53 +0530754 int ret;
Benoit Gobyaab96812011-04-19 20:37:33 -0700755 struct rndis_function_config *rndis = f->config;
756
757 if (!rndis) {
758 pr_err("%s: rndis_pdata\n", __func__);
759 return -1;
760 }
761
762 pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
763 rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
764 rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
765
Manu Gautamf4741132011-11-25 09:08:53 +0530766 ret = gether_setup_name(c->cdev->gadget, rndis->ethaddr, "rndis");
767 if (ret) {
768 pr_err("%s: gether_setup failed\n", __func__);
769 return ret;
770 }
771
Benoit Gobyaab96812011-04-19 20:37:33 -0700772 if (rndis->wceis) {
773 /* "Wireless" RNDIS; auto-detected by Windows */
774 rndis_iad_descriptor.bFunctionClass =
775 USB_CLASS_WIRELESS_CONTROLLER;
776 rndis_iad_descriptor.bFunctionSubClass = 0x01;
777 rndis_iad_descriptor.bFunctionProtocol = 0x03;
778 rndis_control_intf.bInterfaceClass =
779 USB_CLASS_WIRELESS_CONTROLLER;
780 rndis_control_intf.bInterfaceSubClass = 0x01;
781 rndis_control_intf.bInterfaceProtocol = 0x03;
782 }
783
784 return rndis_bind_config(c, rndis->ethaddr, rndis->vendorID,
785 rndis->manufacturer);
786}
787
788static void rndis_function_unbind_config(struct android_usb_function *f,
789 struct usb_configuration *c)
790{
Manu Gautamf4741132011-11-25 09:08:53 +0530791 gether_cleanup();
Benoit Gobyaab96812011-04-19 20:37:33 -0700792}
793
794static ssize_t rndis_manufacturer_show(struct device *dev,
795 struct device_attribute *attr, char *buf)
796{
797 struct android_usb_function *f = dev_get_drvdata(dev);
798 struct rndis_function_config *config = f->config;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +0530799 return snprintf(buf, PAGE_SIZE, "%s\n", config->manufacturer);
Benoit Gobyaab96812011-04-19 20:37:33 -0700800}
801
802static ssize_t rndis_manufacturer_store(struct device *dev,
803 struct device_attribute *attr, const char *buf, size_t size)
804{
805 struct android_usb_function *f = dev_get_drvdata(dev);
806 struct rndis_function_config *config = f->config;
807
808 if (size >= sizeof(config->manufacturer))
809 return -EINVAL;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +0530810 if (sscanf(buf, "%255s", config->manufacturer) == 1)
Benoit Gobyaab96812011-04-19 20:37:33 -0700811 return size;
812 return -1;
813}
814
815static DEVICE_ATTR(manufacturer, S_IRUGO | S_IWUSR, rndis_manufacturer_show,
816 rndis_manufacturer_store);
817
818static ssize_t rndis_wceis_show(struct device *dev,
819 struct device_attribute *attr, char *buf)
820{
821 struct android_usb_function *f = dev_get_drvdata(dev);
822 struct rndis_function_config *config = f->config;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +0530823 return snprintf(buf, PAGE_SIZE, "%d\n", config->wceis);
Benoit Gobyaab96812011-04-19 20:37:33 -0700824}
825
826static ssize_t rndis_wceis_store(struct device *dev,
827 struct device_attribute *attr, const char *buf, size_t size)
828{
829 struct android_usb_function *f = dev_get_drvdata(dev);
830 struct rndis_function_config *config = f->config;
831 int value;
832
833 if (sscanf(buf, "%d", &value) == 1) {
834 config->wceis = value;
835 return size;
836 }
837 return -EINVAL;
838}
839
840static DEVICE_ATTR(wceis, S_IRUGO | S_IWUSR, rndis_wceis_show,
841 rndis_wceis_store);
842
843static ssize_t rndis_ethaddr_show(struct device *dev,
844 struct device_attribute *attr, char *buf)
845{
846 struct android_usb_function *f = dev_get_drvdata(dev);
847 struct rndis_function_config *rndis = f->config;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +0530848 return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n",
Benoit Gobyaab96812011-04-19 20:37:33 -0700849 rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
850 rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
851}
852
853static ssize_t rndis_ethaddr_store(struct device *dev,
854 struct device_attribute *attr, const char *buf, size_t size)
855{
856 struct android_usb_function *f = dev_get_drvdata(dev);
857 struct rndis_function_config *rndis = f->config;
858
859 if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
860 (int *)&rndis->ethaddr[0], (int *)&rndis->ethaddr[1],
861 (int *)&rndis->ethaddr[2], (int *)&rndis->ethaddr[3],
862 (int *)&rndis->ethaddr[4], (int *)&rndis->ethaddr[5]) == 6)
863 return size;
864 return -EINVAL;
865}
866
867static DEVICE_ATTR(ethaddr, S_IRUGO | S_IWUSR, rndis_ethaddr_show,
868 rndis_ethaddr_store);
869
870static ssize_t rndis_vendorID_show(struct device *dev,
871 struct device_attribute *attr, char *buf)
872{
873 struct android_usb_function *f = dev_get_drvdata(dev);
874 struct rndis_function_config *config = f->config;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +0530875 return snprintf(buf, PAGE_SIZE, "%04x\n", config->vendorID);
Benoit Gobyaab96812011-04-19 20:37:33 -0700876}
877
878static ssize_t rndis_vendorID_store(struct device *dev,
879 struct device_attribute *attr, const char *buf, size_t size)
880{
881 struct android_usb_function *f = dev_get_drvdata(dev);
882 struct rndis_function_config *config = f->config;
883 int value;
884
885 if (sscanf(buf, "%04x", &value) == 1) {
886 config->vendorID = value;
887 return size;
888 }
889 return -EINVAL;
890}
891
892static DEVICE_ATTR(vendorID, S_IRUGO | S_IWUSR, rndis_vendorID_show,
893 rndis_vendorID_store);
894
895static struct device_attribute *rndis_function_attributes[] = {
896 &dev_attr_manufacturer,
897 &dev_attr_wceis,
898 &dev_attr_ethaddr,
899 &dev_attr_vendorID,
900 NULL
901};
902
903static struct android_usb_function rndis_function = {
904 .name = "rndis",
905 .init = rndis_function_init,
906 .cleanup = rndis_function_cleanup,
907 .bind_config = rndis_function_bind_config,
908 .unbind_config = rndis_function_unbind_config,
909 .attributes = rndis_function_attributes,
910};
911
912
913struct mass_storage_function_config {
914 struct fsg_config fsg;
915 struct fsg_common *common;
916};
917
918static int mass_storage_function_init(struct android_usb_function *f,
919 struct usb_composite_dev *cdev)
920{
921 struct mass_storage_function_config *config;
922 struct fsg_common *common;
923 int err;
924
925 config = kzalloc(sizeof(struct mass_storage_function_config),
926 GFP_KERNEL);
927 if (!config)
928 return -ENOMEM;
929
930 config->fsg.nluns = 1;
931 config->fsg.luns[0].removable = 1;
932
933 common = fsg_common_init(NULL, cdev, &config->fsg);
934 if (IS_ERR(common)) {
935 kfree(config);
936 return PTR_ERR(common);
937 }
938
939 err = sysfs_create_link(&f->dev->kobj,
940 &common->luns[0].dev.kobj,
941 "lun");
942 if (err) {
Rajkumar Raghupathy01f599c2011-10-25 15:32:43 +0530943 fsg_common_release(&common->ref);
Benoit Gobyaab96812011-04-19 20:37:33 -0700944 kfree(config);
945 return err;
946 }
947
948 config->common = common;
949 f->config = config;
950 return 0;
951}
952
953static void mass_storage_function_cleanup(struct android_usb_function *f)
954{
955 kfree(f->config);
956 f->config = NULL;
957}
958
959static int mass_storage_function_bind_config(struct android_usb_function *f,
960 struct usb_configuration *c)
961{
962 struct mass_storage_function_config *config = f->config;
963 return fsg_bind_config(c->cdev, c, config->common);
964}
965
966static ssize_t mass_storage_inquiry_show(struct device *dev,
967 struct device_attribute *attr, char *buf)
968{
969 struct android_usb_function *f = dev_get_drvdata(dev);
970 struct mass_storage_function_config *config = f->config;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +0530971 return snprintf(buf, PAGE_SIZE, "%s\n", config->common->inquiry_string);
Benoit Gobyaab96812011-04-19 20:37:33 -0700972}
973
974static ssize_t mass_storage_inquiry_store(struct device *dev,
975 struct device_attribute *attr, const char *buf, size_t size)
976{
977 struct android_usb_function *f = dev_get_drvdata(dev);
978 struct mass_storage_function_config *config = f->config;
979 if (size >= sizeof(config->common->inquiry_string))
980 return -EINVAL;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +0530981 if (sscanf(buf, "%28s", config->common->inquiry_string) != 1)
Benoit Gobyaab96812011-04-19 20:37:33 -0700982 return -EINVAL;
983 return size;
984}
985
986static DEVICE_ATTR(inquiry_string, S_IRUGO | S_IWUSR,
987 mass_storage_inquiry_show,
988 mass_storage_inquiry_store);
989
990static struct device_attribute *mass_storage_function_attributes[] = {
991 &dev_attr_inquiry_string,
992 NULL
993};
994
995static struct android_usb_function mass_storage_function = {
996 .name = "mass_storage",
997 .init = mass_storage_function_init,
998 .cleanup = mass_storage_function_cleanup,
999 .bind_config = mass_storage_function_bind_config,
1000 .attributes = mass_storage_function_attributes,
1001};
1002
1003
1004static int accessory_function_init(struct android_usb_function *f,
1005 struct usb_composite_dev *cdev)
1006{
1007 return acc_setup();
1008}
1009
1010static void accessory_function_cleanup(struct android_usb_function *f)
1011{
1012 acc_cleanup();
1013}
1014
1015static int accessory_function_bind_config(struct android_usb_function *f,
1016 struct usb_configuration *c)
1017{
1018 return acc_bind_config(c);
1019}
1020
1021static int accessory_function_ctrlrequest(struct android_usb_function *f,
1022 struct usb_composite_dev *cdev,
1023 const struct usb_ctrlrequest *c)
1024{
1025 return acc_ctrlrequest(cdev, c);
1026}
1027
1028static struct android_usb_function accessory_function = {
1029 .name = "accessory",
1030 .init = accessory_function_init,
1031 .cleanup = accessory_function_cleanup,
1032 .bind_config = accessory_function_bind_config,
1033 .ctrlrequest = accessory_function_ctrlrequest,
1034};
1035
1036
1037static struct android_usb_function *supported_functions[] = {
Anna Perela8c991d2012-04-09 16:44:46 +03001038 &mbim_function,
Manu Gautam1c8ffd72011-09-02 16:00:49 +05301039 &rmnet_smd_function,
Manu Gautam8e0719b2011-09-26 14:47:55 +05301040 &rmnet_sdio_function,
1041 &rmnet_smd_sdio_function,
Manu Gautam2b0234a2011-09-07 16:47:52 +05301042 &rmnet_function,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001043 &diag_function,
Manu Gautama4d993f2011-08-30 18:25:55 +05301044 &serial_function,
Benoit Gobyaab96812011-04-19 20:37:33 -07001045 &adb_function,
Chiranjeevi Velempatie130fd02011-11-29 05:06:13 +05301046 &ccid_function,
Anji jonnala92be1b42011-12-19 09:44:41 +05301047 &acm_function,
Benoit Gobyaab96812011-04-19 20:37:33 -07001048 &mtp_function,
Mike Lockwoodcf7addf2011-06-01 22:17:36 -04001049 &ptp_function,
Benoit Gobyaab96812011-04-19 20:37:33 -07001050 &rndis_function,
1051 &mass_storage_function,
1052 &accessory_function,
1053 NULL
1054};
1055
Lena Salmand092f2d2012-03-12 17:27:24 +02001056static void android_cleanup_functions(struct android_usb_function **functions)
1057{
1058 struct android_usb_function *f;
1059 struct device_attribute **attrs;
1060 struct device_attribute *attr;
1061
1062 while (*functions) {
1063 f = *functions++;
1064
1065 if (f->dev) {
1066 device_destroy(android_class, f->dev->devt);
1067 kfree(f->dev_name);
1068 } else
1069 continue;
1070
1071 if (f->cleanup)
1072 f->cleanup(f);
1073
1074 attrs = f->attributes;
1075 if (attrs) {
1076 while ((attr = *attrs++))
1077 device_remove_file(f->dev, attr);
1078 }
1079 }
1080}
Benoit Gobyaab96812011-04-19 20:37:33 -07001081
1082static int android_init_functions(struct android_usb_function **functions,
1083 struct usb_composite_dev *cdev)
1084{
1085 struct android_dev *dev = _android_dev;
1086 struct android_usb_function *f;
1087 struct device_attribute **attrs;
1088 struct device_attribute *attr;
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301089 int err = 0;
Lena Salmand092f2d2012-03-12 17:27:24 +02001090 int index = 1; /* index 0 is for android0 device */
Benoit Gobyaab96812011-04-19 20:37:33 -07001091
1092 for (; (f = *functions++); index++) {
1093 f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name);
Lena Salmand092f2d2012-03-12 17:27:24 +02001094 if (!f->dev_name) {
1095 err = -ENOMEM;
1096 goto err_out;
1097 }
Benoit Gobyaab96812011-04-19 20:37:33 -07001098 f->dev = device_create(android_class, dev->dev,
1099 MKDEV(0, index), f, f->dev_name);
1100 if (IS_ERR(f->dev)) {
1101 pr_err("%s: Failed to create dev %s", __func__,
1102 f->dev_name);
1103 err = PTR_ERR(f->dev);
Lena Salmand092f2d2012-03-12 17:27:24 +02001104 f->dev = NULL;
Benoit Gobyaab96812011-04-19 20:37:33 -07001105 goto err_create;
1106 }
1107
1108 if (f->init) {
1109 err = f->init(f, cdev);
1110 if (err) {
1111 pr_err("%s: Failed to init %s", __func__,
1112 f->name);
Lena Salmand092f2d2012-03-12 17:27:24 +02001113 goto err_init;
Benoit Gobyaab96812011-04-19 20:37:33 -07001114 }
1115 }
1116
1117 attrs = f->attributes;
1118 if (attrs) {
1119 while ((attr = *attrs++) && !err)
1120 err = device_create_file(f->dev, attr);
1121 }
1122 if (err) {
1123 pr_err("%s: Failed to create function %s attributes",
1124 __func__, f->name);
Lena Salmand092f2d2012-03-12 17:27:24 +02001125 goto err_attrs;
Benoit Gobyaab96812011-04-19 20:37:33 -07001126 }
1127 }
1128 return 0;
1129
Lena Salmand092f2d2012-03-12 17:27:24 +02001130err_attrs:
1131 for (attr = *(attrs -= 2); attrs != f->attributes; attr = *(attrs--))
1132 device_remove_file(f->dev, attr);
1133 if (f->cleanup)
1134 f->cleanup(f);
1135err_init:
Benoit Gobyaab96812011-04-19 20:37:33 -07001136 device_destroy(android_class, f->dev->devt);
1137err_create:
Lena Salmand092f2d2012-03-12 17:27:24 +02001138 f->dev = NULL;
Benoit Gobyaab96812011-04-19 20:37:33 -07001139 kfree(f->dev_name);
Lena Salmand092f2d2012-03-12 17:27:24 +02001140err_out:
1141 android_cleanup_functions(dev->functions);
Benoit Gobyaab96812011-04-19 20:37:33 -07001142 return err;
1143}
1144
Benoit Gobyaab96812011-04-19 20:37:33 -07001145static int
1146android_bind_enabled_functions(struct android_dev *dev,
1147 struct usb_configuration *c)
1148{
1149 struct android_usb_function *f;
1150 int ret;
1151
1152 list_for_each_entry(f, &dev->enabled_functions, enabled_list) {
1153 ret = f->bind_config(f, c);
1154 if (ret) {
1155 pr_err("%s: %s failed", __func__, f->name);
1156 return ret;
1157 }
Krishna, Vamsi83814ea2009-02-11 21:07:20 +05301158 }
1159 return 0;
1160}
1161
Benoit Gobyaab96812011-04-19 20:37:33 -07001162static void
1163android_unbind_enabled_functions(struct android_dev *dev,
1164 struct usb_configuration *c)
Krishna, Vamsi83814ea2009-02-11 21:07:20 +05301165{
Benoit Gobyaab96812011-04-19 20:37:33 -07001166 struct android_usb_function *f;
1167
1168 list_for_each_entry(f, &dev->enabled_functions, enabled_list) {
1169 if (f->unbind_config)
1170 f->unbind_config(f, c);
1171 }
1172}
1173
1174static int android_enable_function(struct android_dev *dev, char *name)
1175{
1176 struct android_usb_function **functions = dev->functions;
1177 struct android_usb_function *f;
1178 while ((f = *functions++)) {
1179 if (!strcmp(name, f->name)) {
1180 list_add_tail(&f->enabled_list, &dev->enabled_functions);
Krishna, Vamsi83814ea2009-02-11 21:07:20 +05301181 return 0;
Mike Lockwoodaecca432011-02-09 09:38:26 -05001182 }
1183 }
Benoit Gobyaab96812011-04-19 20:37:33 -07001184 return -EINVAL;
Mike Lockwoodaecca432011-02-09 09:38:26 -05001185}
1186
Benoit Gobyaab96812011-04-19 20:37:33 -07001187/*-------------------------------------------------------------------------*/
1188/* /sys/class/android_usb/android%d/ interface */
Krishna, Vamsi83814ea2009-02-11 21:07:20 +05301189
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05301190static ssize_t remote_wakeup_show(struct device *pdev,
1191 struct device_attribute *attr, char *buf)
1192{
1193 return snprintf(buf, PAGE_SIZE, "%d\n",
1194 !!(android_config_driver.bmAttributes &
1195 USB_CONFIG_ATT_WAKEUP));
1196}
1197
1198static ssize_t remote_wakeup_store(struct device *pdev,
1199 struct device_attribute *attr, const char *buff, size_t size)
1200{
1201 int enable = 0;
1202
1203 sscanf(buff, "%d", &enable);
1204
1205 pr_debug("android_usb: %s remote wakeup\n",
1206 enable ? "enabling" : "disabling");
1207
1208 if (enable)
1209 android_config_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
1210 else
1211 android_config_driver.bmAttributes &= ~USB_CONFIG_ATT_WAKEUP;
1212
1213 return size;
1214}
1215
Benoit Gobyaab96812011-04-19 20:37:33 -07001216static ssize_t
1217functions_show(struct device *pdev, struct device_attribute *attr, char *buf)
1218{
1219 struct android_dev *dev = dev_get_drvdata(pdev);
1220 struct android_usb_function *f;
1221 char *buff = buf;
1222
Benoit Gobydc1b6342011-12-09 18:05:00 -08001223 mutex_lock(&dev->mutex);
1224
Benoit Gobyaab96812011-04-19 20:37:33 -07001225 list_for_each_entry(f, &dev->enabled_functions, enabled_list)
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301226 buff += snprintf(buff, PAGE_SIZE, "%s,", f->name);
Benoit Gobydc1b6342011-12-09 18:05:00 -08001227
1228 mutex_unlock(&dev->mutex);
1229
Benoit Gobyaab96812011-04-19 20:37:33 -07001230 if (buff != buf)
1231 *(buff-1) = '\n';
1232 return buff - buf;
1233}
1234
1235static ssize_t
1236functions_store(struct device *pdev, struct device_attribute *attr,
1237 const char *buff, size_t size)
1238{
1239 struct android_dev *dev = dev_get_drvdata(pdev);
1240 char *name;
1241 char buf[256], *b;
1242 int err;
1243
Benoit Gobydc1b6342011-12-09 18:05:00 -08001244 mutex_lock(&dev->mutex);
1245
1246 if (dev->enabled) {
1247 mutex_unlock(&dev->mutex);
1248 return -EBUSY;
1249 }
1250
Benoit Gobyaab96812011-04-19 20:37:33 -07001251 INIT_LIST_HEAD(&dev->enabled_functions);
1252
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301253 strlcpy(buf, buff, sizeof(buf));
Benoit Gobyaab96812011-04-19 20:37:33 -07001254 b = strim(buf);
1255
1256 while (b) {
1257 name = strsep(&b, ",");
1258 if (name) {
1259 err = android_enable_function(dev, name);
1260 if (err)
1261 pr_err("android_usb: Cannot enable '%s'", name);
Krishna, Vamsi83814ea2009-02-11 21:07:20 +05301262 }
1263 }
Benoit Gobyaab96812011-04-19 20:37:33 -07001264
Benoit Gobydc1b6342011-12-09 18:05:00 -08001265 mutex_unlock(&dev->mutex);
1266
Benoit Gobyaab96812011-04-19 20:37:33 -07001267 return size;
1268}
1269
1270static ssize_t enable_show(struct device *pdev, struct device_attribute *attr,
1271 char *buf)
1272{
1273 struct android_dev *dev = dev_get_drvdata(pdev);
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301274 return snprintf(buf, PAGE_SIZE, "%d\n", dev->enabled);
Benoit Gobyaab96812011-04-19 20:37:33 -07001275}
1276
1277static ssize_t enable_store(struct device *pdev, struct device_attribute *attr,
1278 const char *buff, size_t size)
1279{
1280 struct android_dev *dev = dev_get_drvdata(pdev);
1281 struct usb_composite_dev *cdev = dev->cdev;
1282 int enabled = 0;
1283
Benoit Gobydc1b6342011-12-09 18:05:00 -08001284 mutex_lock(&dev->mutex);
1285
Benoit Gobyaab96812011-04-19 20:37:33 -07001286 sscanf(buff, "%d", &enabled);
1287 if (enabled && !dev->enabled) {
1288 /* update values in composite driver's copy of device descriptor */
1289 cdev->desc.idVendor = device_desc.idVendor;
1290 cdev->desc.idProduct = device_desc.idProduct;
1291 cdev->desc.bcdDevice = device_desc.bcdDevice;
1292 cdev->desc.bDeviceClass = device_desc.bDeviceClass;
1293 cdev->desc.bDeviceSubClass = device_desc.bDeviceSubClass;
1294 cdev->desc.bDeviceProtocol = device_desc.bDeviceProtocol;
Manu Gautam05b9ca42011-10-14 17:12:40 +05301295 if (usb_add_config(cdev, &android_config_driver,
1296 android_bind_config))
1297 return size;
1298
Benoit Gobyaab96812011-04-19 20:37:33 -07001299 usb_gadget_connect(cdev->gadget);
1300 dev->enabled = true;
1301 } else if (!enabled && dev->enabled) {
1302 usb_gadget_disconnect(cdev->gadget);
Benoit Gobye0de0a52011-11-29 13:49:27 -08001303 /* Cancel pending control requests */
1304 usb_ep_dequeue(cdev->gadget->ep0, cdev->req);
Benoit Gobyaab96812011-04-19 20:37:33 -07001305 usb_remove_config(cdev, &android_config_driver);
1306 dev->enabled = false;
1307 } else {
1308 pr_err("android_usb: already %s\n",
1309 dev->enabled ? "enabled" : "disabled");
1310 }
Benoit Gobydc1b6342011-12-09 18:05:00 -08001311
1312 mutex_unlock(&dev->mutex);
Benoit Gobyaab96812011-04-19 20:37:33 -07001313 return size;
1314}
1315
1316static ssize_t state_show(struct device *pdev, struct device_attribute *attr,
1317 char *buf)
1318{
1319 struct android_dev *dev = dev_get_drvdata(pdev);
1320 struct usb_composite_dev *cdev = dev->cdev;
1321 char *state = "DISCONNECTED";
1322 unsigned long flags;
1323
1324 if (!cdev)
1325 goto out;
1326
1327 spin_lock_irqsave(&cdev->lock, flags);
1328 if (cdev->config)
1329 state = "CONFIGURED";
1330 else if (dev->connected)
1331 state = "CONNECTED";
1332 spin_unlock_irqrestore(&cdev->lock, flags);
1333out:
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301334 return snprintf(buf, PAGE_SIZE, "%s\n", state);
Benoit Gobyaab96812011-04-19 20:37:33 -07001335}
1336
1337#define DESCRIPTOR_ATTR(field, format_string) \
1338static ssize_t \
1339field ## _show(struct device *dev, struct device_attribute *attr, \
1340 char *buf) \
1341{ \
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301342 return snprintf(buf, PAGE_SIZE, \
1343 format_string, device_desc.field); \
Benoit Gobyaab96812011-04-19 20:37:33 -07001344} \
1345static ssize_t \
1346field ## _store(struct device *dev, struct device_attribute *attr, \
Benoit Gobydc1b6342011-12-09 18:05:00 -08001347 const char *buf, size_t size) \
Benoit Gobyaab96812011-04-19 20:37:33 -07001348{ \
Benoit Gobydc1b6342011-12-09 18:05:00 -08001349 int value; \
Benoit Gobyaab96812011-04-19 20:37:33 -07001350 if (sscanf(buf, format_string, &value) == 1) { \
1351 device_desc.field = value; \
1352 return size; \
1353 } \
1354 return -1; \
1355} \
1356static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store);
1357
1358#define DESCRIPTOR_STRING_ATTR(field, buffer) \
1359static ssize_t \
1360field ## _show(struct device *dev, struct device_attribute *attr, \
1361 char *buf) \
1362{ \
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301363 return snprintf(buf, PAGE_SIZE, "%s", buffer); \
Benoit Gobyaab96812011-04-19 20:37:33 -07001364} \
1365static ssize_t \
1366field ## _store(struct device *dev, struct device_attribute *attr, \
Benoit Gobydc1b6342011-12-09 18:05:00 -08001367 const char *buf, size_t size) \
Benoit Gobyaab96812011-04-19 20:37:33 -07001368{ \
1369 if (size >= sizeof(buffer)) return -EINVAL; \
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301370 if (sscanf(buf, "%255s", buffer) == 1) { \
Benoit Gobyaab96812011-04-19 20:37:33 -07001371 return size; \
1372 } \
1373 return -1; \
1374} \
1375static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store);
1376
1377
1378DESCRIPTOR_ATTR(idVendor, "%04x\n")
1379DESCRIPTOR_ATTR(idProduct, "%04x\n")
1380DESCRIPTOR_ATTR(bcdDevice, "%04x\n")
1381DESCRIPTOR_ATTR(bDeviceClass, "%d\n")
1382DESCRIPTOR_ATTR(bDeviceSubClass, "%d\n")
1383DESCRIPTOR_ATTR(bDeviceProtocol, "%d\n")
1384DESCRIPTOR_STRING_ATTR(iManufacturer, manufacturer_string)
1385DESCRIPTOR_STRING_ATTR(iProduct, product_string)
1386DESCRIPTOR_STRING_ATTR(iSerial, serial_string)
1387
1388static DEVICE_ATTR(functions, S_IRUGO | S_IWUSR, functions_show, functions_store);
1389static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store);
1390static DEVICE_ATTR(state, S_IRUGO, state_show, NULL);
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05301391static DEVICE_ATTR(remote_wakeup, S_IRUGO | S_IWUSR,
1392 remote_wakeup_show, remote_wakeup_store);
Benoit Gobyaab96812011-04-19 20:37:33 -07001393
1394static struct device_attribute *android_usb_attributes[] = {
1395 &dev_attr_idVendor,
1396 &dev_attr_idProduct,
1397 &dev_attr_bcdDevice,
1398 &dev_attr_bDeviceClass,
1399 &dev_attr_bDeviceSubClass,
1400 &dev_attr_bDeviceProtocol,
1401 &dev_attr_iManufacturer,
1402 &dev_attr_iProduct,
1403 &dev_attr_iSerial,
1404 &dev_attr_functions,
1405 &dev_attr_enable,
1406 &dev_attr_state,
Pavankumar Kondeti352396c2011-12-07 13:32:40 +05301407 &dev_attr_remote_wakeup,
Benoit Gobyaab96812011-04-19 20:37:33 -07001408 NULL
1409};
1410
1411/*-------------------------------------------------------------------------*/
1412/* Composite driver */
1413
1414static int android_bind_config(struct usb_configuration *c)
1415{
1416 struct android_dev *dev = _android_dev;
1417 int ret = 0;
1418
1419 ret = android_bind_enabled_functions(dev, c);
1420 if (ret)
1421 return ret;
1422
1423 return 0;
1424}
1425
1426static void android_unbind_config(struct usb_configuration *c)
1427{
1428 struct android_dev *dev = _android_dev;
1429
1430 android_unbind_enabled_functions(dev, c);
Krishna, Vamsi83814ea2009-02-11 21:07:20 +05301431}
1432
Dmitry Shmidt577e37a2010-07-02 12:46:34 -07001433static int android_bind(struct usb_composite_dev *cdev)
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05001434{
1435 struct android_dev *dev = _android_dev;
1436 struct usb_gadget *gadget = cdev->gadget;
Mike Lockwoodaecca432011-02-09 09:38:26 -05001437 int gcnum, id, ret;
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05001438
Benoit Gobyaab96812011-04-19 20:37:33 -07001439 usb_gadget_disconnect(gadget);
1440
1441 ret = android_init_functions(dev->functions, cdev);
1442 if (ret)
1443 return ret;
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05001444
1445 /* Allocate string descriptor numbers ... note that string
1446 * contents can be overridden by the composite_dev glue.
1447 */
1448 id = usb_string_id(cdev);
1449 if (id < 0)
1450 return id;
1451 strings_dev[STRING_MANUFACTURER_IDX].id = id;
1452 device_desc.iManufacturer = id;
1453
1454 id = usb_string_id(cdev);
1455 if (id < 0)
1456 return id;
1457 strings_dev[STRING_PRODUCT_IDX].id = id;
1458 device_desc.iProduct = id;
1459
Benoit Gobyaab96812011-04-19 20:37:33 -07001460 /* Default strings - should be updated by userspace */
Rajkumar Raghupathy42ec8da2011-10-21 18:58:53 +05301461 strlcpy(manufacturer_string, "Android",
1462 sizeof(manufacturer_string) - 1);
1463 strlcpy(product_string, "Android", sizeof(product_string) - 1);
1464 strlcpy(serial_string, "0123456789ABCDEF", sizeof(serial_string) - 1);
Benoit Gobyaab96812011-04-19 20:37:33 -07001465
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05001466 id = usb_string_id(cdev);
1467 if (id < 0)
1468 return id;
1469 strings_dev[STRING_SERIAL_IDX].id = id;
1470 device_desc.iSerialNumber = id;
1471
Vijayavardhan Vennapusa56e60522012-02-16 15:40:16 +05301472 if (gadget_is_otg(cdev->gadget))
1473 android_config_driver.descriptors = otg_desc;
1474
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05001475 gcnum = usb_gadget_controller_number(gadget);
1476 if (gcnum >= 0)
1477 device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
1478 else {
1479 /* gadget zero is so simple (for now, no altsettings) that
1480 * it SHOULD NOT have problems with bulk-capable hardware.
1481 * so just warn about unrcognized controllers -- don't panic.
1482 *
1483 * things like configuration and altsetting numbering
1484 * can need hardware-specific attention though.
1485 */
1486 pr_warning("%s: controller '%s' not recognized\n",
1487 longname, gadget->name);
1488 device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
1489 }
1490
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05001491 dev->cdev = cdev;
1492
1493 return 0;
1494}
1495
Benoit Gobyaab96812011-04-19 20:37:33 -07001496static int android_usb_unbind(struct usb_composite_dev *cdev)
1497{
1498 struct android_dev *dev = _android_dev;
1499
Lena Salmand092f2d2012-03-12 17:27:24 +02001500 manufacturer_string[0] = '\0';
1501 product_string[0] = '\0';
1502 serial_string[0] = '0';
Benoit Gobyaab96812011-04-19 20:37:33 -07001503 cancel_work_sync(&dev->work);
1504 android_cleanup_functions(dev->functions);
1505 return 0;
1506}
1507
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05001508static struct usb_composite_driver android_usb_driver = {
1509 .name = "android_usb",
1510 .dev = &device_desc,
1511 .strings = dev_strings,
Benoit Gobyaab96812011-04-19 20:37:33 -07001512 .unbind = android_usb_unbind,
Tatyana Brokhman3ba28902011-06-29 16:41:49 +03001513 .max_speed = USB_SPEED_SUPER
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05001514};
1515
Benoit Gobyaab96812011-04-19 20:37:33 -07001516static int
1517android_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *c)
1518{
1519 struct android_dev *dev = _android_dev;
1520 struct usb_composite_dev *cdev = get_gadget_data(gadget);
1521 struct usb_request *req = cdev->req;
Benoit Gobyaab96812011-04-19 20:37:33 -07001522 struct android_usb_function *f;
1523 int value = -EOPNOTSUPP;
1524 unsigned long flags;
1525
1526 req->zero = 0;
1527 req->complete = composite_setup_complete;
1528 req->length = 0;
1529 gadget->ep0->driver_data = cdev;
1530
Mike Lockwood6c7dd4b2011-08-02 11:13:48 -04001531 list_for_each_entry(f, &dev->enabled_functions, enabled_list) {
Benoit Gobyaab96812011-04-19 20:37:33 -07001532 if (f->ctrlrequest) {
1533 value = f->ctrlrequest(f, cdev, c);
1534 if (value >= 0)
1535 break;
1536 }
1537 }
1538
Mike Lockwood686d33a2011-09-07 09:55:12 -07001539 /* Special case the accessory function.
1540 * It needs to handle control requests before it is enabled.
1541 */
1542 if (value < 0)
1543 value = acc_ctrlrequest(cdev, c);
1544
Benoit Gobyaab96812011-04-19 20:37:33 -07001545 if (value < 0)
1546 value = composite_setup(gadget, c);
1547
1548 spin_lock_irqsave(&cdev->lock, flags);
1549 if (!dev->connected) {
1550 dev->connected = 1;
1551 schedule_work(&dev->work);
1552 }
1553 else if (c->bRequest == USB_REQ_SET_CONFIGURATION && cdev->config) {
1554 schedule_work(&dev->work);
1555 }
1556 spin_unlock_irqrestore(&cdev->lock, flags);
1557
1558 return value;
1559}
1560
1561static void android_disconnect(struct usb_gadget *gadget)
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05001562{
Krishna, Vamsi83814ea2009-02-11 21:07:20 +05301563 struct android_dev *dev = _android_dev;
Dima Zavin21bad752011-09-14 11:53:11 -07001564 struct usb_composite_dev *cdev = get_gadget_data(gadget);
1565 unsigned long flags;
1566
1567 composite_disconnect(gadget);
1568
1569 spin_lock_irqsave(&cdev->lock, flags);
Benoit Gobyaab96812011-04-19 20:37:33 -07001570 dev->connected = 0;
1571 schedule_work(&dev->work);
Dima Zavin21bad752011-09-14 11:53:11 -07001572 spin_unlock_irqrestore(&cdev->lock, flags);
Krishna, Vamsi83814ea2009-02-11 21:07:20 +05301573}
1574
Benoit Gobyaab96812011-04-19 20:37:33 -07001575static int android_create_device(struct android_dev *dev)
John Michelaud5d2de62010-12-10 11:33:54 -06001576{
Benoit Gobyaab96812011-04-19 20:37:33 -07001577 struct device_attribute **attrs = android_usb_attributes;
1578 struct device_attribute *attr;
1579 int err;
John Michelaud5d2de62010-12-10 11:33:54 -06001580
Benoit Gobyaab96812011-04-19 20:37:33 -07001581 dev->dev = device_create(android_class, NULL,
1582 MKDEV(0, 0), NULL, "android0");
1583 if (IS_ERR(dev->dev))
1584 return PTR_ERR(dev->dev);
John Michelaud5d2de62010-12-10 11:33:54 -06001585
Benoit Gobyaab96812011-04-19 20:37:33 -07001586 dev_set_drvdata(dev->dev, dev);
1587
1588 while ((attr = *attrs++)) {
1589 err = device_create_file(dev->dev, attr);
1590 if (err) {
1591 device_destroy(android_class, dev->dev->devt);
1592 return err;
John Michelaud5d2de62010-12-10 11:33:54 -06001593 }
1594 }
Benoit Gobyaab96812011-04-19 20:37:33 -07001595 return 0;
John Michelaud5d2de62010-12-10 11:33:54 -06001596}
1597
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05301598static void android_destroy_device(struct android_dev *dev)
1599{
1600 struct device_attribute **attrs = android_usb_attributes;
1601 struct device_attribute *attr;
1602
1603 while ((attr = *attrs++))
1604 device_remove_file(dev->dev, attr);
1605 device_destroy(android_class, dev->dev->devt);
1606}
1607
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001608static int __devinit android_probe(struct platform_device *pdev)
1609{
1610 struct android_usb_platform_data *pdata = pdev->dev.platform_data;
1611 struct android_dev *dev = _android_dev;
Lena Salmand092f2d2012-03-12 17:27:24 +02001612 int ret = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001613
1614 dev->pdata = pdata;
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05301615
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05301616 android_class = class_create(THIS_MODULE, "android_usb");
1617 if (IS_ERR(android_class))
1618 return PTR_ERR(android_class);
1619
1620 ret = android_create_device(dev);
1621 if (ret) {
1622 pr_err("%s(): android_create_device failed\n", __func__);
1623 goto err_dev;
1624 }
1625
Lena Salmand092f2d2012-03-12 17:27:24 +02001626 ret = usb_composite_probe(&android_usb_driver, android_bind);
1627 if (ret) {
1628 pr_err("%s(): Failed to register android "
1629 "composite driver\n", __func__);
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05301630 goto err_probe;
Lena Salmand092f2d2012-03-12 17:27:24 +02001631 }
1632
1633 return ret;
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05301634err_probe:
1635 android_destroy_device(dev);
1636err_dev:
1637 class_destroy(android_class);
1638 return ret;
Lena Salmand092f2d2012-03-12 17:27:24 +02001639}
1640
1641static int android_remove(struct platform_device *pdev)
1642{
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05301643 struct android_dev *dev = _android_dev;
1644
1645 android_destroy_device(dev);
1646 class_destroy(android_class);
Lena Salmand092f2d2012-03-12 17:27:24 +02001647 usb_composite_unregister(&android_usb_driver);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001648 return 0;
1649}
1650
1651static struct platform_driver android_platform_driver = {
1652 .driver = { .name = "android_usb"},
Lena Salmand092f2d2012-03-12 17:27:24 +02001653 .probe = android_probe,
1654 .remove = android_remove,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001655};
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05001656
1657static int __init init(void)
1658{
1659 struct android_dev *dev;
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05301660 int ret;
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05001661
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05001662 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05301663 if (!dev) {
1664 pr_err("%s(): Failed to alloc memory for android_dev\n",
1665 __func__);
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05001666 return -ENOMEM;
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05301667 }
Benoit Gobyaab96812011-04-19 20:37:33 -07001668 dev->functions = supported_functions;
1669 INIT_LIST_HEAD(&dev->enabled_functions);
1670 INIT_WORK(&dev->work, android_work);
Benoit Gobydc1b6342011-12-09 18:05:00 -08001671 mutex_init(&dev->mutex);
Benoit Gobyaab96812011-04-19 20:37:33 -07001672
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05001673 _android_dev = dev;
1674
Benoit Gobyaab96812011-04-19 20:37:33 -07001675 /* Override composite driver functions */
1676 composite_driver.setup = android_setup;
1677 composite_driver.disconnect = android_disconnect;
1678
Pavankumar Kondeti044914d2012-01-31 12:56:13 +05301679 ret = platform_driver_register(&android_platform_driver);
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05301680 if (ret) {
1681 pr_err("%s(): Failed to register android"
1682 "platform driver\n", __func__);
Rajkumar Raghupathy5d3fc392012-04-11 16:53:19 +05301683 kfree(dev);
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05301684 }
Lena Salmand092f2d2012-03-12 17:27:24 +02001685
Rajkumar Raghupathya1df77e2012-01-19 17:45:55 +05301686 return ret;
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05001687}
1688module_init(init);
1689
1690static void __exit cleanup(void)
1691{
Lena Salmand092f2d2012-03-12 17:27:24 +02001692 platform_driver_unregister(&android_platform_driver);
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05001693 kfree(_android_dev);
Mike Lockwood7f0d7bd2008-12-02 22:01:33 -05001694 _android_dev = NULL;
1695}
1696module_exit(cleanup);