Skip to content

Commit

Permalink
HID: roccat: propagate special events of roccat hardware to userspace
Browse files Browse the repository at this point in the history
Module roccat is a char device used to report special events of roccat hardware
to userland. These events include requests for on-screen-display of profile or
dpi settings or requests for execution of macro sequences that are not stored
in device. The information in these events depends on hid device implementation
and contains data that is not available in a single hid event or else hidraw
could have been used.

It is inspired by hidraw, but uses only one circular buffer for all readers.
The device is as generic as possible so that the functionality is usable by all
(kone and upcomming) roccat device drivers.

Signed-off-by: Stefan Achatz <erazor_de@users.sourceforge.net>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
  • Loading branch information
Stefan Achatz authored and Jiri Kosina committed May 25, 2010
1 parent c2fd1a4 commit 206f5f2
Show file tree
Hide file tree
Showing 6 changed files with 526 additions and 0 deletions.
8 changes: 8 additions & 0 deletions drivers/hid/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,14 @@ config HID_QUANTA
---help---
Support for Quanta Optical Touch dual-touch panels.

config HID_ROCCAT
tristate "Roccat special event support"
depends on USB_HID
---help---
Support for Roccat special events.
Say Y here if you have a Roccat mouse or keyboard and want OSD or
macro execution support.

config HID_ROCCAT_KONE
tristate "Roccat Kone Mouse support"
depends on USB_HID
Expand Down
1 change: 1 addition & 0 deletions drivers/hid/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ obj-$(CONFIG_HID_QUANTA) += hid-quanta.o
obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o
obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o
obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o
obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o
obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
Expand Down
49 changes: 49 additions & 0 deletions drivers/hid/hid-roccat-kone.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include "hid-ids.h"
#include "hid-roccat.h"
#include "hid-roccat-kone.h"

static void kone_set_settings_checksum(struct kone_settings *settings)
Expand Down Expand Up @@ -849,6 +850,16 @@ static int kone_init_specials(struct hid_device *hdev)
"couldn't init struct kone_device\n");
goto exit_free;
}

retval = roccat_connect(hdev);
if (retval < 0) {
dev_err(&hdev->dev, "couldn't init char dev\n");
/* be tolerant about not getting chrdev */
} else {
kone->roccat_claimed = 1;
kone->chrdev_minor = retval;
}

retval = kone_create_sysfs_attributes(intf);
if (retval) {
dev_err(&hdev->dev, "cannot create sysfs files\n");
Expand All @@ -868,10 +879,14 @@ static int kone_init_specials(struct hid_device *hdev)
static void kone_remove_specials(struct hid_device *hdev)
{
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
struct kone_device *kone;

if (intf->cur_altsetting->desc.bInterfaceProtocol
== USB_INTERFACE_PROTOCOL_MOUSE) {
kone_remove_sysfs_attributes(intf);
kone = hid_get_drvdata(hdev);
if (kone->roccat_claimed)
roccat_disconnect(kone->chrdev_minor);
kfree(hid_get_drvdata(hdev));
}
}
Expand Down Expand Up @@ -930,6 +945,37 @@ static void kone_keep_values_up_to_date(struct kone_device *kone,
}
}

static void kone_report_to_chrdev(struct kone_device const *kone,
struct kone_mouse_event const *event)
{
struct kone_roccat_report roccat_report;

switch (event->event) {
case kone_mouse_event_switch_profile:
case kone_mouse_event_switch_dpi:
case kone_mouse_event_osd_profile:
case kone_mouse_event_osd_dpi:
roccat_report.event = event->event;
roccat_report.value = event->value;
roccat_report.key = 0;
roccat_report_event(kone->chrdev_minor,
(uint8_t *)&roccat_report,
sizeof(struct kone_roccat_report));
break;
case kone_mouse_event_call_overlong_macro:
if (event->value == kone_keystroke_action_press) {
roccat_report.event = kone_mouse_event_call_overlong_macro;
roccat_report.value = kone->actual_profile;
roccat_report.key = event->macro_key;
roccat_report_event(kone->chrdev_minor,
(uint8_t *)&roccat_report,
sizeof(struct kone_roccat_report));
}
break;
}

}

/*
* Is called for keyboard- and mousepart.
* Only mousepart gets informations about special events in its extended event
Expand Down Expand Up @@ -958,6 +1004,9 @@ static int kone_raw_event(struct hid_device *hdev, struct hid_report *report,

kone_keep_values_up_to_date(kone, event);

if (kone->roccat_claimed)
kone_report_to_chrdev(kone, event);

return 0; /* always do further processing */
}

Expand Down
9 changes: 9 additions & 0 deletions drivers/hid/hid-roccat-kone.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,12 @@ enum kone_commands {
kone_command_firmware = 0xe5a
};

struct kone_roccat_report {
uint8_t event;
uint8_t value; /* holds dpi or profile value */
uint8_t key; /* macro key on overlong macro execution */
};

#pragma pack(pop)

struct kone_device {
Expand Down Expand Up @@ -219,6 +225,9 @@ struct kone_device {
* so it's read only once
*/
int firmware_version;

int roccat_claimed;
int chrdev_minor;
};

#endif
Loading

0 comments on commit 206f5f2

Please sign in to comment.