标题:
ARM做为USB从设备的实现(3)
[打印本页]
作者:
yuyang911220
时间:
2015-5-30 09:21
标题:
ARM做为USB从设备的实现(3)
/****************************** Gadget Bind ******************************/
static
int __init hid_bind(struct usb_composite_dev *cdev)
{
struct usb_gadget *gadget = cdev->gadget;
struct list_head *tmp;
int status, gcnum, funcs = 0;
list_for_each(tmp, &hidg_func_list)
funcs++;
if (!funcs)
return -ENODEV;
/* set up HID */
printk("=============bind\n");
status = ghid_setup(cdev->gadget, funcs);
if (status < 0)
return status;
gcnum = usb_gadget_controller_number(gadget);
if (gcnum >= 0)
device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
else
device_desc.bcdDevice = cpu_to_le16(0x0300 | 0x0099);
/* Allocate string descriptor numbers ... note that string
* contents can be overridden by the composite_dev glue.
*/
/* device descriptor strings: manufacturer, product */
snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
init_utsname()->sysname, init_utsname()->release,
gadget->name);
status = usb_string_id(cdev);
if (status < 0)
return status;
strings_dev[STRING_MANUFACTURER_IDX].id = status;
device_desc.iManufacturer = status;
status = usb_string_id(cdev);
if (status < 0)
return status;
strings_dev[STRING_PRODUCT_IDX].id = status;
device_desc.iProduct = status;
/* register our configuration */
status = usb_add_config(cdev, &config_driver);
if (status < 0)
return status;
dev_info(&gadget->dev, DRIVER_DESC ", version: " DRIVER_VERSION "\n");
return 0;
}
static
int __exit hid_unbind(struct usb_composite_dev *cdev)
{
ghid_cleanup();
return 0;
}
static
int __init hidg_plat_driver_probe(struct platform_device *pdev)
{
struct hidg_func_descriptor *func = pdev->dev.platform_data;
struct hidg_func_node *entry;
if (!func) {
dev_err(&pdev->dev, "Platform data missing\n");
return -ENODEV;
}
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (!entry)
return -ENOMEM;
entry->func = func;
list_add_tail(&entry->node, &hidg_func_list);
return 0;
}
static
int __devexit hidg_plat_driver_remove(struct platform_device *pdev)
{
struct hidg_func_node *e, *n;
list_for_each_entry_safe(e, n, &hidg_func_list, node) {
list_del(&e->node);
kfree(e);
}
return 0;
}
/****************************** Some noise ******************************/
static
struct usb_composite_driver hidg_driver = {
.name = "g_hid",
.dev = &device_desc,
.strings = dev_strings,
.bind = hid_bind,
.unbind = __exit_p(hid_unbind),
};
static
struct platform_driver hidg_plat_driver = {
.remove = __devexit_p(hidg_plat_driver_remove),
.driver = {
.name = "hidg",
.owner = THIS_MODULE,
},
};
static
struct musb_hdrc_platform_data hidg_plat_data = {
.mode = MUSB_PERIPHERAL,//MUSB_OTG,
};
static
struct platform_device hidg_plat_device = {
.name = "hidg",
.id = -1,
.dev = {
//.init_name = "hidg_init"
.platform_data = &hidg_plat_data,
},
};
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_AUTHOR("Fabien Chouteau, Peter Korsgaard");
MODULE_LICENSE("GPL");
static
int __init hidg_init(void)
{
int status;
status = platform_device_register(&hidg_plat_device);
if(status < 0)
return status;
status = platform_driver_probe(&hidg_plat_driver, hidg_plat_driver_probe);
if (status < 0)
return status;
status = usb_composite_register(&hidg_driver);
if (status < 0)
platform_driver_unregister(&hidg_plat_driver);
return status;
}
module_init(hidg_init);
static
void __exit hidg_cleanup(void)
{
platform_driver_unregister(&hidg_plat_driver);
usb_composite_unregister(&hidg_driver);
}
module_exit(hidg_cleanup);
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0