13 Replies Latest reply on Jan 13, 2015 3:28 PM by @hippiehacker

    Enabling USB HID Gadget Support


      https://www.kernel.org/doc/Documentation/usb/gadget_hid.txt has some info on enabling g_hid / config fs.

      https://wiki.tizen.org/wiki/USB/Linux_USB_Layers/Configfs_Composite_Gadget/Usage_eq._to_g_hid.ko also has some great stuff


      I rebuilt the kernel with usb gadget+hid support, but there must be more to it.


      root@edison:/# ls /lib/modules/3.10.17-poky-edison\+/kernel/drivers/usb/gadget/

      g_hid.ko         gadgetfs.ko      u_serial.ko

      g_multi.ko       libcomposite.ko  usb_f_acm.ko

      root@edison:/# modprobe g_hid

      modprobe: ERROR: could not insert 'g_hid': No such device


      Here is something similar for the beagleboard, and they talk about adding stuff to hid.c from the gadget_hid.txt above, but I'm not sure which hid.c they are referring too.



      Thanks in advance,


        • 1. Re: Enabling USB HID Gadget Support

          Hi @hippiehacker


          The hid.c that they are talking about is the code that appear in the that link. Let's try with that first. Also, are you connecting the device to the USB port and putting the switch (SW1) closer to that port?




          • 2. Re: Enabling USB HID Gadget Support

            I'm using the edison breakout board and power is supplied over the OTG, (I connect both ports).

            • 3. Re: Enabling USB HID Gadget Support

              I'm still not sure I understand which hid.c file within the edison-src directory it's referring too.









              step1: go to the link below.



              step2: copy the following two structures from the above link and paste into hid.c




              step3: compile the hid module


              step4: load the module



              In your hidg_init function in the module, call the following





              int status; status = platform_device_register(&my_hid); if (status < 0) { platform_driver_unregister(&my_hid); return status; }

              where my_hid is a pointer to platform_device struct.


              Also call the following function in your hidg_cleanup function




              Hope this will help.

              • 4. Re: Enabling USB HID Gadget Support

                I'm thinking it's probably something that needs to be in the upstream_to_edison.patch


                # grep \| edison-src/device-software/meta-edison/recipes-kernel/linux/files/upstream_to_edison.patch  | grep usb/          

                drivers/usb/core/hcd.c                             |   23 +-

                drivers/usb/dwc3/Kconfig                           |   66 +

                drivers/usb/dwc3/Makefile                          |   10 +-

                drivers/usb/dwc3/core.c                            |   21 +-

                drivers/usb/dwc3/core.h                            |   71 +

                drivers/usb/dwc3/debugfs.c                         |   49 +

                drivers/usb/dwc3/dwc3-device-intel.c               |  648 +++

                drivers/usb/dwc3/dwc3-host-intel.c                 |  724 +++

                drivers/usb/dwc3/dwc3-intel-byt.c                  |  970 ++++

                drivers/usb/dwc3/dwc3-intel-mrfl.c                 |  992 ++++

                drivers/usb/dwc3/dwc3-pci.c                        |    4 +

                drivers/usb/dwc3/ep0.c                             |   37 +-

                drivers/usb/dwc3/gadget.c                          | 1085 +++-

                drivers/usb/dwc3/gadget.h                          |    7 +

                drivers/usb/dwc3/otg.c                             | 1509 +++++

                drivers/usb/dwc3/otg.h                             |  432 ++

                drivers/usb/gadget/epautoconf.c                    |   42 +

                drivers/usb/gadget/f_dvc_dfx.c                     |  922 ++++

                drivers/usb/gadget/f_dvc_trace.c                   |  887 +++

                drivers/usb/gadget/f_mass_storage.c                |    2 +-

                drivers/usb/gadget/gadget_chips.h                  |    5 +-

                drivers/usb/gadget/multi.c                         |   37 +-

                drivers/usb/gadget/u_ether.c                       |    2 -

                drivers/usb/gadget/u_serial.c                      |    2 +-

                drivers/usb/gadget/udc-core.c                      |   12 +-

                drivers/usb/host/ehci-pci.c                        |    2 +-

                drivers/usb/host/xhci-plat.c                       |   11 +

                drivers/usb/phy/penwell_otg.c                      | 5780 ++++++++++++++++++++

                include/linux/usb/debug.h                          |  253 +

                include/linux/usb/dwc3-intel-mid.h                 |  190 +

                include/linux/usb/dwc3-intel-mrfl.h                |  168 +

                include/linux/usb/gadget.h                         |    4 +

                include/linux/usb/hcd.h                            |    3 +

                include/linux/usb/penwell_otg.h                    |  515 ++

                include/linux/usb/phy.h                            |   14 +

                include/uapi/linux/usb/ch9.h                       |    1 +

                • 5. Re: Enabling USB HID Gadget Support

                  Another approach that adds platform_device_register(&my_hid) to KERNEL/arch/arm/mach-omap2/board-am335xevm.c.

                  Looks like we need to find the right c files for the edison.


                  embedded - omap_udc.c g_hid.c hid gadget on beagleboard with angstrom linux - Stack Overflow/

                  • 6. Re: Enabling USB HID Gadget Support

                    I tried just compiling intel's patch(1) to 3.10.17 with CONFIG_USB_GADGETFS=m CONFIG_USB_G_HID=m but I get an error trying to load the module:

                    modprobe: ERROR: could not insert 'g_hid': No such device


                    According to https://www.kernel.org/doc/Documentation/usb/gadget_hid.txt:

                            g_hid is a platform driver, so to use it you need to add
                    struct platform_device(s) to your platform code defining the HID function descriptors you want to use

                    It's not clear to me what part of the platform code I should be adding, but I assume it's something under:


                    • 7. Re: Enabling USB HID Gadget Support

                      I did find a demo for the beagleboard black:


                      csimmonds/g_hid-demo · GitHub

                      This is a quick and dirty hack to demonstrate the gadget hid driver. Normally the platform_device descriptor would be part of the board support for the device, e.g. in arch/arm/mach-omap2/devices.c, but for convenience I am putting it in to the g_hid module to make easier for testing.

                      Copy this file over the one in drivers/usb/gadget, build the g_hid module and copy to the device.

                      • 8. Re: Enabling USB HID Gadget Support

                        Hi @hippiehacker


                        Let me know about your last test, also, have you tried with another method I think that usbutils could work and what kind of device do you want to connect? A mouse, keyboard, joystick?




                        • 9. Re: Enabling USB HID Gadget Support

                          I've reached out to the linux-usb mailing list and got a response: http://article.gmane.org/gmane.linux.usb.general/120297

                          I'm not sure where to add this stuff to the platform. It was suggested ask on an intel-mid platform specific mailing list.


                          We have the patches supplied by intel


                          Which completely provides the platform/intel-mid:



                          I reached out to a few folks directly who's names appeared in those files but haven't heard anything.


                          I was informed (not by intel, but by some of the nice folks at the linux-usb list) that emailing folks in source files is a netiquette faux pas, and it was suggested I find the intel-mid platform specific mailing list.


                          Any clues on locating this platform/intel-mid mailing list?

                          Does it exist?

                          If not, is this forum browsed by folks that could speak to attempts to update / modify the intel-mid platform?

                          • 10. Re: Enabling USB HID Gadget Support

                            Looking at all the heavy hitters on the lkml, it may be that I need to ask there directly... a bit intimidating.

                            But that may be the right place.

                            • 11. Re: Enabling USB HID Gadget Support

                              Looks like we have two options, and I created two new threads to follow them through:


                              1) Using configfs with the kernel 3.19.X Equivalent of g_hid with configfs

                              Building edison-image BSP with Linux 3.19.x?


                              2) Adding g_hid boilerplate code (from Documentation/usb/gadget_hid.txt) to the right module within the intel-mid platform by adding support for usb hid gadget via a patch

                              Integrating linux-yocto-3.10 usb/gadget_hid.txt into platform/intel-mid?

                              • 12. Re: Enabling USB HID Gadget Support

                                Hi @hippiehacker


                                Could you tell me what kind of device you do you want to use? Have you tried to configure the device with udev, or maybe just using the kernel-module-g-multi_3.10.17+git0+6ad20f049a_c03195ed6e-r0_edison.ipk package from AlexT's repo

                                • 13. Re: Enabling USB HID Gadget Support

                                  As shipped with the Intel-Edison BSP kernel https://www.kernel.org/doc/Documentation/usb/gadget_multi.txt
                                  only supports and exports rndis,cdc, and usb-storage to the host it is connected to on boot:


                                  On the usb that provides power and is exported from the Intel Edison using the g_multi:

                                  linuxdesktop-with-edison-attached# lsusb -t

                                                  |__ Port 1: Dev 87, If 0, class="Communications", Driver=rndis_host, 480M

                                                  |__ Port 1: Dev 87, If 1, class="CDC" Data, Driver=rndis_host, 480M

                                                  |__ Port 1: Dev 87, If 2, class="Communications", Driver=cdc_acm, 480M

                                                  |__ Port 1: Dev 87, If 3, class="CDC" Data, Driver=cdc_acm, 480M

                                                  |__ Port 1: Dev 87, If 4, class="Mass" Storage, Driver=usb-storage, 480M


                                  I would like to add usbhid support to g_multi and be able to simultaneously export the above at the same time as we export a keyboard / mouse HID

                                  linuxdesktop-with-hidpatched+edison-attached# lsusb -t

                                                  .... above plus a keyboard / mouse ...

                                                  |__ Port 1: Dev 87, If 5, class="Human" Interface Device, Driver=usbhid, 12M

                                                  |__ Port 1: Dev 87, If 6, class="Human" Interface Device, Driver=usbhid, 12M


                                  It might be possible to hack/rebuild g_multi to support this, but it would definitely require changes to the ./drivers/usb/gadget/multi.c


                                  Intel did that to incorporate the ethernet, maybe we just need to add the hid?:


                                  +++ b/drivers/usb/gadget/multi.c

                                  @@ -15,7 +15,6 @@


                                  #include <linux/kernel.h>

                                  #include <linux/module.h>

                                  -#include <linux/moduleparam.h>


                                  #include "u_serial.h"

                                  #if defined USB_ETH_RNDIS

                                  @@ -54,12 +53,6 @@ MODULE_LICENSE("GPL");




                                  -static char ethernet_config[6];

                                  -module_param_string(ethernet_config, ethernet_config, sizeof(ethernet_config),

                                  -       0444);


                                  -       "ethernet configuration : should be cdc or rndis");


                                  /***************************** Device Descriptor ****************************/


                                  #define MULTI_VENDOR_NUM       0x1d6b  /* Linux Foundation */

                                  @@ -315,31 +308,13 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)

                                          device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;


                                          /* register configurations */

                                  -       /* RNDIS configuration */

                                  -       if (strncmp(ethernet_config, "rndis", 5) == 0) {

                                  -               status = rndis_config_register(cdev);


                                  -               if (unlikely(status < 0))

                                  -                       goto fail2;

                                  -       } else if (strncmp(ethernet_config, "cdc", 3) == 0) {

                                  -               /* CDC ECM configuration  */

                                  -               status = cdc_config_register(cdev);


                                  -               if (unlikely(status < 0))

                                  -                       goto fail2;

                                  -       } else {

                                  -               status = rndis_config_register(cdev);


                                  -               if (unlikely(status < 0))

                                  -                       goto fail2;


                                  -               status = cdc_config_register(cdev);


                                  -               if (unlikely(status < 0))

                                  -                       goto fail2;

                                  -       }


                                  +       status = rndis_config_register(cdev);

                                  +       if (unlikely(status < 0))

                                  +               goto fail2;


                                  +       status = cdc_config_register(cdev);

                                  +       if (unlikely(status < 0))

                                  +               goto fail2;

                                          usb_composite_overwrite_options(cdev, &coverwrite);


                                          /* we're done */