usb/hid:The HID Simple Driver Patches 0.5.1
PATCH 1/1 usb/hid:The HID Simple Driver Patches 0.5.1
This patch set include :
1. usb/hid: The HID Simple Driver Interface 0.5.0 (core)
2. usb/hid:Microsoft Natural Ergonomic Keyboard 4000 Driver 0.5.1
3. Some related kbuild changes.
The changelog since 0.5.0:
1. The parameter ascii_keycode of usbnek4k.ko is on default. so the five custom keys can work without any care.
2. Add the parameter zoom_scroll of usbnek4k.ko, so we can use zoomin/zoomout handlers as mouse scrollwheel. this is on default too.
drivers/hid/hid-core.c +151 -2
@@ -27,8 +27,10 @@#include <linux/input.h> #include <linux/wait.h> #include <linux/vmalloc.h> +#include <linux/mutex.h> #include <linux/hid.h> +#include <linux/hid-simple.h> #include <linux/hiddev.h> #include <linux/hid-debug.h>
@@ -42,6 +44,19 @@#define DRIVER_LICENSE "GPL"/* +* The global data structure for simple device driver interface. +*/ +DEFINE_MUTEX (matched_devices_lock); +DEFINE_MUTEX (simple_drivers_lock); +LIST_HEAD (matched_devices_list); +LIST_HEAD (simple_drivers_list); + +EXPORT_SYMBOL (matched_devices_lock); +EXPORT_SYMBOL (simple_drivers_lock); +EXPORT_SYMBOL (matched_devices_list); +EXPORT_SYMBOL (simple_drivers_list); + +/* * Register a new report for a device. */
@@ -803,8 +818,12 @@ static __inline__ int search(__s32 *arrastatic void hid_process_event (struct hid_device *hid,struct hid_field *field,struct hid_usage *usage,__s32 value,int interrupt) {hid_dump_input (usage, value); -if (hid->claimed &HID_CLAIMED_INPUT ) +if (hid->claimed &HID_CLAIMED_INPUT ) { +if (!hidinput_simple_event_filter (hid, field, usage, value)) +return ;hidinput_hid_event (hid, field, usage, value); +hidinput_simple_event_post (hid, field, usage, value); + }if (hid->claimed &HID_CLAIMED_HIDDEV && interrupt && hid->hiddev_hid_event) hid->hiddev_hid_event (hid, field, usage, value); }
@@ -829,7 +848,6 @@ void hid_input_field(struct hid_device *return ;for (n =0 ; n < count; n++) { - value[n] = min <0 ?snto32 (extract (data, offset + n * size, size), size) :extract (data, offset + n * size, size);
@@ -985,5 +1003,136 @@ int hid_input_report(struct hid_device * }EXPORT_SYMBOL_GPL (hid_input_report); +#ifdef CONFIG_HID_SIMPLE +static int hidinput_simple_driver_bind_one (struct hidinput_simple_driver *simple, +struct hid_device *hid, +struct matched_device *matched, +int reload) +{ +int ret; + +if (!try_module_get (simple->owner)) +return -ENODEV ; +/* +* If the simple driver register itself after device insert, +* we must send hotplug message to userspace again, elsewise, +* we will break down some applications. +*/ +if (reload &&hidinput_disconnect_core (hid)) { +module_put (simple->owner); +return -ENODEV ; + } + ret =hidinput_simple_driver_connect (simple, matched); + +if (reload) +hidinput_reconnect_core (hid);/* To activate this input_dev */ +if (!ret) +printk (KERN_INFO "The simple driver \'%s\' attach" +" to the device \'%s\'\n" , simple->name, hid->name); +else +module_put (simple->owner); +return 0 ; +} + +void hidinput_simple_driver_bind_foreach_simple ( +struct hid_device *hid, +struct matched_device *matched) +{ +struct hidinput_simple_driver *simple; +struct list_head *node; + +if (!hid || !matched || !matched->id || matched->hid) +return ; +mutex_lock (&simple_drivers_lock); +list_for_each (node, &simple_drivers_list) { + simple = list_entry(node, struct hidinput_simple_driver, node); +if (simple->match_device (simple, matched)) { +if (!hidinput_simple_driver_bind_one (simple, hid, + matched,0 )) +break ; + } + } +mutex_unlock (&simple_drivers_lock); +} +EXPORT_SYMBOL (hidinput_simple_driver_bind_foreach_simple); + +void hidinput_simple_driver_bind_foreach_matched ( +struct hidinput_simple_driver *simple) +{ +struct list_head *node=NULL ; +struct matched_device *matched; +struct hid_device *hid=NULL ; + +if (!simple) +return ; + +mutex_lock (&matched_devices_lock); +list_for_each (node, &matched_devices_list) { + matched = list_entry(node, struct matched_device, node); + hid = matched->hid; +if (!hid || hid->simple) +continue ; +if (!simple->match_device (simple, matched)) +continue ; +if (!hidinput_simple_driver_bind_one (simple, hid, matched,1 )) +break ; + } +mutex_unlock (&matched_devices_lock); +} + +void hidinput_simple_driver_bind_foreach (void ) +{ +struct hidinput_simple_driver *simple; +struct matched_device *matched =NULL ; +struct list_head *matched_node =NULL , *simple_node =NULL ; +struct hid_device *hid =NULL ; + +mutex_lock (&matched_devices_lock); +list_for_each (matched_node, &matched_devices_list) { + matched = list_entry(matched_node, struct matched_device, node); + hid = matched->hid; +if (!hid || hid->simple) +continue ; +mutex_lock (&simple_drivers_lock); +list_for_each (simple_node, &simple_drivers_list) { + simple = list_entry(simple_node, struct hidinput_simple_driver, node); +if (!simple->match_device (simple,matched)) +continue ; +hidinput_simple_driver_bind_one (simple, + hid, matched,1 ); + } +mutex_unlock (&simple_drivers_lock); + } +mutex_unlock (&matched_devices_lock); +} + +int hidinput_register_simple_driver (struct hidinput_simple_driver *simple) +{ +if (!simple || !simple->name) +return -EINVAL ; + +hidinput_simple_driver_init (simple); +hidinput_simple_driver_bind_foreach_matched (simple); + +mutex_lock (&simple_drivers_lock); +list_add (&simple->node, &simple_drivers_list); +mutex_unlock (&simple_drivers_lock); + +return 0 ; +} +EXPORT_SYMBOL_GPL (hidinput_register_simple_driver); + +void hidinput_unregister_simple_driver (struct hidinput_simple_driver *simple) +{ +hidinput_simple_driver_clear (simple); +mutex_lock (&simple_drivers_lock); +list_del (&simple->node); +mutex_unlock (&simple_drivers_lock); +/* to active simple device driver that it is waiting */ +hidinput_simple_driver_bind_foreach (); +} +EXPORT_SYMBOL_GPL (hidinput_unregister_simple_driver); +#endif +MODULE_LICENSE (DRIVER_LICENSE );
drivers/hid/hid-input.c +157 -42
370 lines not on this page · raw message
drivers/hid/hid-simple.c +334 -0
334 lines not on this page · raw message
drivers/hid/Kconfig +8 -0
@@ -36,5 +36,13 @@ config HID_DEBUG If unsure, say N +config HID_SIMPLE + bool "HID simple driver interface" + depends on HID + help + This simple interface let the writing HID driver more easier. Moreover, + this allow you write force-feedback driver without touch HID input + implementation code. Also, it can be used as input filter. + endmenu
drivers/hid/Makefile +4 -0
@@ -3,6 +3,10 @@ # hid-objs := hid-core.o hid-input.o +ifeq ($(CONFIG_HID_SIMPLE),y) +hid-objs += hid-simple.o +endif + obj-$(CONFIG_HID) += hid.o hid-$(CONFIG_HID_DEBUG) += hid-debug.o
drivers/usb/input/hid-core.c +80 -3
124 lines not on this page · raw message
drivers/usb/input/Kconfig +9 -0
@@ -357,6 +357,15 @@ config USB_APPLETOUCH To compile this driver as a module, choose M here: the module will be called appletouch. +config HID_SIMPLE_MSNEK4K + tristate "Microsoft Natural Ergonomic Keyboard 4000 Driver" + depends on HID_SIMPLE + ---help--- + Microsoft Natural Ergonomic Keyboard 4000 extended keys support. These + may not work without change user space configration, e.g, XKB conf- + iguration in X. + + config USB_GTCO tristate "GTCO CalComp/InterWrite USB Support" depends on USB && INPUT
drivers/usb/input/Makefile +1 -0
@@ -48,6 +48,7 @@ obj-$(CONFIG_USB_ACECAD) += acecad.o obj-$(CONFIG_USB_YEALINK) += yealink.o obj-$(CONFIG_USB_XPAD) += xpad.o obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o +obj-$(CONFIG_HID_SIMPLE_MSNEK4K) += usbnek4k.o obj-$(CONFIG_USB_GTCO) += gtco.o ifeq ($(CONFIG_USB_DEBUG),y)
drivers/usb/input/usbnek4k.c +356 -0
356 lines not on this page · raw message
include/linux/hid.h +12 -0
@@ -35,6 +35,7 @@#include <linux/timer.h> #include <linux/workqueue.h> #include <linux/input.h> +#include <linux/mutex.h> /* * USB HID (Human Interface Device) interface class code
@@ -399,8 +400,15 @@ struct hid_input {struct list_head list;struct hid_report *report;struct input_dev *input; +unsigned long input_lock;/* To protect accessing input_dev from +* hid-input processing. But it not +* necessary for accessing this input_dev +* instance from input subsystem. */ +void *private; }; +struct hidinput_simple_driver ; +struct hid_device {/* device report descriptor */ __u8 *rdesc;unsigned rsize;
@@ -431,6 +439,8 @@ struct hid_device { /* device repochar phys[64 ];/* Device physical location */ char uniq[64 ];/* Device unique identifier (serial #) */ +struct hidinput_simple_driver *simple; +void *driver_data;/* device-specific function pointers */
@@ -485,6 +495,8 @@ extern void hidinput_hid_event(struct hiextern void hidinput_report_event (struct hid_device *hid,struct hid_report *report);extern int hidinput_connect (struct hid_device *);extern void hidinput_disconnect (struct hid_device *); +extern void hidinput_reconnect_core (struct hid_device *); +extern int hidinput_disconnect_core (struct hid_device *);int hid_set_field (struct hid_field *,unsigned ,__s32 );int hid_input_report (struct hid_device *,int type,u8 *,int ,int );
include/linux/hid-simple.h +260 -0
260 lines not on this page · raw message
Quoted 10 lines · Li Yu
This patch set include :
1. usb/hid: The HID Simple Driver Interface 0.5.0 (core)
2. usb/hid:Microsoft Natural Ergonomic Keyboard 4000 Driver 0.5.1
3. Some related kbuild changes.
The changelog since 0.5.0:
1. The parameterascii_keycodeof usbnek4k.ko is on default. so the five custom keys can work without any care.
2. Add the parameterzoom_scrollof usbnek4k.ko, so we can use zoomin/zoomout handlers as mouse scrollwheel. this is on default too.
Hi Li,
is there any chance that you rather split up the hid bus patch you have been working on recently into independent reviewable patches instead, as we were discussing it previously?
Thanks,
Signature · 1 line
Jiri Kosina