All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lucas Tanure <tanure@linux.com>
To: Greg KH <greg@kroah.com>
Cc: kernelnewbies <Kernelnewbies@kernelnewbies.org>
Subject: Re: USB Hid driver Help
Date: Tue, 4 Feb 2020 18:15:10 +0000	[thread overview]
Message-ID: <CAJX_Q+2uK_8dEXcHvQLz9Usa8ixhyvTB6o4H3hVwD6MOqpLTuQ@mail.gmail.com> (raw)
In-Reply-To: <CAJX_Q+1_oPzc+nmw5ZoJb0rG3Ztuei64su=UFxmjk6y2+k5oqQ@mail.gmail.com>

On Tue, Feb 4, 2020 at 1:27 PM Lucas Tanure <tanure@linux.com> wrote:
>
> On Mon, Feb 3, 2020 at 10:00 PM Lucas Tanure <tanure@linux.com> wrote:
> >
> > On Mon, Feb 3, 2020 at 8:11 PM Greg KH <greg@kroah.com> wrote:
> > >
> > > On Mon, Feb 03, 2020 at 04:32:46PM +0000, Lucas Tanure wrote:
> > > > Hi,
> > > >
> > > > I'm trying to write a Hid driver for MCP2210.
> > >
> > > What type of device is this?
> > It is a USB <-> SPI converter.
> >
> > >
> > > > But the USB Hid specification is quite complicated.
> > >
> > > The kernel should do it "all for you" already, why do you need to create
> > > a custom HID driver for this device?
> > I need a driver that register an SPI controller with in the kernel.
> > So this SPI controller would receive regmap reads/writes and translate
> > to USB HID packages and send to the SPI device attached in the other
> > side of the cable.
> >
> > >
> > > What type of HID reports does the device export and why doesn't the
> > > existing kernel drivers work for you?
> > I don't know enough yet to answer about HID Reports, but at end of
> > this e-mail I attached the lsub -v of the device.
> > I want to use this device in kernel space, registering a SPI
> > controller. And with this SPI controller another SPI slave device will
> > be registered.
> > So, for the SPI slave device it will be like there is no USB in
> > between itself and the kernel.
> >
> > >
> > > > I would like to know how to send and receive data to the device. Any
> > > > links to a good tutorial ?
> > >
> > > HID has the idea of "reports" and data comes in and out in that specific
> > > format, all depending on how the device describes itself.  There's isn't
> > > usually a normal "send/receive" type of thing, but it all depends on the
> > > type of device.
> > Ok. Reading the datasheet of this device I need to send some 64 byte
> > arrays to configure the SPI bus.
> > And after that I start to send reports to communicate with the SPI slave device.
> >
> > >
> > > > This is my current driver is attached.
> > > >
> > > > Thanks
> > > > Lucas
> > >
> > > > #define DEBUG
> > > > #include <linux/module.h>
> > > > #include <linux/hid.h>
> > > > #include <linux/usb.h>
> > > >
> > > > static int mcp2210_probe(struct hid_device *hdev,
> > > >                        const struct hid_device_id *id)
> > > > {
> > > >       struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
> > > >       int ret = 0;
> > > >
> > > >       hid_dbg(hdev, "%s\n", __FUNCTION__);
> > > >
> > > >       ret = hid_parse(hdev);
> > > >       if (ret) {
> > > >               hid_err(hdev, "parse failed\n");
> > > >               return ret;
> > > >       } else {
> > > >               hid_dbg(hdev, "parse success\n");
> > > >       }
> > > >
> > > >       ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
> > > >       if (ret) {
> > > >               hid_err(hdev, "hw start failed\n");
> > > >               return ret;
> > > >       } else {
> > > >               hid_dbg(hdev, "start success\n");
> > > >       }
> > >
> > > Does this all work?
> > For this version, it`s takes precedence from HID generic driver, wich is great.
> >
> > >
> > > What fails?
> > If I try to execute small test of data communcation:
> >
> > u8 *buf = kzalloc (64, GFP_KERNEL);
> > buf[0] = 0x50; //read EEPROM command
> > buf[1] = 0x03 ; // Address to read
> >
> > ret = hid_hw_raw_request(hdev, 0, buf, 64, HID_INPUT_REPORT, HID_REQ_GET_REPORT)
> > ret is -EPIPE.
> >
> > >
> > > thanks,
> > >
> > > greg k-h
> >
> > Many Thanks
> > Lucas
> >
> > Bus 001 Device 008: ID 04d8:00de Microchip Technology, Inc. MCP2210
> > USB to SPI Master
> > Couldn't open device, some information will be missing
> > Device Descriptor:
> >  bLength                18
> >  bDescriptorType         1
> >  bcdUSB               2.00
> >  bDeviceClass            0
> >  bDeviceSubClass         0
> >  bDeviceProtocol         0
> >  bMaxPacketSize0         8
> >  idVendor           0x04d8 Microchip Technology, Inc.
> >  idProduct          0x00de
> >  bcdDevice            0.02
> >  iManufacturer           1
> >  iProduct                2
> >  iSerial                 3
> >  bNumConfigurations      1
> >  Configuration Descriptor:
> >    bLength                 9
> >    bDescriptorType         2
> >    wTotalLength       0x0029
> >    bNumInterfaces          1
> >    bConfigurationValue     1
> >    iConfiguration          0
> >    bmAttributes         0x80
> >      (Bus Powered)
> >    MaxPower              100mA
> >    Interface Descriptor:
> >      bLength                 9
> >      bDescriptorType         4
> >      bInterfaceNumber        0
> >      bAlternateSetting       0
> >      bNumEndpoints           2
> >      bInterfaceClass         3 Human Interface Device
> >      bInterfaceSubClass      0
> >      bInterfaceProtocol      0
> >      iInterface              0
> >        HID Device Descriptor:
> >          bLength                 9
> >          bDescriptorType        33
> >          bcdHID               1.11
> >          bCountryCode            0 Not supported
> >          bNumDescriptors         1
> >          bDescriptorType        34 Report
> >          wDescriptorLength      29
> >         Report Descriptors:
> >           ** UNAVAILABLE **
> >      Endpoint Descriptor:
> >        bLength                 7
> >        bDescriptorType         5
> >        bEndpointAddress     0x81  EP 1 IN
> >        bmAttributes            3
> >          Transfer Type            Interrupt
> >          Synch Type               None
> >          Usage Type               Data
> >        wMaxPacketSize     0x0040  1x 64 bytes
> >        bInterval               1
> >      Endpoint Descriptor:
> >        bLength                 7
> >        bDescriptorType         5
> >        bEndpointAddress     0x01  EP 1 OUT
> >        bmAttributes            3
> >          Transfer Type            Interrupt
> >          Synch Type               None
> >          Usage Type               Data
> >        wMaxPacketSize     0x0040  1x 64 bytes
> >        bInterval               1
>
> Hi,
>
> If I use hid_hw_output_report I can write my 64 bytes buffer to the device.
> And I would expect a 64 bytes answer from the device, but I don't know
> how to get it.
>
> How do I know where my output data is going to ? Control Pipe or
> Interrupt Pipe ?
> How to I get the answer data from the device ?
>
> Thanks
> Lucas
>
> static int mcp2210_probe(struct hid_device *hdev,
>                          const struct hid_device_id *id)
> {
>         //struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
>         int ret = 0;
>         //struct hid_report *report = kzalloc(sizeof(struct
> hid_report), GFP_KERNEL);
>         u8 *buf = kzalloc(64, GFP_KERNEL);
>         u8 *buf2 = kzalloc(64, GFP_KERNEL);
>
>         hid_dbg(hdev, "%s\n", __FUNCTION__);
>
>         ret = hid_parse(hdev);
>         if (ret) {
>                 hid_err(hdev, "parse failed\n");
>                 return ret;
>         } else {
>                 hid_dbg(hdev, "parse success\n");
>         }
>
>         ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
>         if (ret) {
>                 hid_err(hdev, "hw start failed\n");
>                 return ret;
>         } else {
>                 hid_dbg(hdev, "start success\n");
>         }
>         ret = hid_hw_open(hdev);
>         hid_dbg(hdev, "hid_hw_open %d\n", ret);
>
>         buf[0] = 0x50;
>         buf[1] = 0x07;
>         ret = hid_hw_output_report(hdev, buf, 64);
>         hid_dbg(hdev, "hid_hw_output_report %d back
> [%x][%x][%x][%x]\n", ret, buf[0], buf[1], buf[2], buf[3]);
>         //dmesg prints ret 0
>
>         ret = hid_hw_raw_request(hdev, 0x81, buf2, 64,
> HID_INPUT_REPORT, HID_REQ_SET_REPORT);
>         hid_dbg(hdev, "hid_input_report %d back [%x][%x][%x][%x]\n",
> ret, buf2[0], buf2[1], buf2[2], buf2[3]);
>         //dmesg prints ret -32
>
>         kfree(buf);
>         kfree(buf2);
>
>         return 0;
> }
>
> Dmesg:
> [   72.991830] MCP2210 USB SPI Driver 0003:04D8:00DE.0002: mcp2210_probe
> [   73.001793] MCP2210 USB SPI Driver 0003:04D8:00DE.0002: parse success
> [   73.020234] MCP2210 USB SPI Driver 0003:04D8:00DE.0002:
> hiddev96,hidraw0: USB HID v1.11 Device [Microchip Technology Inc.
> MCP2210 USB-to-SPI Master] on usb-3f980000.usb-1.3/input0
> [   73.039798] MCP2210 USB SPI Driver 0003:04D8:00DE.0002: start success
> [   73.111858] MCP2210 USB SPI Driver 0003:04D8:00DE.0002: hid_hw_open 0
> [   73.126599] MCP2210 USB SPI Driver 0003:04D8:00DE.0002:
> hid_hw_output_report 64 back [50][7][0][0]
> [   73.140170] MCP2210 USB SPI Driver 0003:04D8:00DE.0002:
> hid_input_report -32 back [81][0][0][0]

Hi,

Doing some hacks I can see that using a user space library for this device uses:
[   38.188226] [<806b9728>] (usbhid_output_report) from [<806b7db4>]
(hidraw_send_report+0x100/0x180)
And the layer between hidraw_send_report and usbhid_output_report is
hid_hw_output_report.  So the function I should use is
hid_hw_output_report.

[   38.137293] usbhid_output_report START
###############################################################################
[   38.137306] usbhid_output_report 30 0 0 0 1 0 0
[   38.148204] CPU: 3 PID: 475 Comm: hidusbtest Tainted: G         C
     4.19.69-v7+ #8
[   38.148210] Hardware name: BCM2835
[   38.164463] [<80111dac>] (unwind_backtrace) from [<8010d36c>]
(show_stack+0x20/0x24)
[   38.172494] [<8010d36c>] (show_stack) from [<808166bc>]
(dump_stack+0xcc/0x110)
[   38.179928] [<808166bc>] (dump_stack) from [<806b9728>]
(usbhid_output_report+0x94/0x144)
[   38.188226] [<806b9728>] (usbhid_output_report) from [<806b7db4>]
(hidraw_send_report+0x100/0x180)
[   38.197311] [<806b7db4>] (hidraw_send_report) from [<806b7e78>]
(hidraw_write+0x44/0x58)
[   38.205517] [<806b7e78>] (hidraw_write) from [<802ac2ec>]
(__vfs_write+0x48/0x170)
[   38.213193] [<802ac2ec>] (__vfs_write) from [<802ac5fc>]
(vfs_write+0xb4/0x1c4)
[   38.220604] [<802ac5fc>] (vfs_write) from [<802ac8d4>] (ksys_write+0x6c/0xec)
[   38.227841] [<802ac8d4>] (ksys_write) from [<802ac96c>] (sys_write+0x18/0x1c)
[   38.235076] [<802ac96c>] (sys_write) from [<80101000>]
(ret_fast_syscall+0x0/0x28)
[   38.242750] Exception stack(0xb391ffa8 to 0xb391fff0)
[   38.247869] ffa0:                   00000000 00014bec 00000003
7e9ec8b4 00000040 00000000
[   38.256161] ffc0: 00000000 00014bec 00010f38 00000004 00000000
00000000 76fc9000 7e9ec844
[   38.264451] ffe0: 0000006c 7e9ec810 00012f00 76cd4944
[   38.272431] usbhid_output_report END
###############################################################################

And after using hid_hw_output_report my driver get a call at mcp2210_raw_event:
[   38.333979] [<7f32a04c>] (mcp2210_raw_event [mcp2210]) from
[<806ae188>] (hid_input_report+0xf4/0x18c)

So, to receive the success status of the command sent with
hid_hw_output_report the driver receives an event.
Now I need to understand how to register my driver to receive this
event, once the hidraw driver will not be in use.

[   38.284788] hid_irq_in 0
[   38.284798] mcp2210_raw_event START
###############################################################################
[   38.287370] CPU: 0 PID: 322 Comm: rs:main Q:Reg Tainted: G
C        4.19.69-v7+ #8
[   38.306324] Hardware name: BCM2835
[   38.309787] [<80111dac>] (unwind_backtrace) from [<8010d36c>]
(show_stack+0x20/0x24)
[   38.317642] [<8010d36c>] (show_stack) from [<808166bc>]
(dump_stack+0xcc/0x110)
[   38.325062] [<808166bc>] (dump_stack) from [<7f32a04c>]
(mcp2210_raw_event+0x4c/0x120 [mcp2210])
[   38.333979] [<7f32a04c>] (mcp2210_raw_event [mcp2210]) from
[<806ae188>] (hid_input_report+0xf4/0x18c)
[   38.343420] [<806ae188>] (hid_input_report) from [<806ba39c>]
(hid_irq_in+0x20c/0x248)
[   38.351452] [<806ba39c>] (hid_irq_in) from [<8061bc48>]
(__usb_hcd_giveback_urb+0xa0/0x15c)
[   38.359923] [<8061bc48>] (__usb_hcd_giveback_urb) from [<8061befc>]
(usb_hcd_giveback_urb+0xd4/0xf4)
[   38.369188] [<8061befc>] (usb_hcd_giveback_urb) from [<80647434>]
(completion_tasklet_func+0x8c/0xcc)
[   38.378542] [<80647434>] (completion_tasklet_func) from
[<80656374>] (tasklet_callback+0x20/0x24)
[   38.387544] [<80656374>] (tasklet_callback) from [<80126a14>]
(tasklet_action_common.constprop.5+0x64/0xec)
[   38.397426] [<80126a14>] (tasklet_action_common.constprop.5) from
[<80126af4>] (tasklet_hi_action+0x28/0x30)
[   38.407394] [<80126af4>] (tasklet_hi_action) from [<801023f4>]
(__do_softirq+0x184/0x424)
[   38.415687] [<801023f4>] (__do_softirq) from [<801266ac>]
(irq_exit+0xf8/0x134)
[   38.423102] [<801266ac>] (irq_exit) from [<8017f710>]
(__handle_domain_irq+0x70/0xc4)
[   38.431044] [<8017f710>] (__handle_domain_irq) from [<801021a0>]
(bcm2836_arm_irqchip_handle_irq+0x60/0xa8)
[   38.440924] [<801021a0>] (bcm2836_arm_irqchip_handle_irq) from
[<801019bc>] (__irq_svc+0x5c/0x7c)
[   38.449919] Exception stack(0xb63e5bf0 to 0xb63e5c38)
[   38.455038] 5be0:                                     b59d022c
00000005 80c66000 b9bb87c0
[   38.463331] 5c00: b59d00b0 00000400 80c66000 b59d022c b97dc400
b63e5da0 b63e5cd4 b63e5c4c
[   38.471622] 5c20: b63e5c50 b63e5c40 8036a1e4 808322fc 40000013 ffffffff
[   38.478330] [<801019bc>] (__irq_svc) from [<808322fc>]
(_raw_spin_lock+0xc/0x54)
[   38.485834] [<808322fc>] (_raw_spin_lock) from [<8036a1e4>]
(ext4_mark_iloc_dirty+0x108/0x8c8)
[   38.494569] [<8036a1e4>] (ext4_mark_iloc_dirty) from [<8036aca4>]
(ext4_mark_inode_dirty+0x84/0x1f8)
[   38.503832] [<8036aca4>] (ext4_mark_inode_dirty) from [<8037058c>]
(ext4_dirty_inode+0x54/0x70)
[   38.512656] [<8037058c>] (ext4_dirty_inode) from [<802de768>]
(__mark_inode_dirty+0x50/0x414)
[   38.521305] [<802de768>] (__mark_inode_dirty) from [<802c97a8>]
(generic_update_time+0xf4/0x11c)
[   38.530215] [<802c97a8>] (generic_update_time) from [<802c9c88>]
(file_update_time+0x128/0x158)
[   38.539039] [<802c9c88>] (file_update_time) from [<8023b158>]
(__generic_file_write_iter+0xa0/0x1e0)
[   38.548305] [<8023b158>] (__generic_file_write_iter) from
[<80357a20>] (ext4_file_write_iter+0xfc/0x4b8)
[   38.557921] [<80357a20>] (ext4_file_write_iter) from [<802ac3b0>]
(__vfs_write+0x10c/0x170)
[   38.566390] [<802ac3b0>] (__vfs_write) from [<802ac5fc>]
(vfs_write+0xb4/0x1c4)
[   38.573800] [<802ac5fc>] (vfs_write) from [<802ac8d4>] (ksys_write+0x6c/0xec)
[   38.581034] [<802ac8d4>] (ksys_write) from [<802ac96c>] (sys_write+0x18/0x1c)
[   38.588269] [<802ac96c>] (sys_write) from [<80101000>]
(ret_fast_syscall+0x0/0x28)
[   38.595941] Exception stack(0xb63e5fa8 to 0xb63e5ff0)
[   38.601059] 5fa0:                   0000004a 75700bc0 00000007
75700bc0 0000004a 00000000
[   38.609351] 5fc0: 0000004a 75700bc0 00000007 00000004 75700bc0
fffff815 00092410 000924e8
[   38.617641] 5fe0: 00000002 760fe6e8 00000000 76eeb1bc
[   38.622762] MCP2210 USB SPI Driver 0003:04D8:00DE.0001: mcp2210_raw_event 64
[   38.629930] MCP2210 USB SPI Driver 0003:04D8:00DE.0001: 30 0 0 0 1
0 2 2 2 2 2 0 0 ff 1 ff 1 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0
[   38.646944] mcp2210_raw_event END
###############################################################################

_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

  reply	other threads:[~2020-02-04 18:23 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-31 23:12 Introduction & Query on Newbie Website Status Jack Winch
2020-02-01 12:20 ` Cindy Sue Causey
2020-02-02 23:26 ` Anuz Pratap Singh Tomar
2020-02-03  0:36   ` Rik van Riel
2020-02-03 16:32     ` USB Hid driver Help Lucas Tanure
2020-02-03 20:11       ` Greg KH
2020-02-03 22:00         ` Lucas Tanure
2020-02-04 13:27           ` Lucas Tanure
2020-02-04 18:15             ` Lucas Tanure [this message]
2020-02-03 19:49     ` Introduction & Query on Newbie Website Status Jack Winch
2020-02-03 20:10       ` Rik van Riel
2020-02-05 15:46         ` Jack Winch

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAJX_Q+2uK_8dEXcHvQLz9Usa8ixhyvTB6o4H3hVwD6MOqpLTuQ@mail.gmail.com \
    --to=tanure@linux.com \
    --cc=Kernelnewbies@kernelnewbies.org \
    --cc=greg@kroah.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.