mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
usb: gadget: Multiple ACM gadget instances
- Added multiple ACM instance support in Android gadget - Fixed multiple instance naming issue in ACM function - Increased max instances from 4 to 8 Change-Id: I65f1b0be94da859bab7ec0ad7cd804b896c7c4c5 Signed-off-by: John Michelau <john.michelau@motorola.com>
This commit is contained in:
committed by
Colin Cross
parent
51d5755259
commit
677ba87bdf
@@ -698,6 +698,7 @@ acm_unbind(struct usb_configuration *c, struct usb_function *f)
|
||||
usb_free_descriptors(f->hs_descriptors);
|
||||
usb_free_descriptors(f->descriptors);
|
||||
gs_free_req(acm->notify, acm->notify_req);
|
||||
kfree(acm->port.func.name);
|
||||
kfree(acm);
|
||||
}
|
||||
|
||||
@@ -769,7 +770,11 @@ int acm_bind_config(struct usb_configuration *c, u8 port_num)
|
||||
acm->port.disconnect = acm_disconnect;
|
||||
acm->port.send_break = acm_send_break;
|
||||
|
||||
acm->port.func.name = "acm";
|
||||
acm->port.func.name = kasprintf(GFP_KERNEL, "acm%u", port_num);
|
||||
if (!acm->port.func.name) {
|
||||
kfree(acm);
|
||||
return -ENOMEM;
|
||||
}
|
||||
acm->port.func.strings = acm_strings;
|
||||
/* descriptors are per-instance copies */
|
||||
acm->port.func.bind = acm_bind;
|
||||
@@ -785,12 +790,38 @@ int acm_bind_config(struct usb_configuration *c, u8 port_num)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_ANDROID_ACM
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
static struct acm_platform_data *acm_pdata;
|
||||
|
||||
static int acm_probe(struct platform_device *pdev)
|
||||
{
|
||||
acm_pdata = pdev->dev.platform_data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver acm_platform_driver = {
|
||||
.driver = { .name = "acm", },
|
||||
.probe = acm_probe,
|
||||
};
|
||||
|
||||
int acm_function_bind_config(struct usb_configuration *c)
|
||||
{
|
||||
int ret = acm_bind_config(c, 0);
|
||||
if (ret == 0)
|
||||
gserial_setup(c->cdev->gadget, 1);
|
||||
int i;
|
||||
u8 num_inst = acm_pdata ? acm_pdata->num_inst : 1;
|
||||
int ret = gserial_setup(c->cdev->gadget, num_inst);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < num_inst; i++) {
|
||||
ret = acm_bind_config(c, i);
|
||||
if (ret) {
|
||||
pr_err("Could not bind acm%u config\n", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -802,6 +833,7 @@ static struct android_usb_function acm_function = {
|
||||
static int __init init(void)
|
||||
{
|
||||
printk(KERN_INFO "f_acm init\n");
|
||||
platform_driver_register(&acm_platform_driver);
|
||||
android_register_function(&acm_function);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ struct gs_port {
|
||||
};
|
||||
|
||||
/* increase N_PORTS if you need more */
|
||||
#define N_PORTS 4
|
||||
#define N_PORTS 8
|
||||
static struct portmaster {
|
||||
struct mutex lock; /* protect open/close */
|
||||
struct gs_port *port;
|
||||
|
||||
@@ -88,6 +88,11 @@ struct usb_ether_platform_data {
|
||||
const char *vendorDescr;
|
||||
};
|
||||
|
||||
/* Platform data for ACM driver. */
|
||||
struct acm_platform_data {
|
||||
u8 num_inst;
|
||||
};
|
||||
|
||||
extern void android_register_function(struct android_usb_function *f);
|
||||
|
||||
extern void android_enable_function(struct usb_function *f, int enable);
|
||||
|
||||
Reference in New Issue
Block a user