diff options
Diffstat (limited to 'drivers/hid/hid-uclogic-core.c')
-rw-r--r-- | drivers/hid/hid-uclogic-core.c | 61 |
1 files changed, 42 insertions, 19 deletions
diff --git a/drivers/hid/hid-uclogic-core.c b/drivers/hid/hid-uclogic-core.c index cfbbc39807a6..f67835f9ed4c 100644 --- a/drivers/hid/hid-uclogic-core.c +++ b/drivers/hid/hid-uclogic-core.c @@ -22,25 +22,6 @@ #include "hid-ids.h" -/* Driver data */ -struct uclogic_drvdata { - /* Interface parameters */ - struct uclogic_params params; - /* Pointer to the replacement report descriptor. NULL if none. */ - __u8 *desc_ptr; - /* - * Size of the replacement report descriptor. - * Only valid if desc_ptr is not NULL - */ - unsigned int desc_size; - /* Pen input device */ - struct input_dev *pen_input; - /* In-range timer */ - struct timer_list inrange_timer; - /* Last rotary encoder state, or U8_MAX for none */ - u8 re_state; -}; - /** * uclogic_inrange_timeout - handle pen in-range state timeout. * Emulate input events normally generated when pen goes out of range for @@ -202,6 +183,7 @@ static int uclogic_probe(struct hid_device *hdev, } timer_setup(&drvdata->inrange_timer, uclogic_inrange_timeout, 0); drvdata->re_state = U8_MAX; + drvdata->quirks = id->driver_data; hid_set_drvdata(hdev, drvdata); /* Initialize the device and retrieve interface parameters */ @@ -268,6 +250,34 @@ static int uclogic_resume(struct hid_device *hdev) #endif /** + * uclogic_exec_event_hook - if the received event is hooked schedules the + * associated work. + * + * @p: Tablet interface report parameters. + * @event: Raw event. + * @size: The size of event. + * + * Returns: + * Whether the event was hooked or not. + */ +static bool uclogic_exec_event_hook(struct uclogic_params *p, u8 *event, int size) +{ + struct uclogic_raw_event_hook *curr; + + if (!p->event_hooks) + return false; + + list_for_each_entry(curr, &p->event_hooks->list, list) { + if (curr->size == size && memcmp(curr->event, event, size) == 0) { + schedule_work(&curr->work); + return true; + } + } + + return false; +} + +/** * uclogic_raw_event_pen - handle raw pen events (pen HID reports). * * @drvdata: Driver data. @@ -425,6 +435,9 @@ static int uclogic_raw_event(struct hid_device *hdev, if (report->type != HID_INPUT_REPORT) return 0; + if (uclogic_exec_event_hook(params, data, size)) + return 0; + while (true) { /* Tweak pen reports, if necessary */ if ((report_id == params->pen.id) && (size >= 2)) { @@ -530,8 +543,14 @@ static const struct hid_device_id uclogic_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L) }, { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, + USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_MW), + .driver_data = UCLOGIC_MOUSE_FRAME_QUIRK | UCLOGIC_BATTERY_QUIRK }, + { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_S) }, { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, + USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_SW), + .driver_data = UCLOGIC_MOUSE_FRAME_QUIRK | UCLOGIC_BATTERY_QUIRK }, + { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06) }, { } }; @@ -556,3 +575,7 @@ module_hid_driver(uclogic_driver); MODULE_AUTHOR("Martin Rusko"); MODULE_AUTHOR("Nikolai Kondrashov"); MODULE_LICENSE("GPL"); + +#ifdef CONFIG_HID_KUNIT_TEST +#include "hid-uclogic-core-test.c" +#endif |