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:
Linus Torvalds 2010-05-10 09:44:53 -07:00
Родитель b57f95a382 fde4e2f732
Коммит b77b907fae
7 изменённых файлов: 46 добавлений и 54 удалений

Просмотреть файл

@ -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)