USB Hid driver Help
Lucas Tanure
tanure at linux.com
Tue Feb 4 08:27:26 EST 2020
On Mon, Feb 3, 2020 at 10:00 PM Lucas Tanure <tanure at linux.com> wrote:
>
> On Mon, Feb 3, 2020 at 8:11 PM Greg KH <greg at 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]
More information about the Kernelnewbies
mailing list