orangepi zero usb otg 多个设备

由于工作需要:

orangepi zero 需要otg device支持两个hid设备与一个tty串口设备,使用官网代码发现usb otg device 不满足需要

经过一番探索,做了以下修改

在此聊聊记下

首先修改了gadget的设备驱动serial代码,在serial中增加两个hid设备,关键代码如下

static bool use_acm = false;//禁用acm使用gs代码

#include "f_hid.c"//包含hidgadget的相关代码

serial_config_driver.bConfigurationValue = 3;//修改配置个数为3
device_desc.bDeviceClass = 0;//修改设备类为0(为什么设置为0,在usb设备描述符中去找原因)

//增加一个键盘的数据描述,用于注册hid设备
static struct hidg_func_descriptor my_hid_data = {
    .subclass        = 0, /* No subclass */
    .protocol        = 1, /* Keyboard */
    .report_length        = 8,
    .report_desc_length    = 63,
    .report_desc        = {
        0x05, 0x01,    /* USAGE_PAGE (Generic Desktop)              */
        0x09, 0x06,    /* USAGE (Keyboard)                       */
        0xa1, 0x01,    /* COLLECTION (Application)               */
        0x05, 0x07,    /*   USAGE_PAGE (Keyboard)                */
        0x19, 0xe0,    /*   USAGE_MINIMUM (Keyboard LeftControl) */
        0x29, 0xe7,    /*   USAGE_MAXIMUM (Keyboard Right GUI)   */
        0x15, 0x00,    /*   LOGICAL_MINIMUM (0)                  */
        0x25, 0x01,    /*   LOGICAL_MAXIMUM (1)                  */
        0x75, 0x01,    /*   REPORT_SIZE (1)                      */
        0x95, 0x08,    /*   REPORT_COUNT (8)                     */
        0x81, 0x02,    /*   INPUT (Data,Var,Abs)                 */
        0x95, 0x01,    /*   REPORT_COUNT (1)                     */
        0x75, 0x08,    /*   REPORT_SIZE (8)                      */
        0x81, 0x03,    /*   INPUT (Cnst,Var,Abs)                 */
        0x95, 0x05,    /*   REPORT_COUNT (5)                     */
        0x75, 0x01,    /*   REPORT_SIZE (1)                      */
        0x05, 0x08,    /*   USAGE_PAGE (LEDs)                    */
        0x19, 0x01,    /*   USAGE_MINIMUM (Num Lock)             */
        0x29, 0x05,    /*   USAGE_MAXIMUM (Kana)                 */
        0x91, 0x02,    /*   OUTPUT (Data,Var,Abs)                */
        0x95, 0x01,    /*   REPORT_COUNT (1)                     */
        0x75, 0x03,    /*   REPORT_SIZE (3)                      */
        0x91, 0x03,    /*   OUTPUT (Cnst,Var,Abs)                */
        0x95, 0x06,    /*   REPORT_COUNT (6)                     */
        0x75, 0x08,    /*   REPORT_SIZE (8)                      */
        0x15, 0x00,    /*   LOGICAL_MINIMUM (0)                  */
        0x25, 0x65,    /*   LOGICAL_MAXIMUM (101)                */
        0x05, 0x07,    /*   USAGE_PAGE (Keyboard)                */
        0x19, 0x00,    /*   USAGE_MINIMUM (Reserved)             */
        0x29, 0x65,    /*   USAGE_MAXIMUM (Keyboard Application) */
        0x81, 0x00,    /*   INPUT (Data,Ary,Abs)                 */
        0xc0        /* END_COLLECTION                         */
    }
};

//在gs_bind中增加下面先关代码,为了标明增加位置 特多复制了几行代码
/* register our configuration */
status = usb_add_config(cdev, &serial_config_driver,
        serial_bind_config);
if (status < 0)
    goto fail;

status = ghid_setup(cdev->gadget, 2);
if (status < 0)
    return status;
status = hidg_bind_config(&serial_config_driver, &my_hid_data,0);
if (status < 0)
    return status;
status = hidg_bind_config(&serial_config_driver, &my_hid_data,1);
if (status < 0)
    return status;
usb_gadget_connect(cdev->gadget);

按照正常逻辑在增加以上代码后设备应该能够正常枚举,枚举出两个hid键盘与一个串口设备,但是经过多次测试发现还是有问题,设备枚举失败,一个设备都没有正常枚举,经过一番苦查,发现问题出现在hidg_bind_config,在bind hid设备的时候出现的问题,在bind的时候发现有debug信息显示 hid的endpoint 申请失败,于是开始怀疑是cpu本身提供的endpoint不够,又去查cpu手册,发现手册上显示的allwinner H2的作为device时有8个endpoint,所以这个疑点又排除了

又经过一番苦查发现H2的usb otg的endpoint 类型在代码中直接定义死了,不能在代码运行时进行修改,修改了相关代码后出现了我想要的结果修改了以下代码,虽然有些瑕疵,但是已经满足了现在的需要

--- a/OrangePi-Kernel/linux-3.4/drivers/usb/sunxi_usb/include/sunxi_udc.h
+++ b/OrangePi-Kernel/linux-3.4/drivers/usb/sunxi_usb/include/sunxi_udc.h
@@ -71,7 +71,8 @@ static const char ep1in_bulk_name []  = "ep1in-bulk";
 static const char ep1out_bulk_name [] = "ep1out-bulk";
 static const char ep2in_bulk_name []  = "ep2in-bulk";
 static const char ep2out_bulk_name [] = "ep2out-bulk";
-static const char ep3_iso_name []     = "ep3-iso";
+//static const char ep3_iso_name []     = "ep3-iso";
+static const char ep3_iso_name []     = "ep3-int";//不要被变量名迷惑,这里根据字符串进行查找的
 static const char ep4_int_name []     = "ep4-int";
 static const char ep5in_bulk_name []  = "ep5in-bulk";
 static const char ep5out_bulk_name [] = "ep5out-bulk";

 --- a/OrangePi-Kernel/linux-3.4/drivers/usb/sunxi_usb/udc/sunxi_udc.c
+++ b/OrangePi-Kernel/linux-3.4/drivers/usb/sunxi_usb/udc/sunxi_udc.c
@@ -2777,12 +2777,12 @@ static struct sunxi_udc sunxi_udc = {
                .ep = {
                        .name           = ep3_iso_name,
                        .ops            = &sunxi_udc_ep_ops,
-                       .maxpacket      = SW_UDC_EP_ISO_FIFO_SIZE,
+                       .maxpacket      = SW_UDC_EP_FIFO_SIZE,//修改最大值(这个修改在sunxi_udc.h中有个size的定义,不知道会不会有潜在的问题,暂时可以满足我的需求)
                },
                .dev                    = &sunxi_udc,
                //.fifo_size            = SW_UDC_EP_FIFO_SIZE,
                .bEndpointAddress   = 3,
-               .bmAttributes       = USB_ENDPOINT_XFER_ISOC,
+               .bmAttributes       = USB_ENDPOINT_XFER_INT,//修改相关的类型
        },

代码没有整理,应该可以修改相关的变量名,已经最大值的适配,该工作暂时告一段落,日后有问题的话再去查找
全部的diff 如下

diff --git a/OrangePi-Kernel/linux-3.4/drivers/usb/gadget/f_serial.c b/OrangePi-Kernel/linux-3.4/drivers/usb/gadget/f_serial.c
index 07197d63..3ef2589a 100644
--- a/OrangePi-Kernel/linux-3.4/drivers/usb/gadget/f_serial.c
+++ b/OrangePi-Kernel/linux-3.4/drivers/usb/gadget/f_serial.c
@@ -47,8 +47,8 @@ static struct usb_interface_descriptor gser_interface_desc __initdata = {
     .bDescriptorType =    USB_DT_INTERFACE,
     /* .bInterfaceNumber = DYNAMIC */
     .bNumEndpoints =    2,
-    .bInterfaceClass =    USB_CLASS_VENDOR_SPEC,
-    .bInterfaceSubClass =    0,
+    .bInterfaceClass =    2,
+    .bInterfaceSubClass =    2,
     .bInterfaceProtocol =    0,
     /* .iInterface = DYNAMIC */
 };
diff --git a/OrangePi-Kernel/linux-3.4/drivers/usb/gadget/serial.c b/OrangePi-Kernel/linux-3.4/drivers/usb/gadget/serial.c
index 665c0742..bc00d988 100644
--- a/OrangePi-Kernel/linux-3.4/drivers/usb/gadget/serial.c
+++ b/OrangePi-Kernel/linux-3.4/drivers/usb/gadget/serial.c
@@ -18,6 +18,7 @@

 #include "u_serial.h"
 #include "gadget_chips.h"
+#include "f_hid.c"


 /* Defines */
@@ -97,7 +98,7 @@ static struct usb_device_descriptor device_desc = {
     /* .bcdDevice = f(hardware) */
     /* .iManufacturer = DYNAMIC */
     /* .iProduct = DYNAMIC */
-    .bNumConfigurations =    1,
+    .bNumConfigurations =    3,
 };

 static struct usb_otg_descriptor otg_descriptor = {
@@ -123,7 +124,7 @@ MODULE_AUTHOR("Al Borchers");
 MODULE_AUTHOR("David Brownell");
 MODULE_LICENSE("GPL");

-static bool use_acm = true;
+static bool use_acm = false;
 module_param(use_acm, bool, 0);
 MODULE_PARM_DESC(use_acm, "Use CDC ACM, default=yes");

@@ -159,6 +160,49 @@ static struct usb_configuration serial_config_driver = {
     /* .iConfiguration = DYNAMIC */
     .bmAttributes    = USB_CONFIG_ATT_SELFPOWER,
 };
+/* hid descriptor for a keyboard */
+static struct hidg_func_descriptor my_hid_data = {
+    .subclass        = 0, /* No subclass */
+    .protocol        = 1, /* Keyboard */
+    .report_length        = 8,
+    .report_desc_length    = 63,
+    .report_desc        = {
+        0x05, 0x01,    /* USAGE_PAGE (Generic Desktop)              */
+        0x09, 0x06,    /* USAGE (Keyboard)                       */
+        0xa1, 0x01,    /* COLLECTION (Application)               */
+        0x05, 0x07,    /*   USAGE_PAGE (Keyboard)                */
+        0x19, 0xe0,    /*   USAGE_MINIMUM (Keyboard LeftControl) */
+        0x29, 0xe7,    /*   USAGE_MAXIMUM (Keyboard Right GUI)   */
+        0x15, 0x00,    /*   LOGICAL_MINIMUM (0)                  */
+        0x25, 0x01,    /*   LOGICAL_MAXIMUM (1)                  */
+        0x75, 0x01,    /*   REPORT_SIZE (1)                      */
+        0x95, 0x08,    /*   REPORT_COUNT (8)                     */
+        0x81, 0x02,    /*   INPUT (Data,Var,Abs)                 */
+        0x95, 0x01,    /*   REPORT_COUNT (1)                     */
+        0x75, 0x08,    /*   REPORT_SIZE (8)                      */
+        0x81, 0x03,    /*   INPUT (Cnst,Var,Abs)                 */
+        0x95, 0x05,    /*   REPORT_COUNT (5)                     */
+        0x75, 0x01,    /*   REPORT_SIZE (1)                      */
+        0x05, 0x08,    /*   USAGE_PAGE (LEDs)                    */
+        0x19, 0x01,    /*   USAGE_MINIMUM (Num Lock)             */
+        0x29, 0x05,    /*   USAGE_MAXIMUM (Kana)                 */
+        0x91, 0x02,    /*   OUTPUT (Data,Var,Abs)                */
+        0x95, 0x01,    /*   REPORT_COUNT (1)                     */
+        0x75, 0x03,    /*   REPORT_SIZE (3)                      */
+        0x91, 0x03,    /*   OUTPUT (Cnst,Var,Abs)                */
+        0x95, 0x06,    /*   REPORT_COUNT (6)                     */
+        0x75, 0x08,    /*   REPORT_SIZE (8)                      */
+        0x15, 0x00,    /*   LOGICAL_MINIMUM (0)                  */
+        0x25, 0x65,    /*   LOGICAL_MAXIMUM (101)                */
+        0x05, 0x07,    /*   USAGE_PAGE (Keyboard)                */
+        0x19, 0x00,    /*   USAGE_MINIMUM (Reserved)             */
+        0x29, 0x65,    /*   USAGE_MAXIMUM (Keyboard Application) */
+        0x81, 0x00,    /*   INPUT (Data,Ary,Abs)                 */
+        0xc0        /* END_COLLECTION                         */
+    }
+};
+
+

 static int __init gs_bind(struct usb_composite_dev *cdev)
 {
@@ -229,6 +273,14 @@ static int __init gs_bind(struct usb_composite_dev *cdev)
     if (status < 0)
         goto fail;

+    status = ghid_setup(cdev->gadget, 2);
+    if (status < 0)
+        return status;
+    status = hidg_bind_config(&serial_config_driver, &my_hid_data,0);
+    status = hidg_bind_config(&serial_config_driver, &my_hid_data,1);
+    usb_gadget_connect(cdev->gadget);
+
+
     INFO(cdev, "%s\n", GS_VERSION_NAME);

     return 0;
@@ -264,8 +316,9 @@ static int __init init(void)
             cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID);
     } else {
         serial_config_driver.label = "Generic Serial config";
-        serial_config_driver.bConfigurationValue = 1;
-        device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
+        serial_config_driver.bConfigurationValue = 3;
+        //device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
+        device_desc.bDeviceClass = 0;
         device_desc.idProduct =
                 cpu_to_le16(GS_PRODUCT_ID);
     }
diff --git a/OrangePi-Kernel/linux-3.4/drivers/usb/sunxi_usb/include/sunxi_udc.h b/OrangePi-Kernel/linux-3.4/drivers/usb/sunxi_usb/include/sunxi_udc.h
index f9cabe94..974f0ae2 100755
--- a/OrangePi-Kernel/linux-3.4/drivers/usb/sunxi_usb/include/sunxi_udc.h
+++ b/OrangePi-Kernel/linux-3.4/drivers/usb/sunxi_usb/include/sunxi_udc.h
@@ -71,7 +71,8 @@ static const char ep1in_bulk_name []  = "ep1in-bulk";
 static const char ep1out_bulk_name [] = "ep1out-bulk";
 static const char ep2in_bulk_name []  = "ep2in-bulk";
 static const char ep2out_bulk_name [] = "ep2out-bulk";
-static const char ep3_iso_name []     = "ep3-iso";
+//static const char ep3_iso_name []     = "ep3-iso";
+static const char ep3_iso_name []     = "ep3-int";
 static const char ep4_int_name []     = "ep4-int";
 static const char ep5in_bulk_name []  = "ep5in-bulk";
 static const char ep5out_bulk_name [] = "ep5out-bulk";
diff --git a/OrangePi-Kernel/linux-3.4/drivers/usb/sunxi_usb/udc/sunxi_udc.c b/OrangePi-Kernel/linux-3.4/drivers/usb/sunxi_usb/udc/sunxi_udc.c
index f24298c7..3c05f810 100755
--- a/OrangePi-Kernel/linux-3.4/drivers/usb/sunxi_usb/udc/sunxi_udc.c
+++ b/OrangePi-Kernel/linux-3.4/drivers/usb/sunxi_usb/udc/sunxi_udc.c
@@ -2777,12 +2777,12 @@ static struct sunxi_udc sunxi_udc = {
         .ep = {
             .name        = ep3_iso_name,
             .ops        = &sunxi_udc_ep_ops,
-            .maxpacket    = SW_UDC_EP_ISO_FIFO_SIZE,
+            .maxpacket    = SW_UDC_EP_FIFO_SIZE,
         },
         .dev                = &sunxi_udc,
         //.fifo_size            = SW_UDC_EP_FIFO_SIZE,
         .bEndpointAddress   = 3,
-        .bmAttributes        = USB_ENDPOINT_XFER_ISOC,
+        .bmAttributes        = USB_ENDPOINT_XFER_INT,
     },

     .ep[6] = {
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值