|
@@ -37,8 +37,6 @@
|
|
|
* the runtime footprint, and giving us at least some parts of what
|
|
|
* a "gcc --combine ... part1.c part2.c part3.c ... " build would.
|
|
|
*/
|
|
|
-#define USB_FACM_INCLUDED
|
|
|
-#include "f_acm.c"
|
|
|
#include "f_ecm.c"
|
|
|
#include "f_obex.c"
|
|
|
#include "f_serial.c"
|
|
@@ -98,7 +96,8 @@ MODULE_AUTHOR("Felipe Balbi");
|
|
|
MODULE_LICENSE("GPL");
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
-
|
|
|
+static struct usb_function *f_acm_cfg1;
|
|
|
+static struct usb_function *f_acm_cfg2;
|
|
|
static u8 hostaddr[ETH_ALEN];
|
|
|
|
|
|
enum {
|
|
@@ -110,8 +109,27 @@ enum {
|
|
|
|
|
|
static unsigned char tty_lines[TTY_PORTS_MAX];
|
|
|
|
|
|
+static struct usb_configuration nokia_config_500ma_driver = {
|
|
|
+ .label = "Bus Powered",
|
|
|
+ .bConfigurationValue = 1,
|
|
|
+ /* .iConfiguration = DYNAMIC */
|
|
|
+ .bmAttributes = USB_CONFIG_ATT_ONE,
|
|
|
+ .MaxPower = 500,
|
|
|
+};
|
|
|
+
|
|
|
+static struct usb_configuration nokia_config_100ma_driver = {
|
|
|
+ .label = "Self Powered",
|
|
|
+ .bConfigurationValue = 2,
|
|
|
+ /* .iConfiguration = DYNAMIC */
|
|
|
+ .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
|
|
|
+ .MaxPower = 100,
|
|
|
+};
|
|
|
+
|
|
|
+static struct usb_function_instance *fi_acm;
|
|
|
+
|
|
|
static int __init nokia_bind_config(struct usb_configuration *c)
|
|
|
{
|
|
|
+ struct usb_function *f_acm;
|
|
|
int status = 0;
|
|
|
|
|
|
status = phonet_bind_config(c);
|
|
@@ -126,36 +144,36 @@ static int __init nokia_bind_config(struct usb_configuration *c)
|
|
|
if (status)
|
|
|
printk(KERN_DEBUG "could not bind obex config %d\n", 0);
|
|
|
|
|
|
- status = acm_bind_config(c, tty_lines[TTY_PORT_ACM]);
|
|
|
+ f_acm = usb_get_function(fi_acm);
|
|
|
+ if (IS_ERR(f_acm))
|
|
|
+ return PTR_ERR(f_acm);
|
|
|
+
|
|
|
+ status = usb_add_function(c, f_acm);
|
|
|
if (status)
|
|
|
- printk(KERN_DEBUG "could not bind acm config\n");
|
|
|
+ goto err_conf;
|
|
|
|
|
|
status = ecm_bind_config(c, hostaddr);
|
|
|
- if (status)
|
|
|
- printk(KERN_DEBUG "could not bind ecm config\n");
|
|
|
+ if (status) {
|
|
|
+ pr_debug("could not bind ecm config %d\n", status);
|
|
|
+ goto err_ecm;
|
|
|
+ }
|
|
|
+ if (c == &nokia_config_500ma_driver)
|
|
|
+ f_acm_cfg1 = f_acm;
|
|
|
+ else
|
|
|
+ f_acm_cfg2 = f_acm;
|
|
|
|
|
|
return status;
|
|
|
+err_ecm:
|
|
|
+ usb_remove_function(c, f_acm);
|
|
|
+err_conf:
|
|
|
+ usb_put_function(f_acm);
|
|
|
+ return status;
|
|
|
}
|
|
|
|
|
|
-static struct usb_configuration nokia_config_500ma_driver = {
|
|
|
- .label = "Bus Powered",
|
|
|
- .bConfigurationValue = 1,
|
|
|
- /* .iConfiguration = DYNAMIC */
|
|
|
- .bmAttributes = USB_CONFIG_ATT_ONE,
|
|
|
- .MaxPower = 500,
|
|
|
-};
|
|
|
-
|
|
|
-static struct usb_configuration nokia_config_100ma_driver = {
|
|
|
- .label = "Self Powered",
|
|
|
- .bConfigurationValue = 2,
|
|
|
- /* .iConfiguration = DYNAMIC */
|
|
|
- .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
|
|
|
- .MaxPower = 100,
|
|
|
-};
|
|
|
-
|
|
|
static int __init nokia_bind(struct usb_composite_dev *cdev)
|
|
|
{
|
|
|
struct usb_gadget *gadget = cdev->gadget;
|
|
|
+ struct f_serial_opts *opts;
|
|
|
int status;
|
|
|
int cur_line;
|
|
|
|
|
@@ -185,22 +203,32 @@ static int __init nokia_bind(struct usb_composite_dev *cdev)
|
|
|
if (!gadget_supports_altsettings(gadget))
|
|
|
goto err_usb;
|
|
|
|
|
|
+ fi_acm = usb_get_function_instance("acm");
|
|
|
+ if (IS_ERR(fi_acm))
|
|
|
+ goto err_usb;
|
|
|
+ opts = container_of(fi_acm, struct f_serial_opts, func_inst);
|
|
|
+ opts->port_num = tty_lines[TTY_PORT_ACM];
|
|
|
+
|
|
|
/* finally register the configuration */
|
|
|
status = usb_add_config(cdev, &nokia_config_500ma_driver,
|
|
|
nokia_bind_config);
|
|
|
if (status < 0)
|
|
|
- goto err_usb;
|
|
|
+ goto err_acm_inst;
|
|
|
|
|
|
status = usb_add_config(cdev, &nokia_config_100ma_driver,
|
|
|
nokia_bind_config);
|
|
|
if (status < 0)
|
|
|
- goto err_usb;
|
|
|
+ goto err_put_cfg1;
|
|
|
|
|
|
usb_composite_overwrite_options(cdev, &coverwrite);
|
|
|
dev_info(&gadget->dev, "%s\n", NOKIA_LONG_NAME);
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
+err_put_cfg1:
|
|
|
+ usb_put_function(f_acm_cfg1);
|
|
|
+err_acm_inst:
|
|
|
+ usb_put_function_instance(fi_acm);
|
|
|
err_usb:
|
|
|
gether_cleanup();
|
|
|
err_ether:
|
|
@@ -217,6 +245,9 @@ static int __exit nokia_unbind(struct usb_composite_dev *cdev)
|
|
|
{
|
|
|
int i;
|
|
|
|
|
|
+ usb_put_function(f_acm_cfg1);
|
|
|
+ usb_put_function(f_acm_cfg2);
|
|
|
+ usb_put_function_instance(fi_acm);
|
|
|
gphonet_cleanup();
|
|
|
|
|
|
for (i = 0; i < TTY_PORTS_MAX; i++)
|
|
@@ -247,4 +278,3 @@ static void __exit nokia_cleanup(void)
|
|
|
usb_composite_unregister(&nokia_driver);
|
|
|
}
|
|
|
module_exit(nokia_cleanup);
|
|
|
-
|