linux usb做复合设备,usb从设备驱动usb_composite_driver复合设备

这篇博客详细介绍了如何在Linux ARM 3.10.104内核中实现USB复合设备驱动,特别是`composite.c`文件中的关键函数,如`composite_bind`, `composite_setup`等。内容涉及USB gadget driver的初始化、配置、接口设置以及如何处理USB标准和特定功能的控制请求。此外,还提到了音频功能驱动`f_uac1.c`中的`f_audio_setup`和`f_audio_set_alt`函数,说明了如何处理音频接口和端点的请求以及如何设置音频功能的替代设置。" 122006079,315221,Arduino SPI驱动 ili9341 TFT显示屏仿真实例,"['Arduino', '嵌入式', '仿真', 'TFT显示屏', 'SPI驱动']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Linux/arm 3.10.104

drivers/usb/gadget/composite.c

static const struct usb_gadget_driver composite_driver_template = {

.bind        = composite_bind,

.unbind        = composite_unbind,

.setup        = composite_setup,

.disconnect    = composite_disconnect,

.suspend    = composite_suspend,

.resume        = composite_resume,

.driver    = {

.owner        = THIS_MODULE,

},

};

drivers/usb/gadget/composite.c

/*

* The setup() callback implements all the ep0 functionality that's

* not handled lower down, in hardware or the hardware driver(like

* device and endpoint feature flags, and their status).  It's all

* housekeeping for the gadget function we're implementing.  Most of

* the work is in config and function specific setup.

*/

int

composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)

{

struct usb_composite_dev    *cdev = get_gadget_data(gadget);

struct usb_request        *req = cdev->req;

int                value = -EOPNOTSUPP;

int                status = 0;

u16                w_index = le16_to_cpu(ctrl->wIndex);

u8                intf = w_index & 0xFF;

u16                w_value = le16_to_cpu(ctrl->wValue);

u16                w_length = le16_to_cpu(ctrl->wLength);

struct usb_function        *f = NULL;

u8                endp;

/* partial re-init of the response message; the function or the

* gadget might need to intercept e.g. a control-OUT completion

* when we delegate to it.

*/

req->zero = 0;

req->complete = composite_setup_complete;

req->length = 0;

gadget->ep0->driver_data = cdev;

switch (ctrl->bRequest) {

/* we handle all standard USB descriptors */

case USB_REQ_GET_DESCRIPTOR:

if (ctrl->bRequestType != USB_DIR_IN)

goto unknown;

switch (w_value >> 8) {

case USB_DT_DEVICE:

cdev->desc.bNumConfigurations =

count_configs(cdev, USB_DT_DEVICE);

cdev->desc.bMaxPacketSize0 =

cdev->gadget->ep0->maxpacket;

if (gadget_is_superspeed(gadget)) {

if (gadget->speed >= USB_SPEED_SUPER) {

cdev->desc.bcdUSB = cpu_to_le16(0x0300);

cdev->desc.bMaxPacketSize0 = 9;

} else {

cdev->desc.bcdUSB = cpu_to_le16(0x0210);

}

}

value = min(w_length, (u16) sizeof cdev->desc);

memcpy(req->buf, &cdev->desc, value);

break;

case USB_DT_DEVICE_QUALIFIER:

if (!gadget_is_dualspeed(gadget) ||

gadget->speed >= USB_SPEED_SUPER)

break;

device_qual(cdev);

value = min_t(int, w_length,

sizeof(struct usb_qualifier_descriptor));

break;

case USB_DT_OTHER_SPEED_CONFIG:

if (!gadget_is_dualspeed(gadget) ||

gadget->speed >= USB_SPEED_SUPER)

break;

/* FALLTHROUGH */

case USB_DT_CONFIG:

value = config_desc(cdev, w_value);

if (value >= 0)

value = min(w_length, (u16) value);

break;

case USB_DT_STRING:

value = get_string(cdev, req->buf,

w_index, w_value & 0xff);

if (value >= 0)

value = min(w_length, (u16) value);

break;

case USB_DT_BOS:

if (

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值