Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: HID: fix suspend crash by moving initializations earlier HID: sony: fix sony_set_operational_bt HID: ntrig: Remove unused macro, TripleTap and QuadTap HID: ntrig: TipSwitch for single touch mode touch. HID: hidraw: fix numbered reports HID: wacom: remove annoying non-error printk HID: ntrig: Emit TOUCH with DOUBLETAP for single touch HID: add support for cymotion master solar keyboard HID: ntrig: explain firmware quirk HID: fix N-trig touch panel with recent firmware
This commit is contained in:
Коммит
b77b907fae
|
@ -59,6 +59,7 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||||
|
|
||||||
static const struct hid_device_id ch_devices[] = {
|
static const struct hid_device_id ch_devices[] = {
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(hid, ch_devices);
|
MODULE_DEVICE_TABLE(hid, ch_devices);
|
||||||
|
|
|
@ -1043,13 +1043,8 @@ void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
|
||||||
|
|
||||||
if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
|
if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
|
||||||
hid->hiddev_report_event(hid, report);
|
hid->hiddev_report_event(hid, report);
|
||||||
if (hid->claimed & HID_CLAIMED_HIDRAW) {
|
if (hid->claimed & HID_CLAIMED_HIDRAW)
|
||||||
/* numbered reports need to be passed with the report num */
|
hidraw_report_event(hid, data, size);
|
||||||
if (report_enum->numbered)
|
|
||||||
hidraw_report_event(hid, data - 1, size + 1);
|
|
||||||
else
|
|
||||||
hidraw_report_event(hid, data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (a = 0; a < report->maxfield; a++)
|
for (a = 0; a < report->maxfield; a++)
|
||||||
hid_input_field(hid, report->field[a], cdata, interrupt);
|
hid_input_field(hid, report->field[a], cdata, interrupt);
|
||||||
|
@ -1296,6 +1291,7 @@ static const struct hid_device_id hid_blacklist[] = {
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
|
||||||
|
|
|
@ -131,6 +131,7 @@
|
||||||
|
|
||||||
#define USB_VENDOR_ID_CHERRY 0x046a
|
#define USB_VENDOR_ID_CHERRY 0x046a
|
||||||
#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
|
#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
|
||||||
|
#define USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR 0x0027
|
||||||
|
|
||||||
#define USB_VENDOR_ID_CHIC 0x05fe
|
#define USB_VENDOR_ID_CHIC 0x05fe
|
||||||
#define USB_DEVICE_ID_CHIC_GAMEPAD 0x0014
|
#define USB_DEVICE_ID_CHIC_GAMEPAD 0x0014
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* HID driver for N-Trig touchscreens
|
* HID driver for N-Trig touchscreens
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008 Rafi Rubin
|
* Copyright (c) 2008-2010 Rafi Rubin
|
||||||
* Copyright (c) 2009 Stephane Chatty
|
* Copyright (c) 2009-2010 Stephane Chatty
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/hid.h>
|
#include <linux/hid.h>
|
||||||
|
#include <linux/usb.h>
|
||||||
|
#include "usbhid/usbhid.h"
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
@ -22,17 +24,16 @@
|
||||||
|
|
||||||
#define NTRIG_DUPLICATE_USAGES 0x001
|
#define NTRIG_DUPLICATE_USAGES 0x001
|
||||||
|
|
||||||
#define nt_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
|
|
||||||
EV_KEY, (c))
|
|
||||||
|
|
||||||
struct ntrig_data {
|
struct ntrig_data {
|
||||||
/* Incoming raw values for a single contact */
|
/* Incoming raw values for a single contact */
|
||||||
__u16 x, y, w, h;
|
__u16 x, y, w, h;
|
||||||
__u16 id;
|
__u16 id;
|
||||||
__u8 confidence;
|
|
||||||
|
bool tipswitch;
|
||||||
|
bool confidence;
|
||||||
|
bool first_contact_touch;
|
||||||
|
|
||||||
bool reading_mt;
|
bool reading_mt;
|
||||||
__u8 first_contact_confidence;
|
|
||||||
|
|
||||||
__u8 mt_footer[4];
|
__u8 mt_footer[4];
|
||||||
__u8 mt_foot_count;
|
__u8 mt_foot_count;
|
||||||
|
@ -139,9 +140,10 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
|
||||||
case 0xff000001:
|
case 0xff000001:
|
||||||
/* Tag indicating the start of a multitouch group */
|
/* Tag indicating the start of a multitouch group */
|
||||||
nd->reading_mt = 1;
|
nd->reading_mt = 1;
|
||||||
nd->first_contact_confidence = 0;
|
nd->first_contact_touch = 0;
|
||||||
break;
|
break;
|
||||||
case HID_DG_TIPSWITCH:
|
case HID_DG_TIPSWITCH:
|
||||||
|
nd->tipswitch = value;
|
||||||
/* Prevent emission of touch until validated */
|
/* Prevent emission of touch until validated */
|
||||||
return 1;
|
return 1;
|
||||||
case HID_DG_CONFIDENCE:
|
case HID_DG_CONFIDENCE:
|
||||||
|
@ -169,8 +171,14 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
|
||||||
* to emit a normal (X, Y) position
|
* to emit a normal (X, Y) position
|
||||||
*/
|
*/
|
||||||
if (!nd->reading_mt) {
|
if (!nd->reading_mt) {
|
||||||
|
/*
|
||||||
|
* TipSwitch indicates the presence of a
|
||||||
|
* finger in single touch mode.
|
||||||
|
*/
|
||||||
|
input_report_key(input, BTN_TOUCH,
|
||||||
|
nd->tipswitch);
|
||||||
input_report_key(input, BTN_TOOL_DOUBLETAP,
|
input_report_key(input, BTN_TOOL_DOUBLETAP,
|
||||||
(nd->confidence != 0));
|
nd->tipswitch);
|
||||||
input_event(input, EV_ABS, ABS_X, nd->x);
|
input_event(input, EV_ABS, ABS_X, nd->x);
|
||||||
input_event(input, EV_ABS, ABS_Y, nd->y);
|
input_event(input, EV_ABS, ABS_Y, nd->y);
|
||||||
}
|
}
|
||||||
|
@ -209,7 +217,13 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
|
||||||
|
|
||||||
/* emit a normal (X, Y) for the first point only */
|
/* emit a normal (X, Y) for the first point only */
|
||||||
if (nd->id == 0) {
|
if (nd->id == 0) {
|
||||||
nd->first_contact_confidence = nd->confidence;
|
/*
|
||||||
|
* TipSwitch is superfluous in multitouch
|
||||||
|
* mode. The footer events tell us
|
||||||
|
* if there is a finger on the screen or
|
||||||
|
* not.
|
||||||
|
*/
|
||||||
|
nd->first_contact_touch = nd->confidence;
|
||||||
input_event(input, EV_ABS, ABS_X, nd->x);
|
input_event(input, EV_ABS, ABS_X, nd->x);
|
||||||
input_event(input, EV_ABS, ABS_Y, nd->y);
|
input_event(input, EV_ABS, ABS_Y, nd->y);
|
||||||
}
|
}
|
||||||
|
@ -239,30 +253,11 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
|
||||||
|
|
||||||
nd->reading_mt = 0;
|
nd->reading_mt = 0;
|
||||||
|
|
||||||
if (nd->first_contact_confidence) {
|
if (nd->first_contact_touch) {
|
||||||
switch (value) {
|
input_report_key(input, BTN_TOOL_DOUBLETAP, 1);
|
||||||
case 0: /* for single touch devices */
|
|
||||||
case 1:
|
|
||||||
input_report_key(input,
|
|
||||||
BTN_TOOL_DOUBLETAP, 1);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
input_report_key(input,
|
|
||||||
BTN_TOOL_TRIPLETAP, 1);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
default:
|
|
||||||
input_report_key(input,
|
|
||||||
BTN_TOOL_QUADTAP, 1);
|
|
||||||
}
|
|
||||||
input_report_key(input, BTN_TOUCH, 1);
|
input_report_key(input, BTN_TOUCH, 1);
|
||||||
} else {
|
} else {
|
||||||
input_report_key(input,
|
input_report_key(input, BTN_TOOL_DOUBLETAP, 0);
|
||||||
BTN_TOOL_DOUBLETAP, 0);
|
|
||||||
input_report_key(input,
|
|
||||||
BTN_TOOL_TRIPLETAP, 0);
|
|
||||||
input_report_key(input,
|
|
||||||
BTN_TOOL_QUADTAP, 0);
|
|
||||||
input_report_key(input, BTN_TOUCH, 0);
|
input_report_key(input, BTN_TOUCH, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -286,6 +281,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||||
struct ntrig_data *nd;
|
struct ntrig_data *nd;
|
||||||
struct hid_input *hidinput;
|
struct hid_input *hidinput;
|
||||||
struct input_dev *input;
|
struct input_dev *input;
|
||||||
|
struct hid_report *report;
|
||||||
|
|
||||||
if (id->driver_data)
|
if (id->driver_data)
|
||||||
hdev->quirks |= HID_QUIRK_MULTI_INPUT;
|
hdev->quirks |= HID_QUIRK_MULTI_INPUT;
|
||||||
|
@ -327,13 +323,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||||
__clear_bit(BTN_TOOL_PEN, input->keybit);
|
__clear_bit(BTN_TOOL_PEN, input->keybit);
|
||||||
__clear_bit(BTN_TOOL_FINGER, input->keybit);
|
__clear_bit(BTN_TOOL_FINGER, input->keybit);
|
||||||
__clear_bit(BTN_0, input->keybit);
|
__clear_bit(BTN_0, input->keybit);
|
||||||
/*
|
|
||||||
* A little something special to enable
|
|
||||||
* two and three finger taps.
|
|
||||||
*/
|
|
||||||
__set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
|
__set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
|
||||||
__set_bit(BTN_TOOL_TRIPLETAP, input->keybit);
|
|
||||||
__set_bit(BTN_TOOL_QUADTAP, input->keybit);
|
|
||||||
/*
|
/*
|
||||||
* The physical touchscreen (single touch)
|
* The physical touchscreen (single touch)
|
||||||
* input has a value for physical, whereas
|
* input has a value for physical, whereas
|
||||||
|
@ -349,6 +339,12 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is needed for devices with more recent firmware versions */
|
||||||
|
report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a];
|
||||||
|
if (report)
|
||||||
|
usbhid_submit_report(hdev, report, USB_DIR_OUT);
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
err_free:
|
err_free:
|
||||||
kfree(nd);
|
kfree(nd);
|
||||||
|
|
|
@ -76,7 +76,7 @@ static int sony_set_operational_usb(struct hid_device *hdev)
|
||||||
|
|
||||||
static int sony_set_operational_bt(struct hid_device *hdev)
|
static int sony_set_operational_bt(struct hid_device *hdev)
|
||||||
{
|
{
|
||||||
unsigned char buf[] = { 0x53, 0xf4, 0x42, 0x03, 0x00, 0x00 };
|
unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 };
|
||||||
return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
|
return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -277,7 +277,6 @@ static int __init wacom_init(void)
|
||||||
ret = hid_register_driver(&wacom_driver);
|
ret = hid_register_driver(&wacom_driver);
|
||||||
if (ret)
|
if (ret)
|
||||||
printk(KERN_ERR "can't register wacom driver\n");
|
printk(KERN_ERR "can't register wacom driver\n");
|
||||||
printk(KERN_ERR "wacom driver registered\n");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -999,13 +999,6 @@ static int usbhid_start(struct hid_device *hid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init_waitqueue_head(&usbhid->wait);
|
|
||||||
INIT_WORK(&usbhid->reset_work, hid_reset);
|
|
||||||
INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
|
|
||||||
setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
|
|
||||||
|
|
||||||
spin_lock_init(&usbhid->lock);
|
|
||||||
|
|
||||||
usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
|
usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
|
||||||
if (!usbhid->urbctrl) {
|
if (!usbhid->urbctrl) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
@ -1179,6 +1172,12 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
|
||||||
usbhid->intf = intf;
|
usbhid->intf = intf;
|
||||||
usbhid->ifnum = interface->desc.bInterfaceNumber;
|
usbhid->ifnum = interface->desc.bInterfaceNumber;
|
||||||
|
|
||||||
|
init_waitqueue_head(&usbhid->wait);
|
||||||
|
INIT_WORK(&usbhid->reset_work, hid_reset);
|
||||||
|
INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
|
||||||
|
setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
|
||||||
|
spin_lock_init(&usbhid->lock);
|
||||||
|
|
||||||
ret = hid_add_device(hid);
|
ret = hid_add_device(hid);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (ret != -ENODEV)
|
if (ret != -ENODEV)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче