aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2007-05-14 09:57:40 +0200
committerJiri Kosina <jkosina@suse.cz>2007-10-14 14:47:26 +0200
commit86166b7bcda0bcb53525114fa1c87ac432be478e (patch)
tree1f6afc4c1c1d7a6dd88236f3c11fde61c1885b14 /include
parentefc493f9d5463d933a64a2758fbe6d9bb8300cbb (diff)
HID: add hidraw interface
hidraw is an interface that is going to obsolete hiddev one day. Many userland applications are using libusb instead of using kernel-provided hiddev interface. This is caused by various reasons - the HID parser in kernel doesn't handle all the HID hardware on the planet properly, some devices might require its own specific quirks/drivers, etc. hiddev interface tries to do its best to parse all the received reports properly, and presents only parsed usages into userspace. This is however often not enough, and that's the reason why many userland applications just don't use hiddev at all, and rather use libusb to read raw USB events and process them on their own. Another drawback of hiddev is that it is USB-specific. hidraw interface provides userspace readers with really raw HID reports, no matter what the low-level transport layer is (USB/BT), and gives the userland applications all the freedom to process the HID reports in a way they wish to. Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'include')
-rw-r--r--include/linux/hid.h5
-rw-r--r--include/linux/hidraw.h86
2 files changed, 91 insertions, 0 deletions
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 898103b401f..0ac2b5260b2 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -403,6 +403,7 @@ struct hid_control_fifo {
#define HID_CLAIMED_INPUT 1
#define HID_CLAIMED_HIDDEV 2
+#define HID_CLAIMED_HIDRAW 4
#define HID_CTRL_RUNNING 1
#define HID_OUT_RUNNING 2
@@ -438,6 +439,7 @@ struct hid_device { /* device report descriptor */
struct list_head inputs; /* The list of inputs */
void *hiddev; /* The hiddev structure */
+ void *hidraw;
int minor; /* Hiddev minor number */
wait_queue_head_t wait; /* For sleeping */
@@ -458,6 +460,9 @@ struct hid_device { /* device report descriptor */
void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field,
struct hid_usage *, __s32);
void (*hiddev_report_event) (struct hid_device *, struct hid_report *);
+
+ /* handler for raw output data, used by hidraw */
+ int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t);
#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
unsigned long pb_pressed_fn[NBITS(KEY_MAX)];
unsigned long pb_pressed_numlock[NBITS(KEY_MAX)];
diff --git a/include/linux/hidraw.h b/include/linux/hidraw.h
new file mode 100644
index 00000000000..6676cd5e995
--- /dev/null
+++ b/include/linux/hidraw.h
@@ -0,0 +1,86 @@
+#ifndef _HIDRAW_H
+#define _HIDRAW_H
+
+/*
+ * Copyright (c) 2007 Jiri Kosina
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+struct hidraw_report_descriptor {
+ __u32 size;
+ __u8 *value;
+};
+
+struct hidraw_devinfo {
+ __u32 bustype;
+ __s16 vendor;
+ __s16 product;
+};
+
+/* ioctl interface */
+#define HIDIOCGRDESCSIZE _IOR('H', 0x01, int)
+#define HIDIOCGRDESC _IOR('H', 0x02, struct hidraw_report_descriptor)
+#define HIDIOCGRAWINFO _IOR('H', 0x03, struct hidraw_devinfo)
+
+#define HIDRAW_FIRST_MINOR 0
+#define HIDRAW_MAX_DEVICES 64
+/* number of reports to buffer */
+#define HIDRAW_BUFFER_SIZE 64
+
+
+/* kernel-only API declarations */
+#ifdef __KERNEL__
+
+#include <linux/hid.h>
+
+struct hidraw {
+ unsigned int minor;
+ int exist;
+ int open;
+ wait_queue_head_t wait;
+ struct hid_device *hid;
+ struct device *dev;
+ struct list_head list;
+};
+
+struct hidraw_report {
+ __u8 *value;
+ int len;
+};
+
+struct hidraw_list {
+ struct hidraw_report buffer[HIDRAW_BUFFER_SIZE];
+ int head;
+ int tail;
+ struct fasync_struct *fasync;
+ struct hidraw *hidraw;
+ struct list_head node;
+ struct mutex read_mutex;
+};
+
+#ifdef CONFIG_HIDRAW
+int hidraw_init(void);
+void hidraw_exit(void);
+void hidraw_report_event(struct hid_device *, u8 *, int);
+int hidraw_connect(struct hid_device *);
+void hidraw_disconnect(struct hid_device *);
+#else
+static inline int hidraw_init(void) { return 0; }
+static inline void hidraw_exit(void) { }
+static inline void hidraw_report_event(struct hid_device *hid, u8 *data, int len) { }
+static inline int hidraw_connect(struct hid_device *hid) { return -1; }
+static inline void hidraw_disconnect(struct hid_device *hid) { }
+#endif
+
+#endif
+
+#endif