LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* led and hid class - hid_device vs led_classdev
@ 2008-11-04 7:51 Adam Nielsen
2008-11-04 21:48 ` Jiri Slaby
0 siblings, 1 reply; 7+ messages in thread
From: Adam Nielsen @ 2008-11-04 7:51 UTC (permalink / raw)
To: LKML Mailinglist
Hi all,
I'm writing a driver for a USB HID device (using the new hid class), but
I'm a bit confused about how the hid_device structure relates to the
other driver-information structures.
One of the functions the device implements is a LED. This is pretty
simple to control (basic on/off), so I'd like to implement a device in
the "led" class that controls this led.
In my hid driver's probe function I'm given a struct hid_device* which
is used with functions like hid_hw_start().
I then need to call led_classdev_register() to register my led device.
At the moment I pass this function hid_device.dev
Then I set my custom driver data with hid_set_drvdata().
Later on, when the user wants to switch the LED on or off, a function in
my driver gets called, with a struct led_classdev* parameter.
I'm stuck trying to figure out how to convert this led_classdev
parameter back into a hid_device, so that I can extract the custom data
I set with hid_set_drvdata().
Some of the led drivers use platform_set_drvdata() in their probe
functions to get their custom data instead, but I'm afraid if I do this
I'll overwrite any hid-related data that hid_set_drvdata() might tack on
to my custom data.
Some pseudocode to help illustrate:
static int my_probe(struct hid_device *hid,
const struct hid_device_id *id)
{
hid_parse(hid);
hid_hw_start(hid, HID_CONNECT_DEFAULT);
led_classdev_register(&hid->dev, &my_led);
hid_set_drvdata(hid, my_data);
/* Don't want to use this, in case it overwrites something that
hid_set_drvdata() includes. */
/*platform_set_drvdata(&hid->dev, my_data);*/
}
/* Callback function when user wants to change LED state */
static void my_led_set(struct led_classdev *led_cdev,
enum led_brightness value)
{
/* How do I get my_data back? */
}
Hopefully this explains what I'm after - if you need me to clarify
anything please let me know.
Many thanks,
Adam.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: led and hid class - hid_device vs led_classdev
2008-11-04 7:51 led and hid class - hid_device vs led_classdev Adam Nielsen
@ 2008-11-04 21:48 ` Jiri Slaby
2008-11-08 6:18 ` hid class and sysfs/hwmon (was: led and hid class - hid_device vs led_classdev) Adam Nielsen
0 siblings, 1 reply; 7+ messages in thread
From: Jiri Slaby @ 2008-11-04 21:48 UTC (permalink / raw)
To: Adam Nielsen; +Cc: LKML Mailinglist
On 11/04/2008 08:51 AM, Adam Nielsen wrote:
> /* Callback function when user wants to change LED state */
> static void my_led_set(struct led_classdev *led_cdev,
> enum led_brightness value)
> {
> /* How do I get my_data back? */
> }
>
> Hopefully this explains what I'm after - if you need me to clarify
> anything please let me know.
my_led should by part of my_data, then you do
my_data = container_of(led_cdev, /*typeof(my_data)*/, my_led);
^ permalink raw reply [flat|nested] 7+ messages in thread
* hid class and sysfs/hwmon (was: led and hid class - hid_device vs led_classdev)
2008-11-04 21:48 ` Jiri Slaby
@ 2008-11-08 6:18 ` Adam Nielsen
2008-11-08 14:16 ` hid class and sysfs/hwmon Jiri Slaby
0 siblings, 1 reply; 7+ messages in thread
From: Adam Nielsen @ 2008-11-08 6:18 UTC (permalink / raw)
To: Jiri Slaby; +Cc: LKML Mailinglist
>> static void my_led_set(struct led_classdev *led_cdev,
>> enum led_brightness value)
>> {
>> /* How do I get my_data back? */
>> }
>>
>
> my_led should by part of my_data, then you do
> my_data = container_of(led_cdev, /*typeof(my_data)*/, my_led);
That did the trick, thanks! I hadn't realised what container_of() was
meant to be for - that's quite a useful little macro!
I got that working (can switch the LED on and off via the led device)
but now I'm stuck trying to implement a hwmon interface for the device's
sensors.
As far as I can tell I'm doing everything fine, but for some reason the
hwmon interface gets created but with no files inside it (apart from a
few defaults.) It's supposed to have files like "temp1_input" to report
temperatures, but these files never appear.
The only thing that I'm unsure of is the first parameter to
sysfs_create_group(). All the other drivers use something like
i2c_client.dev.kobj or platform_device.dev.kobj, but I'm using
hid_device.dev.kobj. I'm guessing that should work just as well, but I
can't figure out why else the sysfs files never appear in the new hwmon
folder in /sys/class/hwmon/
Here is the code so far, if it's useful: (I've omitted all the error
checking code for clarity, all the functions called here return success)
--------------------------------------------
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
static struct attribute *odin_attributes[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
NULL
};
static const struct attribute_group odin_attr_group = {
.attrs = odin_attributes,
};
static int odin_probe(struct hid_device *hdev,
const struct hid_device_id *id)
{
hid_parse(hdev);
hid_hw_start(hdev, HID_CONNECT_DEFAULT);
odin_psu = kzalloc(sizeof(struct odin_psu_device), GFP_KERNEL);
odin_psu->hdev = hdev;
hid_set_drvdata(hdev, odin_psu);
sysfs_create_group(&hdev->dev.kobj, &odin_attr_group);
odin_psu->hwmon_dev = hwmon_device_register(&hdev->dev);
return 0;
}
--------------------------------------------
$ ls /sys/class/hwmon/hwmon5/
total 0
drwxr-xr-x 3 root root 0 2008-11-08 14:50 .
drwxr-xr-x 8 root root 0 2008-11-08 14:50 ..
lrwxrwxrwx 1 root root 0 2008-11-08 14:50 device ->
../../../devices/pci0000:00/0000:00:1d.2/usb8/8-1/8-1:1.0/0003:1044:4001.0001
drwxr-xr-x 2 root root 0 2008-11-08 14:50 power
lrwxrwxrwx 1 root root 0 2008-11-08 14:50 subsystem -> ../../hwmon
-rw-r--r-- 1 root root 4.0K 2008-11-08 14:50 uevent
--------------------------------------------
If anyone can see why this might result in no sysfs files, please let me
know! I previously had most of this code working with a platform_device
instead of the hid_device, which is what makes me wonder about
hdev->dev.kobj. (Not sure how to test if that variable is accurate,
either.) Or perhaps it has already been used elsewhere and it can only
be used once?
Thanks,
Adam.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: hid class and sysfs/hwmon
2008-11-08 6:18 ` hid class and sysfs/hwmon (was: led and hid class - hid_device vs led_classdev) Adam Nielsen
@ 2008-11-08 14:16 ` Jiri Slaby
2008-11-08 21:45 ` Adam Nielsen
0 siblings, 1 reply; 7+ messages in thread
From: Jiri Slaby @ 2008-11-08 14:16 UTC (permalink / raw)
To: Adam Nielsen; +Cc: LKML Mailinglist
On 11/08/2008 07:18 AM, Adam Nielsen wrote:
> Here is the code so far, if it's useful: (I've omitted all the error
> checking code for clarity, all the functions called here return success)
>
> --------------------------------------------
> static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
>
> static struct attribute *odin_attributes[] = {
> &sensor_dev_attr_temp1_input.dev_attr.attr,
> NULL
> };
>
> static const struct attribute_group odin_attr_group = {
> .attrs = odin_attributes,
> };
>
> static int odin_probe(struct hid_device *hdev,
> const struct hid_device_id *id)
> {
> hid_parse(hdev);
> hid_hw_start(hdev, HID_CONNECT_DEFAULT);
>
> odin_psu = kzalloc(sizeof(struct odin_psu_device), GFP_KERNEL);
> odin_psu->hdev = hdev;
>
> hid_set_drvdata(hdev, odin_psu);
>
> sysfs_create_group(&hdev->dev.kobj, &odin_attr_group);
> odin_psu->hwmon_dev = hwmon_device_register(&hdev->dev);
>
> return 0;
> }
> --------------------------------------------
> If anyone can see why this might result in no sysfs files, please let me
> know! I previously had most of this code working with a platform_device
> instead of the hid_device, which is what makes me wonder about
> hdev->dev.kobj. (Not sure how to test if that variable is accurate,
> either.) Or perhaps it has already been used elsewhere and it can only
> be used once?
I suppose it's under /sys/bus/hid/devices/.../, isn't it?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: hid class and sysfs/hwmon
2008-11-08 14:16 ` hid class and sysfs/hwmon Jiri Slaby
@ 2008-11-08 21:45 ` Adam Nielsen
2008-11-08 21:51 ` Jiri Slaby
0 siblings, 1 reply; 7+ messages in thread
From: Adam Nielsen @ 2008-11-08 21:45 UTC (permalink / raw)
To: Jiri Slaby; +Cc: LKML Mailinglist
>> If anyone can see why this might result in no sysfs files, please let me
>> know! I previously had most of this code working with a platform_device
>> instead of the hid_device, which is what makes me wonder about
>> hdev->dev.kobj. (Not sure how to test if that variable is accurate,
>> either.) Or perhaps it has already been used elsewhere and it can only
>> be used once?
>
> I suppose it's under /sys/bus/hid/devices/.../, isn't it?
Aha, yes! I didn't even think of checking there. I suppose this means
I have to create another device (like a platform_device) in order to
have the sysfs files appear in the correct place?
Is a platform_device the correct type to create, or is there another way?
Thanks,
Adam.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: hid class and sysfs/hwmon
2008-11-08 21:45 ` Adam Nielsen
@ 2008-11-08 21:51 ` Jiri Slaby
2008-11-08 22:02 ` Adam Nielsen
0 siblings, 1 reply; 7+ messages in thread
From: Jiri Slaby @ 2008-11-08 21:51 UTC (permalink / raw)
To: Adam Nielsen; +Cc: LKML Mailinglist
Adam Nielsen napsal(a):
>>> If anyone can see why this might result in no sysfs files, please let me
>>> know! I previously had most of this code working with a platform_device
>>> instead of the hid_device, which is what makes me wonder about
>>> hdev->dev.kobj. (Not sure how to test if that variable is accurate,
>>> either.) Or perhaps it has already been used elsewhere and it can only
>>> be used once?
>>
>> I suppose it's under /sys/bus/hid/devices/.../, isn't it?
>
> Aha, yes! I didn't even think of checking there. I suppose this means
> I have to create another device (like a platform_device) in order to
> have the sysfs files appear in the correct place?
>
> Is a platform_device the correct type to create, or is there another way?
I don't know much about hwmon, but I would guess you should use hwmon_dev
for registering the attributes if you want it under /sys/class/hwmon/...
Such as:
sysfs_create_group(&odin_psu->hwmon_dev->kobj, &odin_attr_group);
No?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: hid class and sysfs/hwmon
2008-11-08 21:51 ` Jiri Slaby
@ 2008-11-08 22:02 ` Adam Nielsen
0 siblings, 0 replies; 7+ messages in thread
From: Adam Nielsen @ 2008-11-08 22:02 UTC (permalink / raw)
To: Jiri Slaby; +Cc: LKML Mailinglist
> I don't know much about hwmon, but I would guess you should use hwmon_dev
> for registering the attributes if you want it under /sys/class/hwmon/...
>
> Such as:
> sysfs_create_group(&odin_psu->hwmon_dev->kobj, &odin_attr_group);
>
> No?
Oh, that worked! All the other hwmon drivers seem to have it the other
way around, i.e. you attach sysfs to your original bus/class device kobj
instead of the hwmon kobj.
Hopefully doing it this way won't have any side effects...
Thanks for your help Jiri!
Cheers,
Adam.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2008-11-08 22:02 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-11-04 7:51 led and hid class - hid_device vs led_classdev Adam Nielsen
2008-11-04 21:48 ` Jiri Slaby
2008-11-08 6:18 ` hid class and sysfs/hwmon (was: led and hid class - hid_device vs led_classdev) Adam Nielsen
2008-11-08 14:16 ` hid class and sysfs/hwmon Jiri Slaby
2008-11-08 21:45 ` Adam Nielsen
2008-11-08 21:51 ` Jiri Slaby
2008-11-08 22:02 ` Adam Nielsen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).