2008-11-01 11:58:16

by Adam Nielsen

[permalink] [raw]
Subject: Can you use the USB HID interface within a driver?

Hi all,

I'm about to start writing a driver for a Gigabyte Odin PC power supply.
This device has a USB connection which allows you to monitor
temperature, voltages, current, etc.

Before I start coding the USB side of things, I'd just like some advice
as to the best way of communicating with the device.

I would rather write the driver in kernel space (so that it "just works"
and provides a hwmon interface without installing extra software),
however the device already appears to the system as a USB HID device,
and so gets claimed by the existing usbhid driver.

Is there any way to interface with the HID driver from within another
driver? Or will I have to claim the device first (or disconnect
usbhid), and communicate with it myself?

I've tried to find some example code from a driver that already does
this (such as a USB keyboard driver) but I'm having some trouble finding
one! The closest drivers I can find are all the ones in
drivers/hid/usbhid, but they all seem to be "embedded" in hid-core.c.
Does that mean I need to modify hid-core.c to call my driver?

Or perhaps someone could point me in the direction of a USB HID driver
that does things "properly" already?

Many thanks,
Adam.


2008-11-01 12:08:53

by Oliver Neukum

[permalink] [raw]
Subject: Re: Can you use the USB HID interface within a driver?

Am Samstag, 1. November 2008 12:44:51 schrieb Adam Nielsen:
> I've tried to find some example code from a driver that already does
> this (such as a USB keyboard driver) but I'm having some trouble finding
> one!  The closest drivers I can find are all the ones in
> drivers/hid/usbhid, but they all seem to be "embedded" in hid-core.c.
> Does that mean I need to modify hid-core.c to call my driver?
>
> Or perhaps someone could point me in the direction of a USB HID driver
> that does things "properly" already?

Please post "lsusb -v" for your device.

Regards
Oliver

2008-11-01 12:32:38

by Adam Nielsen

[permalink] [raw]
Subject: Re: Can you use the USB HID interface within a driver?

>> Or perhaps someone could point me in the direction of a USB HID driver
>> that does things "properly" already?
>
> Please post "lsusb -v" for your device.

Here's the output. I don't think any of the "class" drivers are
suitable, except as templates for interfacing with the main HID code...I
think...

Bus 008 Device 002: ID 1044:4001 Chu Yuen Enterprise Co., Ltd
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x1044 Chu Yuen Enterprise Co., Ltd
idProduct 0x4001
bcdDevice 1.01
iManufacturer 1 GIGABYTE TECHNOLOGY
iProduct 2 GBT 800W PSU
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 34
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.10
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 32
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 0x0008 1x 8 bytes
bInterval 10
Device Status: 0x0000
(Bus Powered)


Cheers,
Adam.

2008-11-01 14:52:39

by Kay Sievers

[permalink] [raw]
Subject: Re: Can you use the USB HID interface within a driver?

On Sat, Nov 1, 2008 at 13:32, Adam Nielsen <[email protected]> wrote:
>>> Or perhaps someone could point me in the direction of a USB HID driver
>>> that does things "properly" already?
>>
>> Please post "lsusb -v" for your device.
>
> Here's the output. I don't think any of the "class" drivers are suitable,
> except as templates for interfacing with the main HID code...I think...

I think, a real in-kernel driver for HID Power devices, which exports
the device as a "power_supply" device to userspace, would be nice.

That way, USB UPS's which support the HID Power devices:
http://www.usb.org/developers/devclass_docs/pdcv10.pdf

would show up like any other battery and AC connector and userspace
could handle all of them without any specialized code:
ls -1 /sys/class/power_supply/BAT0/
alarm
energy_full
energy_full_design
energy_now
manufacturer
model_name
power
present
serial_number
status
technology
type
voltage_min_design
voltage_now
...

Thanks,
Kay

2008-11-01 20:26:40

by Jiri Kosina

[permalink] [raw]
Subject: Re: Can you use the USB HID interface within a driver?

On Sat, 1 Nov 2008, Adam Nielsen wrote:

> I would rather write the driver in kernel space (so that it "just works"
> and provides a hwmon interface without installing extra software),
> however the device already appears to the system as a USB HID device,
> and so gets claimed by the existing usbhid driver.

There is a long blacklist/ignorelist in the usbhid driver, for the VID/PID
combinations that we don't want to have claimed by usbhid driver, because
there is a more specific one.

> Is there any way to interface with the HID driver from within another
> driver? Or will I have to claim the device first (or disconnect usbhid),
> and communicate with it myself?
> I've tried to find some example code from a driver that already does this
> (such as a USB keyboard driver) but I'm having some trouble finding one! The
> closest drivers I can find are all the ones in drivers/hid/usbhid, but they
> all seem to be "embedded" in hid-core.c. Does that mean I need to modify
> hid-core.c to call my driver?

For 2.6.28, the HID code has been completely refactored, and converted
into a proper bus, making it possible to write driver easily in a way that
the driver implements only parts where device deviates from the HID
standard, and lets the rest to be handled by generic code. I guess this is
what you are looking for?

Please look at drivers/hid in 2.6.28-rc1 or newer. There are quite a
couple of drivers already using this new infrastructure.

If you have any further questions, I'll be happy to help you, but I will
be completely offline until 11th November, sorry.

Hope this helps,

--
Jiri Kosina
SUSE Labs

2008-11-01 23:20:28

by Adam Nielsen

[permalink] [raw]
Subject: Re: Can you use the USB HID interface within a driver?

> For 2.6.28, the HID code has been completely refactored, and converted
> into a proper bus, making it possible to write driver easily in a way that
> the driver implements only parts where device deviates from the HID
> standard, and lets the rest to be handled by generic code. I guess this is
> what you are looking for?

Yes, that sounds like exactly what I'm after! This device seems to be
HID with a custom protocol over the top, so presumably I can let the HID
driver handle all the USB initialisation and just focus on the protocol.

> Please look at drivers/hid in 2.6.28-rc1 or newer. There are quite a
> couple of drivers already using this new infrastructure.

Great, I'll have a look now - thanks!

> If you have any further questions, I'll be happy to help you, but I will
> be completely offline until 11th November, sorry.

Thanks for that! I'll see how I go. If there are existing drivers I
can use as examples, hopefully I should be okay for the most part.

Cheers,
Adam.

2008-11-02 06:43:35

by Adam Nielsen

[permalink] [raw]
Subject: Driver for new hid class (was: Can you use the USB HID interface within a driver?)

>> For 2.6.28, the HID code has been completely refactored, and converted
>> into a proper bus, making it possible to write driver easily in a way
>> that the driver implements only parts where device deviates from the
>> HID standard, and lets the rest to be handled by generic code. I guess
>> this is what you are looking for?
>
> Yes, that sounds like exactly what I'm after! This device seems to be
> HID with a custom protocol over the top, so presumably I can let the HID
> driver handle all the USB initialisation and just focus on the protocol.

Okay, I've upgraded to 2.6.28-rc2 and started writing a driver for the
new hid class. It didn't take long for me to get stuck though :-(

When I load my module, it calls hid_register_driver() which returns
0/success. However that's as far as it gets. I've defined a probe
function to attach to the device, but this never gets called.

Is there something else I need to do? The USB IDs are right, and I
tried replugging the device with my "driver" loaded but it seems to be
ignored. It seems the device appears as a full HID input
implementation, so it gets an evdev device associated with it.

Does this mean I need to blacklist it to stop the HID input driver from
claiming it? Or should my driver be able to claim it in preference to
the input driver as mine is for a specific device, as opposed to the
whole class?

Thanks,
Adam.

2008-11-02 12:14:35

by Jiri Slaby

[permalink] [raw]
Subject: Re: Driver for new hid class

On 11/02/2008 07:43 AM, Adam Nielsen wrote:
> Does this mean I need to blacklist it to stop the HID input driver from
> claiming it?

Yes, add the ids also to hid_blacklist to forbid generic driver binding the device.