2 * cdc2.c -- CDC Composite driver, with ECM and ACM support
4 * Copyright (C) 2008 David Brownell
5 * Copyright (C) 2008 Nokia Corporation
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
13 #include <linux/kernel.h>
14 #include <linux/module.h>
21 #define DRIVER_DESC "CDC Composite Gadget"
22 #define DRIVER_VERSION "King Kamehameha Day 2008"
24 /*-------------------------------------------------------------------------*/
26 /* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!!
27 * Instead: allocate your own, using normal USB-IF procedures.
30 /* Thanks to NetChip Technologies for donating this product ID.
31 * It's for devices with only this composite CDC configuration.
33 #define CDC_VENDOR_NUM 0x0525 /* NetChip */
34 #define CDC_PRODUCT_NUM 0xa4aa /* CDC Composite: ECM + ACM */
36 USB_GADGET_COMPOSITE_OPTIONS();
38 USB_ETHERNET_MODULE_PARAMETERS();
40 /*-------------------------------------------------------------------------*/
42 static struct usb_device_descriptor device_desc
= {
43 .bLength
= sizeof device_desc
,
44 .bDescriptorType
= USB_DT_DEVICE
,
46 .bcdUSB
= cpu_to_le16(0x0200),
48 .bDeviceClass
= USB_CLASS_COMM
,
51 /* .bMaxPacketSize0 = f(hardware) */
53 /* Vendor and product id can be overridden by module parameters. */
54 .idVendor
= cpu_to_le16(CDC_VENDOR_NUM
),
55 .idProduct
= cpu_to_le16(CDC_PRODUCT_NUM
),
56 /* .bcdDevice = f(hardware) */
57 /* .iManufacturer = DYNAMIC */
58 /* .iProduct = DYNAMIC */
59 /* NO SERIAL NUMBER */
60 .bNumConfigurations
= 1,
63 static struct usb_otg_descriptor otg_descriptor
= {
64 .bLength
= sizeof otg_descriptor
,
65 .bDescriptorType
= USB_DT_OTG
,
67 /* REVISIT SRP-only hardware is possible, although
68 * it would not be called "OTG" ...
70 .bmAttributes
= USB_OTG_SRP
| USB_OTG_HNP
,
73 static const struct usb_descriptor_header
*otg_desc
[] = {
74 (struct usb_descriptor_header
*) &otg_descriptor
,
79 /* string IDs are assigned dynamically */
80 static struct usb_string strings_dev
[] = {
81 [USB_GADGET_MANUFACTURER_IDX
].s
= "",
82 [USB_GADGET_PRODUCT_IDX
].s
= DRIVER_DESC
,
83 [USB_GADGET_SERIAL_IDX
].s
= "",
87 static struct usb_gadget_strings stringtab_dev
= {
88 .language
= 0x0409, /* en-us */
89 .strings
= strings_dev
,
92 static struct usb_gadget_strings
*dev_strings
[] = {
97 /*-------------------------------------------------------------------------*/
98 static struct usb_function
*f_acm
;
99 static struct usb_function_instance
*fi_serial
;
101 static struct usb_function
*f_ecm
;
102 static struct usb_function_instance
*fi_ecm
;
105 * We _always_ have both CDC ECM and CDC ACM functions.
107 static int cdc_do_config(struct usb_configuration
*c
)
111 if (gadget_is_otg(c
->cdev
->gadget
)) {
112 c
->descriptors
= otg_desc
;
113 c
->bmAttributes
|= USB_CONFIG_ATT_WAKEUP
;
116 f_ecm
= usb_get_function(fi_ecm
);
118 status
= PTR_ERR(f_ecm
);
122 status
= usb_add_function(c
, f_ecm
);
126 f_acm
= usb_get_function(fi_serial
);
128 status
= PTR_ERR(f_acm
);
132 status
= usb_add_function(c
, f_acm
);
138 usb_put_function(f_acm
);
140 usb_remove_function(c
, f_ecm
);
142 usb_put_function(f_ecm
);
147 static struct usb_configuration cdc_config_driver
= {
148 .label
= "CDC Composite (ECM + ACM)",
149 .bConfigurationValue
= 1,
150 /* .iConfiguration = DYNAMIC */
151 .bmAttributes
= USB_CONFIG_ATT_SELFPOWER
,
154 /*-------------------------------------------------------------------------*/
156 static int cdc_bind(struct usb_composite_dev
*cdev
)
158 struct usb_gadget
*gadget
= cdev
->gadget
;
159 struct f_ecm_opts
*ecm_opts
;
162 if (!can_support_ecm(cdev
->gadget
)) {
163 dev_err(&gadget
->dev
, "controller '%s' not usable\n",
168 fi_ecm
= usb_get_function_instance("ecm");
170 return PTR_ERR(fi_ecm
);
172 ecm_opts
= container_of(fi_ecm
, struct f_ecm_opts
, func_inst
);
174 gether_set_qmult(ecm_opts
->net
, qmult
);
175 if (!gether_set_host_addr(ecm_opts
->net
, host_addr
))
176 pr_info("using host ethernet address: %s", host_addr
);
177 if (!gether_set_dev_addr(ecm_opts
->net
, dev_addr
))
178 pr_info("using self ethernet address: %s", dev_addr
);
180 fi_serial
= usb_get_function_instance("acm");
181 if (IS_ERR(fi_serial
)) {
182 status
= PTR_ERR(fi_serial
);
186 /* Allocate string descriptor numbers ... note that string
187 * contents can be overridden by the composite_dev glue.
190 status
= usb_string_ids_tab(cdev
, strings_dev
);
193 device_desc
.iManufacturer
= strings_dev
[USB_GADGET_MANUFACTURER_IDX
].id
;
194 device_desc
.iProduct
= strings_dev
[USB_GADGET_PRODUCT_IDX
].id
;
196 /* register our configuration */
197 status
= usb_add_config(cdev
, &cdc_config_driver
, cdc_do_config
);
201 usb_composite_overwrite_options(cdev
, &coverwrite
);
202 dev_info(&gadget
->dev
, "%s, version: " DRIVER_VERSION
"\n",
208 usb_put_function_instance(fi_serial
);
210 usb_put_function_instance(fi_ecm
);
214 static int cdc_unbind(struct usb_composite_dev
*cdev
)
216 usb_put_function(f_acm
);
217 usb_put_function_instance(fi_serial
);
218 if (!IS_ERR_OR_NULL(f_ecm
))
219 usb_put_function(f_ecm
);
220 if (!IS_ERR_OR_NULL(fi_ecm
))
221 usb_put_function_instance(fi_ecm
);
225 static struct usb_composite_driver cdc_driver
= {
228 .strings
= dev_strings
,
229 .max_speed
= USB_SPEED_HIGH
,
231 .unbind
= cdc_unbind
,
234 module_usb_composite_driver(cdc_driver
);
236 MODULE_DESCRIPTION(DRIVER_DESC
);
237 MODULE_AUTHOR("David Brownell");
238 MODULE_LICENSE("GPL");