mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID updates from Jiri Kosina: "Updates for HID code - improveements of Logitech HID++ procotol implementation, from Benjamin Tissoires - support for composite RMI devices, from Andrew Duggan - new driver for BETOP controller, from Huang Bo - fixup for conflicting mapping in HID core between PC-101/103/104 and PC-102/105 keyboards from David Herrmann - new hardware support and fixes in Wacom driver, from Ping Cheng - assorted small fixes and device ID additions all over the place" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (33 commits) HID: wacom: add support for Cintiq 27QHD and 27QHD touch HID: wacom: consolidate input capability settings for pen and touch HID: wacom: make sure touch arbitration is applied consistently HID: pidff: Fix initialisation forMicrosoft Sidewinder FF Pro 2 HID: hyperv: match wait_for_completion_timeout return type HID: wacom: Report ABS_MISC event for Cintiq Companion Hybrid HID: Use Kbuild idiom in Makefiles HID: do not bind to Microchip Pick16F1454 HID: hid-lg4ff: use DEVICE_ATTR_RW macro HID: hid-lg4ff: fix sysfs attribute permission HID: wacom: peport In Range event according to the spec HID: wacom: process invalid Cintiq and Intuos data in wacom_intuos_inout() HID: rmi: Add support for the touchpad in the Razer Blade 14 laptop HID: rmi: Support touchpads with external buttons HID: rmi: Use hid_report_len to compute the size of reports HID: logitech-hidpp: store the name of the device in struct hidpp HID: microsoft: add support for Japanese Surface Type Cover 3 HID: fixup the conflicting keyboard mappings quirk HID: apple: fix battery support for the 2009 ANSI wireless keyboard HID: fix Kconfig text ...
This commit is contained in:
commit
870fd0f5df
@ -147,6 +147,16 @@ config HID_BELKIN
|
|||||||
---help---
|
---help---
|
||||||
Support for Belkin Flip KVM and Wireless keyboard.
|
Support for Belkin Flip KVM and Wireless keyboard.
|
||||||
|
|
||||||
|
config HID_BETOP_FF
|
||||||
|
tristate "Betop Production Inc. force feedback support"
|
||||||
|
depends on USB_HID
|
||||||
|
select INPUT_FF_MEMLESS
|
||||||
|
---help---
|
||||||
|
Say Y here if you want to enable force feedback support for devices by
|
||||||
|
BETOP Production Ltd.
|
||||||
|
Currently the following devices are known to be supported:
|
||||||
|
- BETOP 2185 PC & BFM MODE
|
||||||
|
|
||||||
config HID_CHERRY
|
config HID_CHERRY
|
||||||
tristate "Cherry Cymotion keyboard" if EXPERT
|
tristate "Cherry Cymotion keyboard" if EXPERT
|
||||||
depends on HID
|
depends on HID
|
||||||
@ -389,7 +399,7 @@ config HID_LOGITECH_HIDPP
|
|||||||
Say Y if you want support for Logitech devices relying on the HID++
|
Say Y if you want support for Logitech devices relying on the HID++
|
||||||
specification. Such devices are the various Logitech Touchpads (T650,
|
specification. Such devices are the various Logitech Touchpads (T650,
|
||||||
T651, TK820), some mice (Zone Touch mouse), or even keyboards (Solar
|
T651, TK820), some mice (Zone Touch mouse), or even keyboards (Solar
|
||||||
Keayboard).
|
Keyboard).
|
||||||
|
|
||||||
config LOGITECH_FF
|
config LOGITECH_FF
|
||||||
bool "Logitech force feedback support"
|
bool "Logitech force feedback support"
|
||||||
|
@ -2,10 +2,7 @@
|
|||||||
# Makefile for the HID driver
|
# Makefile for the HID driver
|
||||||
#
|
#
|
||||||
hid-y := hid-core.o hid-input.o
|
hid-y := hid-core.o hid-input.o
|
||||||
|
hid-$(CONFIG_DEBUG_FS) += hid-debug.o
|
||||||
ifdef CONFIG_DEBUG_FS
|
|
||||||
hid-objs += hid-debug.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
obj-$(CONFIG_HID) += hid.o
|
obj-$(CONFIG_HID) += hid.o
|
||||||
obj-$(CONFIG_UHID) += uhid.o
|
obj-$(CONFIG_UHID) += uhid.o
|
||||||
@ -15,23 +12,13 @@ obj-$(CONFIG_HID_GENERIC) += hid-generic.o
|
|||||||
hid-$(CONFIG_HIDRAW) += hidraw.o
|
hid-$(CONFIG_HIDRAW) += hidraw.o
|
||||||
|
|
||||||
hid-logitech-y := hid-lg.o
|
hid-logitech-y := hid-lg.o
|
||||||
ifdef CONFIG_LOGITECH_FF
|
hid-logitech-$(CONFIG_LOGITECH_FF) += hid-lgff.o
|
||||||
hid-logitech-y += hid-lgff.o
|
hid-logitech-$(CONFIG_LOGIRUMBLEPAD2_FF) += hid-lg2ff.o
|
||||||
endif
|
hid-logitech-$(CONFIG_LOGIG940_FF) += hid-lg3ff.o
|
||||||
ifdef CONFIG_LOGIRUMBLEPAD2_FF
|
hid-logitech-$(CONFIG_LOGIWHEELS_FF) += hid-lg4ff.o
|
||||||
hid-logitech-y += hid-lg2ff.o
|
|
||||||
endif
|
|
||||||
ifdef CONFIG_LOGIG940_FF
|
|
||||||
hid-logitech-y += hid-lg3ff.o
|
|
||||||
endif
|
|
||||||
ifdef CONFIG_LOGIWHEELS_FF
|
|
||||||
hid-logitech-y += hid-lg4ff.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
hid-wiimote-y := hid-wiimote-core.o hid-wiimote-modules.o
|
hid-wiimote-y := hid-wiimote-core.o hid-wiimote-modules.o
|
||||||
ifdef CONFIG_DEBUG_FS
|
hid-wiimote-$(CONFIG_DEBUG_FS) += hid-wiimote-debug.o
|
||||||
hid-wiimote-y += hid-wiimote-debug.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o
|
obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o
|
||||||
obj-$(CONFIG_HID_ACRUX) += hid-axff.o
|
obj-$(CONFIG_HID_ACRUX) += hid-axff.o
|
||||||
@ -39,6 +26,7 @@ obj-$(CONFIG_HID_APPLE) += hid-apple.o
|
|||||||
obj-$(CONFIG_HID_APPLEIR) += hid-appleir.o
|
obj-$(CONFIG_HID_APPLEIR) += hid-appleir.o
|
||||||
obj-$(CONFIG_HID_AUREAL) += hid-aureal.o
|
obj-$(CONFIG_HID_AUREAL) += hid-aureal.o
|
||||||
obj-$(CONFIG_HID_BELKIN) += hid-belkin.o
|
obj-$(CONFIG_HID_BELKIN) += hid-belkin.o
|
||||||
|
obj-$(CONFIG_HID_BETOP_FF) += hid-betopff.o
|
||||||
obj-$(CONFIG_HID_CHERRY) += hid-cherry.o
|
obj-$(CONFIG_HID_CHERRY) += hid-cherry.o
|
||||||
obj-$(CONFIG_HID_CHICONY) += hid-chicony.o
|
obj-$(CONFIG_HID_CHICONY) += hid-chicony.o
|
||||||
obj-$(CONFIG_HID_CP2112) += hid-cp2112.o
|
obj-$(CONFIG_HID_CP2112) += hid-cp2112.o
|
||||||
@ -76,24 +64,12 @@ obj-$(CONFIG_HID_PENMOUNT) += hid-penmount.o
|
|||||||
obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
|
obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
|
||||||
obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o
|
obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o
|
||||||
hid-picolcd-y += hid-picolcd_core.o
|
hid-picolcd-y += hid-picolcd_core.o
|
||||||
ifdef CONFIG_HID_PICOLCD_FB
|
hid-picolcd-$(CONFIG_HID_PICOLCD_FB) += hid-picolcd_fb.o
|
||||||
hid-picolcd-y += hid-picolcd_fb.o
|
hid-picolcd-$(CONFIG_HID_PICOLCD_BACKLIGHT) += hid-picolcd_backlight.o
|
||||||
endif
|
hid-picolcd-$(CONFIG_HID_PICOLCD_LCD) += hid-picolcd_lcd.o
|
||||||
ifdef CONFIG_HID_PICOLCD_BACKLIGHT
|
hid-picolcd-$(CONFIG_HID_PICOLCD_LEDS) += hid-picolcd_leds.o
|
||||||
hid-picolcd-y += hid-picolcd_backlight.o
|
hid-picolcd-$(CONFIG_HID_PICOLCD_CIR) += hid-picolcd_cir.o
|
||||||
endif
|
hid-picolcd-$(CONFIG_DEBUG_FS) += hid-picolcd_debugfs.o
|
||||||
ifdef CONFIG_HID_PICOLCD_LCD
|
|
||||||
hid-picolcd-y += hid-picolcd_lcd.o
|
|
||||||
endif
|
|
||||||
ifdef CONFIG_HID_PICOLCD_LEDS
|
|
||||||
hid-picolcd-y += hid-picolcd_leds.o
|
|
||||||
endif
|
|
||||||
ifdef CONFIG_HID_PICOLCD_CIR
|
|
||||||
hid-picolcd-y += hid-picolcd_cir.o
|
|
||||||
endif
|
|
||||||
ifdef CONFIG_DEBUG_FS
|
|
||||||
hid-picolcd-y += hid-picolcd_debugfs.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
obj-$(CONFIG_HID_PLANTRONICS) += hid-plantronics.o
|
obj-$(CONFIG_HID_PLANTRONICS) += hid-plantronics.o
|
||||||
obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
|
obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
|
||||||
|
160
drivers/hid/hid-betopff.c
Normal file
160
drivers/hid/hid-betopff.c
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
/*
|
||||||
|
* Force feedback support for Betop based devices
|
||||||
|
*
|
||||||
|
* The devices are distributed under various names and the same USB device ID
|
||||||
|
* can be used in both adapters and actual game controllers.
|
||||||
|
*
|
||||||
|
* 0x11c2:0x2208 "BTP2185 BFM mode Joystick"
|
||||||
|
* - tested with BTP2185 BFM Mode.
|
||||||
|
*
|
||||||
|
* 0x11C0:0x5506 "BTP2185 PC mode Joystick"
|
||||||
|
* - tested with BTP2185 PC Mode.
|
||||||
|
*
|
||||||
|
* 0x8380:0x1850 "BTP2185 V2 PC mode USB Gamepad"
|
||||||
|
* - tested with BTP2185 PC Mode with another version.
|
||||||
|
*
|
||||||
|
* 0x20bc:0x5500 "BTP2185 V2 BFM mode Joystick"
|
||||||
|
* - tested with BTP2171s.
|
||||||
|
* Copyright (c) 2014 Huang Bo <huangbobupt@163.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
|
* Software Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/hid.h>
|
||||||
|
|
||||||
|
#include "hid-ids.h"
|
||||||
|
|
||||||
|
struct betopff_device {
|
||||||
|
struct hid_report *report;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int hid_betopff_play(struct input_dev *dev, void *data,
|
||||||
|
struct ff_effect *effect)
|
||||||
|
{
|
||||||
|
struct hid_device *hid = input_get_drvdata(dev);
|
||||||
|
struct betopff_device *betopff = data;
|
||||||
|
__u16 left, right;
|
||||||
|
|
||||||
|
left = effect->u.rumble.strong_magnitude;
|
||||||
|
right = effect->u.rumble.weak_magnitude;
|
||||||
|
|
||||||
|
betopff->report->field[2]->value[0] = left / 256;
|
||||||
|
betopff->report->field[3]->value[0] = right / 256;
|
||||||
|
|
||||||
|
hid_hw_request(hid, betopff->report, HID_REQ_SET_REPORT);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int betopff_init(struct hid_device *hid)
|
||||||
|
{
|
||||||
|
struct betopff_device *betopff;
|
||||||
|
struct hid_report *report;
|
||||||
|
struct hid_input *hidinput =
|
||||||
|
list_first_entry(&hid->inputs, struct hid_input, list);
|
||||||
|
struct list_head *report_list =
|
||||||
|
&hid->report_enum[HID_OUTPUT_REPORT].report_list;
|
||||||
|
struct input_dev *dev = hidinput->input;
|
||||||
|
int field_count = 0;
|
||||||
|
int error;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
if (list_empty(report_list)) {
|
||||||
|
hid_err(hid, "no output reports found\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
report = list_first_entry(report_list, struct hid_report, list);
|
||||||
|
/*
|
||||||
|
* Actually there are 4 fields for 4 Bytes as below:
|
||||||
|
* -----------------------------------------
|
||||||
|
* Byte0 Byte1 Byte2 Byte3
|
||||||
|
* 0x00 0x00 left_motor right_motor
|
||||||
|
* -----------------------------------------
|
||||||
|
* Do init them with default value.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < report->maxfield; i++) {
|
||||||
|
for (j = 0; j < report->field[i]->report_count; j++) {
|
||||||
|
report->field[i]->value[j] = 0x00;
|
||||||
|
field_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field_count < 4) {
|
||||||
|
hid_err(hid, "not enough fields in the report: %d\n",
|
||||||
|
field_count);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
betopff = kzalloc(sizeof(*betopff), GFP_KERNEL);
|
||||||
|
if (!betopff)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
set_bit(FF_RUMBLE, dev->ffbit);
|
||||||
|
|
||||||
|
error = input_ff_create_memless(dev, betopff, hid_betopff_play);
|
||||||
|
if (error) {
|
||||||
|
kfree(betopff);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
betopff->report = report;
|
||||||
|
hid_hw_request(hid, betopff->report, HID_REQ_SET_REPORT);
|
||||||
|
|
||||||
|
hid_info(hid, "Force feedback for betop devices by huangbo <huangbobupt@163.com>\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int betop_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (id->driver_data)
|
||||||
|
hdev->quirks |= HID_QUIRK_MULTI_INPUT;
|
||||||
|
|
||||||
|
ret = hid_parse(hdev);
|
||||||
|
if (ret) {
|
||||||
|
hid_err(hdev, "parse failed\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
|
||||||
|
if (ret) {
|
||||||
|
hid_err(hdev, "hw start failed\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
betopff_init(hdev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
err:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct hid_device_id betop_devices[] = {
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185BFM, 0x2208) },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185PC, 0x5506) },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185V2PC, 0x1850) },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185V2BFM, 0x5500) },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(hid, betop_devices);
|
||||||
|
|
||||||
|
static struct hid_driver betop_driver = {
|
||||||
|
.name = "betop",
|
||||||
|
.id_table = betop_devices,
|
||||||
|
.probe = betop_probe,
|
||||||
|
};
|
||||||
|
module_hid_driver(betop_driver);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
@ -698,15 +698,25 @@ static void hid_scan_feature_usage(struct hid_parser *parser, u32 usage)
|
|||||||
static void hid_scan_collection(struct hid_parser *parser, unsigned type)
|
static void hid_scan_collection(struct hid_parser *parser, unsigned type)
|
||||||
{
|
{
|
||||||
struct hid_device *hid = parser->device;
|
struct hid_device *hid = parser->device;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (((parser->global.usage_page << 16) == HID_UP_SENSOR) &&
|
if (((parser->global.usage_page << 16) == HID_UP_SENSOR) &&
|
||||||
type == HID_COLLECTION_PHYSICAL)
|
type == HID_COLLECTION_PHYSICAL)
|
||||||
hid->group = HID_GROUP_SENSOR_HUB;
|
hid->group = HID_GROUP_SENSOR_HUB;
|
||||||
|
|
||||||
if (hid->vendor == USB_VENDOR_ID_MICROSOFT &&
|
if (hid->vendor == USB_VENDOR_ID_MICROSOFT &&
|
||||||
hid->product == USB_DEVICE_ID_MS_TYPE_COVER_3 &&
|
(hid->product == USB_DEVICE_ID_MS_TYPE_COVER_3 ||
|
||||||
|
hid->product == USB_DEVICE_ID_MS_TYPE_COVER_3_JP) &&
|
||||||
hid->group == HID_GROUP_MULTITOUCH)
|
hid->group == HID_GROUP_MULTITOUCH)
|
||||||
hid->group = HID_GROUP_GENERIC;
|
hid->group = HID_GROUP_GENERIC;
|
||||||
|
|
||||||
|
if ((parser->global.usage_page << 16) == HID_UP_GENDESK)
|
||||||
|
for (i = 0; i < parser->local.usage_index; i++)
|
||||||
|
if (parser->local.usage[i] == HID_GD_POINTER)
|
||||||
|
parser->scan_flags |= HID_SCAN_FLAG_GD_POINTER;
|
||||||
|
|
||||||
|
if ((parser->global.usage_page << 16) >= HID_UP_MSVENDOR)
|
||||||
|
parser->scan_flags |= HID_SCAN_FLAG_VENDOR_SPECIFIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hid_scan_main(struct hid_parser *parser, struct hid_item *item)
|
static int hid_scan_main(struct hid_parser *parser, struct hid_item *item)
|
||||||
@ -792,11 +802,14 @@ static int hid_scan_report(struct hid_device *hid)
|
|||||||
hid->group = HID_GROUP_WACOM;
|
hid->group = HID_GROUP_WACOM;
|
||||||
break;
|
break;
|
||||||
case USB_VENDOR_ID_SYNAPTICS:
|
case USB_VENDOR_ID_SYNAPTICS:
|
||||||
if ((hid->group == HID_GROUP_GENERIC) &&
|
if (hid->group == HID_GROUP_GENERIC)
|
||||||
(hid->bus != BUS_USB || hid->type == HID_TYPE_USBMOUSE))
|
if ((parser->scan_flags & HID_SCAN_FLAG_VENDOR_SPECIFIC)
|
||||||
/* hid-rmi should only bind to the mouse interface of
|
&& (parser->scan_flags & HID_SCAN_FLAG_GD_POINTER))
|
||||||
* composite USB devices */
|
/*
|
||||||
hid->group = HID_GROUP_RMI;
|
* hid-rmi should take care of them,
|
||||||
|
* not hid-generic
|
||||||
|
*/
|
||||||
|
hid->group = HID_GROUP_RMI;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1757,6 +1770,10 @@ static const struct hid_device_id hid_have_special_driver[] = {
|
|||||||
{ 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_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) },
|
||||||
{ 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_BETOP_2185BFM, 0x2208) },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185PC, 0x5506) },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185V2PC, 0x1850) },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185V2BFM, 0x5500) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
|
||||||
@ -1861,6 +1878,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
|
|||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3) },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3_JP) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
|
||||||
@ -1971,6 +1989,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
|
|||||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
|
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
|
||||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) },
|
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) },
|
||||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE2) },
|
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE2) },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER, USB_DEVICE_ID_RAZER_BLADE_14) },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2328,6 +2347,7 @@ static const struct hid_device_id hid_ignore_list[] = {
|
|||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT2) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT2) },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICK16F1454) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR, USB_DEVICE_ID_N_S_HARMONY) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR, USB_DEVICE_ID_N_S_HARMONY) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 20) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 20) },
|
||||||
|
@ -381,7 +381,7 @@ static void mousevsc_on_channel_callback(void *context)
|
|||||||
static int mousevsc_connect_to_vsp(struct hv_device *device)
|
static int mousevsc_connect_to_vsp(struct hv_device *device)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int t;
|
unsigned long t;
|
||||||
struct mousevsc_dev *input_dev = hv_get_drvdata(device);
|
struct mousevsc_dev *input_dev = hv_get_drvdata(device);
|
||||||
struct mousevsc_prt_msg *request;
|
struct mousevsc_prt_msg *request;
|
||||||
struct mousevsc_prt_msg *response;
|
struct mousevsc_prt_msg *response;
|
||||||
|
@ -189,6 +189,11 @@
|
|||||||
#define USB_VENDOR_ID_BERKSHIRE 0x0c98
|
#define USB_VENDOR_ID_BERKSHIRE 0x0c98
|
||||||
#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140
|
#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140
|
||||||
|
|
||||||
|
#define USB_VENDOR_ID_BETOP_2185BFM 0x11c2
|
||||||
|
#define USB_VENDOR_ID_BETOP_2185PC 0x11c0
|
||||||
|
#define USB_VENDOR_ID_BETOP_2185V2PC 0x8380
|
||||||
|
#define USB_VENDOR_ID_BETOP_2185V2BFM 0x20bc
|
||||||
|
|
||||||
#define USB_VENDOR_ID_BTC 0x046e
|
#define USB_VENDOR_ID_BTC 0x046e
|
||||||
#define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578
|
#define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578
|
||||||
#define USB_DEVICE_ID_BTC_EMPREX_REMOTE_2 0x5577
|
#define USB_DEVICE_ID_BTC_EMPREX_REMOTE_2 0x5577
|
||||||
@ -638,6 +643,7 @@
|
|||||||
#define USB_DEVICE_ID_PICKIT2 0x0033
|
#define USB_DEVICE_ID_PICKIT2 0x0033
|
||||||
#define USB_DEVICE_ID_PICOLCD 0xc002
|
#define USB_DEVICE_ID_PICOLCD 0xc002
|
||||||
#define USB_DEVICE_ID_PICOLCD_BOOTLOADER 0xf002
|
#define USB_DEVICE_ID_PICOLCD_BOOTLOADER 0xf002
|
||||||
|
#define USB_DEVICE_ID_PICK16F1454 0x0042
|
||||||
|
|
||||||
#define USB_VENDOR_ID_MICROSOFT 0x045e
|
#define USB_VENDOR_ID_MICROSOFT 0x045e
|
||||||
#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b
|
#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b
|
||||||
@ -654,6 +660,7 @@
|
|||||||
#define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7
|
#define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7
|
||||||
#define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9
|
#define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9
|
||||||
#define USB_DEVICE_ID_MS_TYPE_COVER_3 0x07dc
|
#define USB_DEVICE_ID_MS_TYPE_COVER_3 0x07dc
|
||||||
|
#define USB_DEVICE_ID_MS_TYPE_COVER_3_JP 0x07dd
|
||||||
|
|
||||||
#define USB_VENDOR_ID_MOJO 0x8282
|
#define USB_VENDOR_ID_MOJO 0x8282
|
||||||
#define USB_DEVICE_ID_RETRO_ADAPTER 0x3201
|
#define USB_DEVICE_ID_RETRO_ADAPTER 0x3201
|
||||||
@ -768,6 +775,9 @@
|
|||||||
#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001 0x3001
|
#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001 0x3001
|
||||||
#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008 0x3008
|
#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008 0x3008
|
||||||
|
|
||||||
|
#define USB_VENDOR_ID_RAZER 0x1532
|
||||||
|
#define USB_DEVICE_ID_RAZER_BLADE_14 0x011D
|
||||||
|
|
||||||
#define USB_VENDOR_ID_REALTEK 0x0bda
|
#define USB_VENDOR_ID_REALTEK 0x0bda
|
||||||
#define USB_DEVICE_ID_REALTEK_READER 0x0152
|
#define USB_DEVICE_ID_REALTEK_READER 0x0152
|
||||||
|
|
||||||
|
@ -306,10 +306,13 @@ static enum power_supply_property hidinput_battery_props[] = {
|
|||||||
|
|
||||||
static const struct hid_device_id hid_battery_quirks[] = {
|
static const struct hid_device_id hid_battery_quirks[] = {
|
||||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
|
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
|
||||||
USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
|
USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
|
||||||
HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
|
HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
|
||||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
|
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
|
||||||
USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
|
USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
|
||||||
|
HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
|
||||||
|
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
|
||||||
|
USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
|
||||||
HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
|
HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
|
||||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
|
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
|
||||||
USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
|
USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
|
||||||
@ -1104,6 +1107,23 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ignore reports for absolute data if the data didn't change. This is
|
||||||
|
* not only an optimization but also fixes 'dead' key reports. Some
|
||||||
|
* RollOver implementations for localized keys (like BACKSLASH/PIPE; HID
|
||||||
|
* 0x31 and 0x32) report multiple keys, even though a localized keyboard
|
||||||
|
* can only have one of them physically available. The 'dead' keys
|
||||||
|
* report constant 0. As all map to the same keycode, they'd confuse
|
||||||
|
* the input layer. If we filter the 'dead' keys on the HID level, we
|
||||||
|
* skip the keycode translation and only forward real events.
|
||||||
|
*/
|
||||||
|
if (!(field->flags & (HID_MAIN_ITEM_RELATIVE |
|
||||||
|
HID_MAIN_ITEM_BUFFERED_BYTE)) &&
|
||||||
|
(field->flags & HID_MAIN_ITEM_VARIABLE) &&
|
||||||
|
usage->usage_index < field->maxusage &&
|
||||||
|
value == field->value[usage->usage_index])
|
||||||
|
return;
|
||||||
|
|
||||||
/* report the usage code as scancode if the key status has changed */
|
/* report the usage code as scancode if the key status has changed */
|
||||||
if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value)
|
if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value)
|
||||||
input_event(input, EV_MSC, MSC_SCAN, usage->hid);
|
input_event(input, EV_MSC, MSC_SCAN, usage->hid);
|
||||||
|
@ -38,6 +38,7 @@ struct lenovo_drvdata_tpkbd {
|
|||||||
|
|
||||||
struct lenovo_drvdata_cptkbd {
|
struct lenovo_drvdata_cptkbd {
|
||||||
bool fn_lock;
|
bool fn_lock;
|
||||||
|
int sensitivity;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
|
#define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
|
||||||
@ -91,6 +92,38 @@ static int lenovo_input_mapping_cptkbd(struct hid_device *hdev,
|
|||||||
case 0x00fa: /* Fn-Esc: Fn-lock toggle */
|
case 0x00fa: /* Fn-Esc: Fn-lock toggle */
|
||||||
map_key_clear(KEY_FN_ESC);
|
map_key_clear(KEY_FN_ESC);
|
||||||
return 1;
|
return 1;
|
||||||
|
case 0x00fb: /* Middle mouse button (in native mode) */
|
||||||
|
map_key_clear(BTN_MIDDLE);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compatibility middle/wheel mappings should be ignored */
|
||||||
|
if (usage->hid == HID_GD_WHEEL)
|
||||||
|
return -1;
|
||||||
|
if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON &&
|
||||||
|
(usage->hid & HID_USAGE) == 0x003)
|
||||||
|
return -1;
|
||||||
|
if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER &&
|
||||||
|
(usage->hid & HID_USAGE) == 0x238)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Map wheel emulation reports: 0xffa1 = USB, 0xff10 = BT */
|
||||||
|
if ((usage->hid & HID_USAGE_PAGE) == 0xff100000 ||
|
||||||
|
(usage->hid & HID_USAGE_PAGE) == 0xffa10000) {
|
||||||
|
field->flags |= HID_MAIN_ITEM_RELATIVE | HID_MAIN_ITEM_VARIABLE;
|
||||||
|
field->logical_minimum = -127;
|
||||||
|
field->logical_maximum = 127;
|
||||||
|
|
||||||
|
switch (usage->hid & HID_USAGE) {
|
||||||
|
case 0x0000:
|
||||||
|
hid_map_usage(hi, usage, bit, max, EV_REL, 0x06);
|
||||||
|
return 1;
|
||||||
|
case 0x0001:
|
||||||
|
hid_map_usage(hi, usage, bit, max, EV_REL, 0x08);
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,6 +178,7 @@ static void lenovo_features_set_cptkbd(struct hid_device *hdev)
|
|||||||
struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
|
struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
|
||||||
|
|
||||||
ret = lenovo_send_cmd_cptkbd(hdev, 0x05, cptkbd_data->fn_lock);
|
ret = lenovo_send_cmd_cptkbd(hdev, 0x05, cptkbd_data->fn_lock);
|
||||||
|
ret = lenovo_send_cmd_cptkbd(hdev, 0x02, cptkbd_data->sensitivity);
|
||||||
if (ret)
|
if (ret)
|
||||||
hid_err(hdev, "Fn-lock setting failed: %d\n", ret);
|
hid_err(hdev, "Fn-lock setting failed: %d\n", ret);
|
||||||
}
|
}
|
||||||
@ -179,13 +213,50 @@ static ssize_t attr_fn_lock_store_cptkbd(struct device *dev,
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t attr_sensitivity_show_cptkbd(struct device *dev,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
struct hid_device *hdev = container_of(dev, struct hid_device, dev);
|
||||||
|
struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
|
||||||
|
|
||||||
|
return snprintf(buf, PAGE_SIZE, "%u\n",
|
||||||
|
cptkbd_data->sensitivity);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t attr_sensitivity_store_cptkbd(struct device *dev,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
const char *buf,
|
||||||
|
size_t count)
|
||||||
|
{
|
||||||
|
struct hid_device *hdev = container_of(dev, struct hid_device, dev);
|
||||||
|
struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
|
||||||
|
int value;
|
||||||
|
|
||||||
|
if (kstrtoint(buf, 10, &value) || value < 1 || value > 255)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
cptkbd_data->sensitivity = value;
|
||||||
|
lenovo_features_set_cptkbd(hdev);
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct device_attribute dev_attr_fn_lock_cptkbd =
|
static struct device_attribute dev_attr_fn_lock_cptkbd =
|
||||||
__ATTR(fn_lock, S_IWUSR | S_IRUGO,
|
__ATTR(fn_lock, S_IWUSR | S_IRUGO,
|
||||||
attr_fn_lock_show_cptkbd,
|
attr_fn_lock_show_cptkbd,
|
||||||
attr_fn_lock_store_cptkbd);
|
attr_fn_lock_store_cptkbd);
|
||||||
|
|
||||||
|
static struct device_attribute dev_attr_sensitivity_cptkbd =
|
||||||
|
__ATTR(sensitivity, S_IWUSR | S_IRUGO,
|
||||||
|
attr_sensitivity_show_cptkbd,
|
||||||
|
attr_sensitivity_store_cptkbd);
|
||||||
|
|
||||||
|
|
||||||
static struct attribute *lenovo_attributes_cptkbd[] = {
|
static struct attribute *lenovo_attributes_cptkbd[] = {
|
||||||
&dev_attr_fn_lock_cptkbd.attr,
|
&dev_attr_fn_lock_cptkbd.attr,
|
||||||
|
&dev_attr_sensitivity_cptkbd.attr,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -594,8 +665,14 @@ static int lenovo_probe_cptkbd(struct hid_device *hdev)
|
|||||||
if (ret)
|
if (ret)
|
||||||
hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret);
|
hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret);
|
||||||
|
|
||||||
/* Turn Fn-Lock on by default */
|
/* Switch middle button to native mode */
|
||||||
|
ret = lenovo_send_cmd_cptkbd(hdev, 0x09, 0x01);
|
||||||
|
if (ret)
|
||||||
|
hid_warn(hdev, "Failed to switch middle button: %d\n", ret);
|
||||||
|
|
||||||
|
/* Set keyboard settings to known state */
|
||||||
cptkbd_data->fn_lock = true;
|
cptkbd_data->fn_lock = true;
|
||||||
|
cptkbd_data->sensitivity = 0x05;
|
||||||
lenovo_features_set_cptkbd(hdev);
|
lenovo_features_set_cptkbd(hdev);
|
||||||
|
|
||||||
ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd);
|
ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd);
|
||||||
|
@ -49,10 +49,6 @@
|
|||||||
|
|
||||||
static void hid_lg4ff_set_range_dfp(struct hid_device *hid, u16 range);
|
static void hid_lg4ff_set_range_dfp(struct hid_device *hid, u16 range);
|
||||||
static void hid_lg4ff_set_range_g25(struct hid_device *hid, u16 range);
|
static void hid_lg4ff_set_range_g25(struct hid_device *hid, u16 range);
|
||||||
static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *attr, char *buf);
|
|
||||||
static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
|
|
||||||
|
|
||||||
static DEVICE_ATTR(range, S_IRWXU | S_IRWXG | S_IROTH, lg4ff_range_show, lg4ff_range_store);
|
|
||||||
|
|
||||||
struct lg4ff_device_entry {
|
struct lg4ff_device_entry {
|
||||||
__u32 product_id;
|
__u32 product_id;
|
||||||
@ -416,7 +412,8 @@ static void hid_lg4ff_switch_native(struct hid_device *hid, const struct lg4ff_n
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Read current range and display it in terminal */
|
/* Read current range and display it in terminal */
|
||||||
static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *attr, char *buf)
|
static ssize_t range_show(struct device *dev, struct device_attribute *attr,
|
||||||
|
char *buf)
|
||||||
{
|
{
|
||||||
struct hid_device *hid = to_hid_device(dev);
|
struct hid_device *hid = to_hid_device(dev);
|
||||||
struct lg4ff_device_entry *entry;
|
struct lg4ff_device_entry *entry;
|
||||||
@ -441,7 +438,8 @@ static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *att
|
|||||||
|
|
||||||
/* Set range to user specified value, call appropriate function
|
/* Set range to user specified value, call appropriate function
|
||||||
* according to the type of the wheel */
|
* according to the type of the wheel */
|
||||||
static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
|
static ssize_t range_store(struct device *dev, struct device_attribute *attr,
|
||||||
|
const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
struct hid_device *hid = to_hid_device(dev);
|
struct hid_device *hid = to_hid_device(dev);
|
||||||
struct lg4ff_device_entry *entry;
|
struct lg4ff_device_entry *entry;
|
||||||
@ -472,6 +470,7 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at
|
|||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
static DEVICE_ATTR_RW(range);
|
||||||
|
|
||||||
#ifdef CONFIG_LEDS_CLASS
|
#ifdef CONFIG_LEDS_CLASS
|
||||||
static void lg4ff_set_leds(struct hid_device *hid, __u8 leds)
|
static void lg4ff_set_leds(struct hid_device *hid, __u8 leds)
|
||||||
|
@ -89,6 +89,7 @@ struct hidpp_device {
|
|||||||
struct hid_device *hid_dev;
|
struct hid_device *hid_dev;
|
||||||
struct mutex send_mutex;
|
struct mutex send_mutex;
|
||||||
void *send_receive_buf;
|
void *send_receive_buf;
|
||||||
|
char *name; /* will never be NULL and should not be freed */
|
||||||
wait_queue_head_t wait;
|
wait_queue_head_t wait;
|
||||||
bool answer_available;
|
bool answer_available;
|
||||||
u8 protocol_major;
|
u8 protocol_major;
|
||||||
@ -105,6 +106,7 @@ struct hidpp_device {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* HID++ 1.0 error codes */
|
||||||
#define HIDPP_ERROR 0x8f
|
#define HIDPP_ERROR 0x8f
|
||||||
#define HIDPP_ERROR_SUCCESS 0x00
|
#define HIDPP_ERROR_SUCCESS 0x00
|
||||||
#define HIDPP_ERROR_INVALID_SUBID 0x01
|
#define HIDPP_ERROR_INVALID_SUBID 0x01
|
||||||
@ -119,6 +121,8 @@ struct hidpp_device {
|
|||||||
#define HIDPP_ERROR_REQUEST_UNAVAILABLE 0x0a
|
#define HIDPP_ERROR_REQUEST_UNAVAILABLE 0x0a
|
||||||
#define HIDPP_ERROR_INVALID_PARAM_VALUE 0x0b
|
#define HIDPP_ERROR_INVALID_PARAM_VALUE 0x0b
|
||||||
#define HIDPP_ERROR_WRONG_PIN_CODE 0x0c
|
#define HIDPP_ERROR_WRONG_PIN_CODE 0x0c
|
||||||
|
/* HID++ 2.0 error codes */
|
||||||
|
#define HIDPP20_ERROR 0xff
|
||||||
|
|
||||||
static void hidpp_connect_event(struct hidpp_device *hidpp_dev);
|
static void hidpp_connect_event(struct hidpp_device *hidpp_dev);
|
||||||
|
|
||||||
@ -192,9 +196,16 @@ static int hidpp_send_message_sync(struct hidpp_device *hidpp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (response->report_id == REPORT_ID_HIDPP_SHORT &&
|
if (response->report_id == REPORT_ID_HIDPP_SHORT &&
|
||||||
response->fap.feature_index == HIDPP_ERROR) {
|
response->rap.sub_id == HIDPP_ERROR) {
|
||||||
|
ret = response->rap.params[1];
|
||||||
|
dbg_hid("%s:got hidpp error %02X\n", __func__, ret);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response->report_id == REPORT_ID_HIDPP_LONG &&
|
||||||
|
response->fap.feature_index == HIDPP20_ERROR) {
|
||||||
ret = response->fap.params[1];
|
ret = response->fap.params[1];
|
||||||
dbg_hid("__hidpp_send_report got hidpp error %02X\n", ret);
|
dbg_hid("%s:got hidpp 2.0 error %02X\n", __func__, ret);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,7 +282,8 @@ static inline bool hidpp_match_answer(struct hidpp_report *question,
|
|||||||
static inline bool hidpp_match_error(struct hidpp_report *question,
|
static inline bool hidpp_match_error(struct hidpp_report *question,
|
||||||
struct hidpp_report *answer)
|
struct hidpp_report *answer)
|
||||||
{
|
{
|
||||||
return (answer->fap.feature_index == HIDPP_ERROR) &&
|
return ((answer->rap.sub_id == HIDPP_ERROR) ||
|
||||||
|
(answer->fap.feature_index == HIDPP20_ERROR)) &&
|
||||||
(answer->fap.funcindex_clientid == question->fap.feature_index) &&
|
(answer->fap.funcindex_clientid == question->fap.feature_index) &&
|
||||||
(answer->fap.params[0] == question->fap.funcindex_clientid);
|
(answer->fap.params[0] == question->fap.funcindex_clientid);
|
||||||
}
|
}
|
||||||
@ -903,24 +915,24 @@ static int wtp_allocate(struct hid_device *hdev, const struct hid_device_id *id)
|
|||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void wtp_connect(struct hid_device *hdev, bool connected)
|
static int wtp_connect(struct hid_device *hdev, bool connected)
|
||||||
{
|
{
|
||||||
struct hidpp_device *hidpp = hid_get_drvdata(hdev);
|
struct hidpp_device *hidpp = hid_get_drvdata(hdev);
|
||||||
struct wtp_data *wd = hidpp->private_data;
|
struct wtp_data *wd = hidpp->private_data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!connected)
|
if (!connected)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
if (!wd->x_size) {
|
if (!wd->x_size) {
|
||||||
ret = wtp_get_config(hidpp);
|
ret = wtp_get_config(hidpp);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
hid_err(hdev, "Can not get wtp config: %d\n", ret);
|
hid_err(hdev, "Can not get wtp config: %d\n", ret);
|
||||||
return;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hidpp_touchpad_set_raw_report_state(hidpp, wd->mt_feature_index,
|
return hidpp_touchpad_set_raw_report_state(hidpp, wd->mt_feature_index,
|
||||||
true, true);
|
true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -965,7 +977,7 @@ static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* If the mutex is locked then we have a pending answer from a
|
* If the mutex is locked then we have a pending answer from a
|
||||||
* previoulsly sent command
|
* previously sent command.
|
||||||
*/
|
*/
|
||||||
if (unlikely(mutex_is_locked(&hidpp->send_mutex))) {
|
if (unlikely(mutex_is_locked(&hidpp->send_mutex))) {
|
||||||
/*
|
/*
|
||||||
@ -996,9 +1008,6 @@ static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
|
|
||||||
return wtp_raw_event(hidpp->hid_dev, data, size);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1006,7 +1015,9 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report,
|
|||||||
u8 *data, int size)
|
u8 *data, int size)
|
||||||
{
|
{
|
||||||
struct hidpp_device *hidpp = hid_get_drvdata(hdev);
|
struct hidpp_device *hidpp = hid_get_drvdata(hdev);
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
/* Generic HID++ processing. */
|
||||||
switch (data[0]) {
|
switch (data[0]) {
|
||||||
case REPORT_ID_HIDPP_LONG:
|
case REPORT_ID_HIDPP_LONG:
|
||||||
if (size != HIDPP_REPORT_LONG_LENGTH) {
|
if (size != HIDPP_REPORT_LONG_LENGTH) {
|
||||||
@ -1014,16 +1025,23 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report,
|
|||||||
size);
|
size);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return hidpp_raw_hidpp_event(hidpp, data, size);
|
ret = hidpp_raw_hidpp_event(hidpp, data, size);
|
||||||
|
break;
|
||||||
case REPORT_ID_HIDPP_SHORT:
|
case REPORT_ID_HIDPP_SHORT:
|
||||||
if (size != HIDPP_REPORT_SHORT_LENGTH) {
|
if (size != HIDPP_REPORT_SHORT_LENGTH) {
|
||||||
hid_err(hdev, "received hid++ report of bad size (%d)",
|
hid_err(hdev, "received hid++ report of bad size (%d)",
|
||||||
size);
|
size);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return hidpp_raw_hidpp_event(hidpp, data, size);
|
ret = hidpp_raw_hidpp_event(hidpp, data, size);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If no report is available for further processing, skip calling
|
||||||
|
* raw_event of subclasses. */
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
|
if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
|
||||||
return wtp_raw_event(hdev, data, size);
|
return wtp_raw_event(hdev, data, size);
|
||||||
|
|
||||||
@ -1070,6 +1088,7 @@ static void hidpp_input_close(struct input_dev *dev)
|
|||||||
static struct input_dev *hidpp_allocate_input(struct hid_device *hdev)
|
static struct input_dev *hidpp_allocate_input(struct hid_device *hdev)
|
||||||
{
|
{
|
||||||
struct input_dev *input_dev = devm_input_allocate_device(&hdev->dev);
|
struct input_dev *input_dev = devm_input_allocate_device(&hdev->dev);
|
||||||
|
struct hidpp_device *hidpp = hid_get_drvdata(hdev);
|
||||||
|
|
||||||
if (!input_dev)
|
if (!input_dev)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1078,7 +1097,7 @@ static struct input_dev *hidpp_allocate_input(struct hid_device *hdev)
|
|||||||
input_dev->open = hidpp_input_open;
|
input_dev->open = hidpp_input_open;
|
||||||
input_dev->close = hidpp_input_close;
|
input_dev->close = hidpp_input_close;
|
||||||
|
|
||||||
input_dev->name = hdev->name;
|
input_dev->name = hidpp->name;
|
||||||
input_dev->phys = hdev->phys;
|
input_dev->phys = hdev->phys;
|
||||||
input_dev->uniq = hdev->uniq;
|
input_dev->uniq = hdev->uniq;
|
||||||
input_dev->id.bustype = hdev->bus;
|
input_dev->id.bustype = hdev->bus;
|
||||||
@ -1098,8 +1117,11 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
|
|||||||
struct input_dev *input;
|
struct input_dev *input;
|
||||||
char *name, *devm_name;
|
char *name, *devm_name;
|
||||||
|
|
||||||
if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
|
if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) {
|
||||||
wtp_connect(hdev, connected);
|
ret = wtp_connect(hdev, connected);
|
||||||
|
if (ret)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!connected || hidpp->delayed_input)
|
if (!connected || hidpp->delayed_input)
|
||||||
return;
|
return;
|
||||||
@ -1117,22 +1139,28 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
|
|||||||
hid_info(hdev, "HID++ %u.%u device connected.\n",
|
hid_info(hdev, "HID++ %u.%u device connected.\n",
|
||||||
hidpp->protocol_major, hidpp->protocol_minor);
|
hidpp->protocol_major, hidpp->protocol_minor);
|
||||||
|
|
||||||
|
if (!hidpp->name || hidpp->name == hdev->name) {
|
||||||
|
name = hidpp_get_device_name(hidpp);
|
||||||
|
if (!name) {
|
||||||
|
hid_err(hdev,
|
||||||
|
"unable to retrieve the name of the device");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
devm_name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s", name);
|
||||||
|
kfree(name);
|
||||||
|
if (!devm_name)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hidpp->name = devm_name;
|
||||||
|
}
|
||||||
|
|
||||||
input = hidpp_allocate_input(hdev);
|
input = hidpp_allocate_input(hdev);
|
||||||
if (!input) {
|
if (!input) {
|
||||||
hid_err(hdev, "cannot allocate new input device: %d\n", ret);
|
hid_err(hdev, "cannot allocate new input device: %d\n", ret);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = hidpp_get_device_name(hidpp);
|
|
||||||
if (!name) {
|
|
||||||
hid_err(hdev, "unable to retrieve the name of the device");
|
|
||||||
} else {
|
|
||||||
devm_name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s", name);
|
|
||||||
if (devm_name)
|
|
||||||
input->name = devm_name;
|
|
||||||
kfree(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
hidpp_populate_input(hidpp, input, false);
|
hidpp_populate_input(hidpp, input, false);
|
||||||
|
|
||||||
ret = input_register_device(input);
|
ret = input_register_device(input);
|
||||||
@ -1155,6 +1183,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
hidpp->hid_dev = hdev;
|
hidpp->hid_dev = hdev;
|
||||||
|
hidpp->name = hdev->name;
|
||||||
hid_set_drvdata(hdev, hidpp);
|
hid_set_drvdata(hdev, hidpp);
|
||||||
|
|
||||||
hidpp->quirks = id->driver_data;
|
hidpp->quirks = id->driver_data;
|
||||||
|
@ -276,6 +276,8 @@ static const struct hid_device_id ms_devices[] = {
|
|||||||
.driver_data = MS_DUPLICATE_USAGES },
|
.driver_data = MS_DUPLICATE_USAGES },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3),
|
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3),
|
||||||
.driver_data = MS_HIDINPUT },
|
.driver_data = MS_HIDINPUT },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3_JP),
|
||||||
|
.driver_data = MS_HIDINPUT },
|
||||||
|
|
||||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT),
|
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT),
|
||||||
.driver_data = MS_PRESENTER },
|
.driver_data = MS_PRESENTER },
|
||||||
|
@ -33,6 +33,10 @@
|
|||||||
#define RMI_READ_DATA_PENDING BIT(1)
|
#define RMI_READ_DATA_PENDING BIT(1)
|
||||||
#define RMI_STARTED BIT(2)
|
#define RMI_STARTED BIT(2)
|
||||||
|
|
||||||
|
/* device flags */
|
||||||
|
#define RMI_DEVICE BIT(0)
|
||||||
|
#define RMI_DEVICE_HAS_PHYS_BUTTONS BIT(1)
|
||||||
|
|
||||||
enum rmi_mode_type {
|
enum rmi_mode_type {
|
||||||
RMI_MODE_OFF = 0,
|
RMI_MODE_OFF = 0,
|
||||||
RMI_MODE_ATTN_REPORTS = 1,
|
RMI_MODE_ATTN_REPORTS = 1,
|
||||||
@ -118,6 +122,8 @@ struct rmi_data {
|
|||||||
|
|
||||||
struct work_struct reset_work;
|
struct work_struct reset_work;
|
||||||
struct hid_device *hdev;
|
struct hid_device *hdev;
|
||||||
|
|
||||||
|
unsigned long device_flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RMI_PAGE(addr) (((addr) >> 8) & 0xff)
|
#define RMI_PAGE(addr) (((addr) >> 8) & 0xff)
|
||||||
@ -452,9 +458,32 @@ static int rmi_raw_event(struct hid_device *hdev,
|
|||||||
return rmi_read_data_event(hdev, data, size);
|
return rmi_read_data_event(hdev, data, size);
|
||||||
case RMI_ATTN_REPORT_ID:
|
case RMI_ATTN_REPORT_ID:
|
||||||
return rmi_input_event(hdev, data, size);
|
return rmi_input_event(hdev, data, size);
|
||||||
case RMI_MOUSE_REPORT_ID:
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rmi_event(struct hid_device *hdev, struct hid_field *field,
|
||||||
|
struct hid_usage *usage, __s32 value)
|
||||||
|
{
|
||||||
|
struct rmi_data *data = hid_get_drvdata(hdev);
|
||||||
|
|
||||||
|
if ((data->device_flags & RMI_DEVICE) &&
|
||||||
|
(field->application == HID_GD_POINTER ||
|
||||||
|
field->application == HID_GD_MOUSE)) {
|
||||||
|
if (data->device_flags & RMI_DEVICE_HAS_PHYS_BUTTONS) {
|
||||||
|
if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((usage->hid == HID_GD_X || usage->hid == HID_GD_Y)
|
||||||
|
&& !value)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
rmi_schedule_reset(hdev);
|
rmi_schedule_reset(hdev);
|
||||||
break;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -856,6 +885,9 @@ static void rmi_input_configured(struct hid_device *hdev, struct hid_input *hi)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!(data->device_flags & RMI_DEVICE))
|
||||||
|
return;
|
||||||
|
|
||||||
/* Allow incoming hid reports */
|
/* Allow incoming hid reports */
|
||||||
hid_device_io_start(hdev);
|
hid_device_io_start(hdev);
|
||||||
|
|
||||||
@ -914,8 +946,38 @@ static int rmi_input_mapping(struct hid_device *hdev,
|
|||||||
struct hid_input *hi, struct hid_field *field,
|
struct hid_input *hi, struct hid_field *field,
|
||||||
struct hid_usage *usage, unsigned long **bit, int *max)
|
struct hid_usage *usage, unsigned long **bit, int *max)
|
||||||
{
|
{
|
||||||
/* we want to make HID ignore the advertised HID collection */
|
struct rmi_data *data = hid_get_drvdata(hdev);
|
||||||
return -1;
|
|
||||||
|
/*
|
||||||
|
* we want to make HID ignore the advertised HID collection
|
||||||
|
* for RMI deivces
|
||||||
|
*/
|
||||||
|
if (data->device_flags & RMI_DEVICE) {
|
||||||
|
if ((data->device_flags & RMI_DEVICE_HAS_PHYS_BUTTONS) &&
|
||||||
|
((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rmi_check_valid_report_id(struct hid_device *hdev, unsigned type,
|
||||||
|
unsigned id, struct hid_report **report)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
*report = hdev->report_enum[type].report_id_hash[id];
|
||||||
|
if (*report) {
|
||||||
|
for (i = 0; i < (*report)->maxfield; i++) {
|
||||||
|
unsigned app = (*report)->field[i]->application;
|
||||||
|
if ((app & HID_USAGE_PAGE) >= HID_UP_MSVENDOR)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||||
@ -925,6 +987,7 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||||||
size_t alloc_size;
|
size_t alloc_size;
|
||||||
struct hid_report *input_report;
|
struct hid_report *input_report;
|
||||||
struct hid_report *output_report;
|
struct hid_report *output_report;
|
||||||
|
struct hid_report *feature_report;
|
||||||
|
|
||||||
data = devm_kzalloc(&hdev->dev, sizeof(struct rmi_data), GFP_KERNEL);
|
data = devm_kzalloc(&hdev->dev, sizeof(struct rmi_data), GFP_KERNEL);
|
||||||
if (!data)
|
if (!data)
|
||||||
@ -943,27 +1006,37 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
input_report = hdev->report_enum[HID_INPUT_REPORT]
|
if (id->driver_data)
|
||||||
.report_id_hash[RMI_ATTN_REPORT_ID];
|
data->device_flags = id->driver_data;
|
||||||
if (!input_report) {
|
|
||||||
hid_err(hdev, "device does not have expected input report\n");
|
/*
|
||||||
ret = -ENODEV;
|
* Check for the RMI specific report ids. If they are misisng
|
||||||
return ret;
|
* simply return and let the events be processed by hid-input
|
||||||
|
*/
|
||||||
|
if (!rmi_check_valid_report_id(hdev, HID_FEATURE_REPORT,
|
||||||
|
RMI_SET_RMI_MODE_REPORT_ID, &feature_report)) {
|
||||||
|
hid_dbg(hdev, "device does not have set mode feature report\n");
|
||||||
|
goto start;
|
||||||
}
|
}
|
||||||
|
|
||||||
data->input_report_size = (input_report->size >> 3) + 1 /* report id */;
|
if (!rmi_check_valid_report_id(hdev, HID_INPUT_REPORT,
|
||||||
|
RMI_ATTN_REPORT_ID, &input_report)) {
|
||||||
output_report = hdev->report_enum[HID_OUTPUT_REPORT]
|
hid_dbg(hdev, "device does not have attention input report\n");
|
||||||
.report_id_hash[RMI_WRITE_REPORT_ID];
|
goto start;
|
||||||
if (!output_report) {
|
|
||||||
hid_err(hdev, "device does not have expected output report\n");
|
|
||||||
ret = -ENODEV;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data->output_report_size = (output_report->size >> 3)
|
data->input_report_size = hid_report_len(input_report);
|
||||||
+ 1 /* report id */;
|
|
||||||
|
|
||||||
|
if (!rmi_check_valid_report_id(hdev, HID_OUTPUT_REPORT,
|
||||||
|
RMI_WRITE_REPORT_ID, &output_report)) {
|
||||||
|
hid_dbg(hdev,
|
||||||
|
"device does not have rmi write output report\n");
|
||||||
|
goto start;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->output_report_size = hid_report_len(output_report);
|
||||||
|
|
||||||
|
data->device_flags |= RMI_DEVICE;
|
||||||
alloc_size = data->output_report_size + data->input_report_size;
|
alloc_size = data->output_report_size + data->input_report_size;
|
||||||
|
|
||||||
data->writeReport = devm_kzalloc(&hdev->dev, alloc_size, GFP_KERNEL);
|
data->writeReport = devm_kzalloc(&hdev->dev, alloc_size, GFP_KERNEL);
|
||||||
@ -978,13 +1051,15 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||||||
|
|
||||||
mutex_init(&data->page_mutex);
|
mutex_init(&data->page_mutex);
|
||||||
|
|
||||||
|
start:
|
||||||
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
hid_err(hdev, "hw start failed\n");
|
hid_err(hdev, "hw start failed\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!test_bit(RMI_STARTED, &data->flags))
|
if ((data->device_flags & RMI_DEVICE) &&
|
||||||
|
!test_bit(RMI_STARTED, &data->flags))
|
||||||
/*
|
/*
|
||||||
* The device maybe in the bootloader if rmi_input_configured
|
* The device maybe in the bootloader if rmi_input_configured
|
||||||
* failed to find F11 in the PDT. Print an error, but don't
|
* failed to find F11 in the PDT. Print an error, but don't
|
||||||
@ -1007,6 +1082,8 @@ static void rmi_remove(struct hid_device *hdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct hid_device_id rmi_id[] = {
|
static const struct hid_device_id rmi_id[] = {
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER, USB_DEVICE_ID_RAZER_BLADE_14),
|
||||||
|
.driver_data = RMI_DEVICE_HAS_PHYS_BUTTONS },
|
||||||
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_RMI, HID_ANY_ID, HID_ANY_ID) },
|
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_RMI, HID_ANY_ID, HID_ANY_ID) },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
@ -1017,6 +1094,7 @@ static struct hid_driver rmi_driver = {
|
|||||||
.id_table = rmi_id,
|
.id_table = rmi_id,
|
||||||
.probe = rmi_probe,
|
.probe = rmi_probe,
|
||||||
.remove = rmi_remove,
|
.remove = rmi_remove,
|
||||||
|
.event = rmi_event,
|
||||||
.raw_event = rmi_raw_event,
|
.raw_event = rmi_raw_event,
|
||||||
.input_mapping = rmi_input_mapping,
|
.input_mapping = rmi_input_mapping,
|
||||||
.input_configured = rmi_input_configured,
|
.input_configured = rmi_input_configured,
|
||||||
|
@ -2,17 +2,9 @@
|
|||||||
# Makefile for the USB input drivers
|
# Makefile for the USB input drivers
|
||||||
#
|
#
|
||||||
|
|
||||||
# Multipart objects.
|
|
||||||
usbhid-y := hid-core.o hid-quirks.o
|
usbhid-y := hid-core.o hid-quirks.o
|
||||||
|
usbhid-$(CONFIG_USB_HIDDEV) += hiddev.o
|
||||||
# Optional parts of multipart objects.
|
usbhid-$(CONFIG_HID_PID) += hid-pidff.o
|
||||||
|
|
||||||
ifeq ($(CONFIG_USB_HIDDEV),y)
|
|
||||||
usbhid-y += hiddev.o
|
|
||||||
endif
|
|
||||||
ifeq ($(CONFIG_HID_PID),y)
|
|
||||||
usbhid-y += hid-pidff.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
obj-$(CONFIG_USB_HID) += usbhid.o
|
obj-$(CONFIG_USB_HID) += usbhid.o
|
||||||
obj-$(CONFIG_USB_KBD) += usbkbd.o
|
obj-$(CONFIG_USB_KBD) += usbkbd.o
|
||||||
|
@ -1252,6 +1252,8 @@ int hid_pidff_init(struct hid_device *hid)
|
|||||||
|
|
||||||
pidff->hid = hid;
|
pidff->hid = hid;
|
||||||
|
|
||||||
|
hid_device_io_start(hid);
|
||||||
|
|
||||||
pidff_find_reports(hid, HID_OUTPUT_REPORT, pidff);
|
pidff_find_reports(hid, HID_OUTPUT_REPORT, pidff);
|
||||||
pidff_find_reports(hid, HID_FEATURE_REPORT, pidff);
|
pidff_find_reports(hid, HID_FEATURE_REPORT, pidff);
|
||||||
|
|
||||||
@ -1315,9 +1317,13 @@ int hid_pidff_init(struct hid_device *hid)
|
|||||||
|
|
||||||
hid_info(dev, "Force feedback for USB HID PID devices by Anssi Hannula <anssi.hannula@gmail.com>\n");
|
hid_info(dev, "Force feedback for USB HID PID devices by Anssi Hannula <anssi.hannula@gmail.com>\n");
|
||||||
|
|
||||||
|
hid_device_io_stop(hid);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
hid_device_io_stop(hid);
|
||||||
|
|
||||||
kfree(pidff);
|
kfree(pidff);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,7 @@ static const struct hid_blacklist {
|
|||||||
{ USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
|
{ USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
|
||||||
{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
|
{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
|
||||||
{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, HID_QUIRK_NO_INIT_REPORTS },
|
{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, HID_QUIRK_NO_INIT_REPORTS },
|
||||||
|
{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3_JP, HID_QUIRK_NO_INIT_REPORTS },
|
||||||
{ USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS },
|
{ USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS },
|
||||||
{ USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750, HID_QUIRK_NO_INIT_REPORTS },
|
{ USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750, HID_QUIRK_NO_INIT_REPORTS },
|
||||||
{ USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS },
|
{ USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS },
|
||||||
|
@ -173,10 +173,8 @@ static void wacom_usage_mapping(struct hid_device *hdev,
|
|||||||
{
|
{
|
||||||
struct wacom *wacom = hid_get_drvdata(hdev);
|
struct wacom *wacom = hid_get_drvdata(hdev);
|
||||||
struct wacom_features *features = &wacom->wacom_wac.features;
|
struct wacom_features *features = &wacom->wacom_wac.features;
|
||||||
bool finger = (field->logical == HID_DG_FINGER) ||
|
bool finger = WACOM_FINGER_FIELD(field);
|
||||||
(field->physical == HID_DG_FINGER);
|
bool pen = WACOM_PEN_FIELD(field);
|
||||||
bool pen = (field->logical == HID_DG_STYLUS) ||
|
|
||||||
(field->physical == HID_DG_STYLUS);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Requiring Stylus Usage will ignore boot mouse
|
* Requiring Stylus Usage will ignore boot mouse
|
||||||
@ -405,6 +403,9 @@ static int wacom_query_tablet_data(struct hid_device *hdev,
|
|||||||
else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID) {
|
else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID) {
|
||||||
return wacom_set_device_mode(hdev, 18, 3, 2);
|
return wacom_set_device_mode(hdev, 18, 3, 2);
|
||||||
}
|
}
|
||||||
|
else if (features->type == WACOM_27QHDT) {
|
||||||
|
return wacom_set_device_mode(hdev, 131, 3, 2);
|
||||||
|
}
|
||||||
} else if (features->device_type == BTN_TOOL_PEN) {
|
} else if (features->device_type == BTN_TOOL_PEN) {
|
||||||
if (features->type <= BAMBOO_PT && features->type != WIRELESS) {
|
if (features->type <= BAMBOO_PT && features->type != WIRELESS) {
|
||||||
return wacom_set_device_mode(hdev, 2, 2, 2);
|
return wacom_set_device_mode(hdev, 2, 2, 2);
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
#include "wacom_wac.h"
|
#include "wacom_wac.h"
|
||||||
#include "wacom.h"
|
#include "wacom.h"
|
||||||
#include <linux/input/mt.h>
|
#include <linux/input/mt.h>
|
||||||
#include <linux/hid.h>
|
|
||||||
|
|
||||||
/* resolution for penabled devices */
|
/* resolution for penabled devices */
|
||||||
#define WACOM_PL_RES 20
|
#define WACOM_PL_RES 20
|
||||||
@ -444,9 +443,6 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
|
|||||||
|
|
||||||
/* Enter report */
|
/* Enter report */
|
||||||
if ((data[1] & 0xfc) == 0xc0) {
|
if ((data[1] & 0xfc) == 0xc0) {
|
||||||
if (features->quirks & WACOM_QUIRK_MULTI_INPUT)
|
|
||||||
wacom->shared->stylus_in_proximity = true;
|
|
||||||
|
|
||||||
/* serial number of the tool */
|
/* serial number of the tool */
|
||||||
wacom->serial[idx] = ((data[3] & 0x0f) << 28) +
|
wacom->serial[idx] = ((data[3] & 0x0f) << 28) +
|
||||||
(data[4] << 20) + (data[5] << 12) +
|
(data[4] << 20) + (data[5] << 12) +
|
||||||
@ -535,24 +531,46 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* don't report events for invalid data
|
||||||
|
*/
|
||||||
/* older I4 styli don't work with new Cintiqs */
|
/* older I4 styli don't work with new Cintiqs */
|
||||||
if (!((wacom->id[idx] >> 20) & 0x01) &&
|
if ((!((wacom->id[idx] >> 20) & 0x01) &&
|
||||||
(features->type == WACOM_21UX2))
|
(features->type == WACOM_21UX2)) ||
|
||||||
|
/* Only large Intuos support Lense Cursor */
|
||||||
|
(wacom->tool[idx] == BTN_TOOL_LENS &&
|
||||||
|
(features->type == INTUOS3 ||
|
||||||
|
features->type == INTUOS3S ||
|
||||||
|
features->type == INTUOS4 ||
|
||||||
|
features->type == INTUOS4S ||
|
||||||
|
features->type == INTUOS5 ||
|
||||||
|
features->type == INTUOS5S ||
|
||||||
|
features->type == INTUOSPM ||
|
||||||
|
features->type == INTUOSPS)) ||
|
||||||
|
/* Cintiq doesn't send data when RDY bit isn't set */
|
||||||
|
(features->type == CINTIQ && !(data[1] & 0x40)))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* Range Report */
|
if (features->quirks & WACOM_QUIRK_MULTI_INPUT)
|
||||||
if ((data[1] & 0xfe) == 0x20) {
|
wacom->shared->stylus_in_proximity = true;
|
||||||
|
|
||||||
|
/* in Range while exiting */
|
||||||
|
if (((data[1] & 0xfe) == 0x20) && wacom->reporting_data) {
|
||||||
input_report_key(input, BTN_TOUCH, 0);
|
input_report_key(input, BTN_TOUCH, 0);
|
||||||
input_report_abs(input, ABS_PRESSURE, 0);
|
input_report_abs(input, ABS_PRESSURE, 0);
|
||||||
input_report_abs(input, ABS_DISTANCE, wacom->features.distance_max);
|
input_report_abs(input, ABS_DISTANCE, wacom->features.distance_max);
|
||||||
if (features->quirks & WACOM_QUIRK_MULTI_INPUT)
|
return 2;
|
||||||
wacom->shared->stylus_in_proximity = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exit report */
|
/* Exit report */
|
||||||
if ((data[1] & 0xfe) == 0x80) {
|
if ((data[1] & 0xfe) == 0x80) {
|
||||||
if (features->quirks & WACOM_QUIRK_MULTI_INPUT)
|
if (features->quirks & WACOM_QUIRK_MULTI_INPUT)
|
||||||
wacom->shared->stylus_in_proximity = false;
|
wacom->shared->stylus_in_proximity = false;
|
||||||
|
wacom->reporting_data = false;
|
||||||
|
|
||||||
|
/* don't report exit if we don't know the ID */
|
||||||
|
if (!wacom->id[idx])
|
||||||
|
return 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset all states otherwise we lose the initial states
|
* Reset all states otherwise we lose the initial states
|
||||||
@ -586,6 +604,11 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
|
|||||||
wacom->id[idx] = 0;
|
wacom->id[idx] = 0;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* don't report other events if we don't know the ID */
|
||||||
|
if (!wacom->id[idx])
|
||||||
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -633,6 +656,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
|
|||||||
data[0] != WACOM_REPORT_INTUOSREAD &&
|
data[0] != WACOM_REPORT_INTUOSREAD &&
|
||||||
data[0] != WACOM_REPORT_INTUOSWRITE &&
|
data[0] != WACOM_REPORT_INTUOSWRITE &&
|
||||||
data[0] != WACOM_REPORT_INTUOSPAD &&
|
data[0] != WACOM_REPORT_INTUOSPAD &&
|
||||||
|
data[0] != WACOM_REPORT_CINTIQ &&
|
||||||
|
data[0] != WACOM_REPORT_CINTIQPAD &&
|
||||||
data[0] != WACOM_REPORT_INTUOS5PAD) {
|
data[0] != WACOM_REPORT_INTUOS5PAD) {
|
||||||
dev_dbg(input->dev.parent,
|
dev_dbg(input->dev.parent,
|
||||||
"%s: received unknown report #%d\n", __func__, data[0]);
|
"%s: received unknown report #%d\n", __func__, data[0]);
|
||||||
@ -644,7 +669,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
|
|||||||
idx = data[1] & 0x01;
|
idx = data[1] & 0x01;
|
||||||
|
|
||||||
/* pad packets. Works as a second tool and is always in prox */
|
/* pad packets. Works as a second tool and is always in prox */
|
||||||
if (data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD) {
|
if (data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD ||
|
||||||
|
data[0] == WACOM_REPORT_CINTIQPAD) {
|
||||||
input = wacom->pad_input;
|
input = wacom->pad_input;
|
||||||
if (features->type >= INTUOS4S && features->type <= INTUOS4L) {
|
if (features->type >= INTUOS4S && features->type <= INTUOS4L) {
|
||||||
input_report_key(input, BTN_0, (data[2] & 0x01));
|
input_report_key(input, BTN_0, (data[2] & 0x01));
|
||||||
@ -744,6 +770,14 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
|
|||||||
} else {
|
} else {
|
||||||
input_report_abs(input, ABS_MISC, 0);
|
input_report_abs(input, ABS_MISC, 0);
|
||||||
}
|
}
|
||||||
|
} else if (features->type == WACOM_27QHD) {
|
||||||
|
input_report_key(input, KEY_PROG1, data[2] & 0x01);
|
||||||
|
input_report_key(input, KEY_PROG2, data[2] & 0x02);
|
||||||
|
input_report_key(input, KEY_PROG3, data[2] & 0x04);
|
||||||
|
|
||||||
|
input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4]));
|
||||||
|
input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6]));
|
||||||
|
input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8]));
|
||||||
} else if (features->type == CINTIQ_HYBRID) {
|
} else if (features->type == CINTIQ_HYBRID) {
|
||||||
/*
|
/*
|
||||||
* Do not send hardware buttons under Android. They
|
* Do not send hardware buttons under Android. They
|
||||||
@ -760,6 +794,12 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
|
|||||||
input_report_key(input, BTN_7, (data[4] & 0x40)); /* Left */
|
input_report_key(input, BTN_7, (data[4] & 0x40)); /* Left */
|
||||||
input_report_key(input, BTN_8, (data[4] & 0x80)); /* Down */
|
input_report_key(input, BTN_8, (data[4] & 0x80)); /* Down */
|
||||||
input_report_key(input, BTN_0, (data[3] & 0x01)); /* Center */
|
input_report_key(input, BTN_0, (data[3] & 0x01)); /* Center */
|
||||||
|
|
||||||
|
if (data[4] | (data[3] & 0x01)) {
|
||||||
|
input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
|
||||||
|
} else {
|
||||||
|
input_report_abs(input, ABS_MISC, 0);
|
||||||
|
}
|
||||||
} else if (features->type >= INTUOS5S && features->type <= INTUOSPL) {
|
} else if (features->type >= INTUOS5S && features->type <= INTUOSPL) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -843,28 +883,6 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
|
|||||||
if (result)
|
if (result)
|
||||||
return result - 1;
|
return result - 1;
|
||||||
|
|
||||||
/* don't proceed if we don't know the ID */
|
|
||||||
if (!wacom->id[idx])
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Only large Intuos support Lense Cursor */
|
|
||||||
if (wacom->tool[idx] == BTN_TOOL_LENS &&
|
|
||||||
(features->type == INTUOS3 ||
|
|
||||||
features->type == INTUOS3S ||
|
|
||||||
features->type == INTUOS4 ||
|
|
||||||
features->type == INTUOS4S ||
|
|
||||||
features->type == INTUOS5 ||
|
|
||||||
features->type == INTUOS5S ||
|
|
||||||
features->type == INTUOSPM ||
|
|
||||||
features->type == INTUOSPS)) {
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cintiq doesn't send data when RDY bit isn't set */
|
|
||||||
if (features->type == CINTIQ && !(data[1] & 0x40))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (features->type >= INTUOS3S) {
|
if (features->type >= INTUOS3S) {
|
||||||
input_report_abs(input, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1));
|
input_report_abs(input, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1));
|
||||||
input_report_abs(input, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1));
|
input_report_abs(input, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1));
|
||||||
@ -951,6 +969,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
|
|||||||
input_report_abs(input, ABS_MISC, wacom->id[idx]); /* report tool id */
|
input_report_abs(input, ABS_MISC, wacom->id[idx]); /* report tool id */
|
||||||
input_report_key(input, wacom->tool[idx], 1);
|
input_report_key(input, wacom->tool[idx], 1);
|
||||||
input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
|
input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
|
||||||
|
wacom->reporting_data = true;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1019,8 +1038,20 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)
|
|||||||
struct input_dev *input = wacom->input;
|
struct input_dev *input = wacom->input;
|
||||||
unsigned char *data = wacom->data;
|
unsigned char *data = wacom->data;
|
||||||
int i;
|
int i;
|
||||||
int current_num_contacts = data[61];
|
int current_num_contacts = 0;
|
||||||
int contacts_to_send = 0;
|
int contacts_to_send = 0;
|
||||||
|
int num_contacts_left = 4; /* maximum contacts per packet */
|
||||||
|
int byte_per_packet = WACOM_BYTES_PER_24HDT_PACKET;
|
||||||
|
int y_offset = 2;
|
||||||
|
|
||||||
|
if (wacom->features.type == WACOM_27QHDT) {
|
||||||
|
current_num_contacts = data[63];
|
||||||
|
num_contacts_left = 10;
|
||||||
|
byte_per_packet = WACOM_BYTES_PER_QHDTHID_PACKET;
|
||||||
|
y_offset = 0;
|
||||||
|
} else {
|
||||||
|
current_num_contacts = data[61];
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First packet resets the counter since only the first
|
* First packet resets the counter since only the first
|
||||||
@ -1029,12 +1060,11 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)
|
|||||||
if (current_num_contacts)
|
if (current_num_contacts)
|
||||||
wacom->num_contacts_left = current_num_contacts;
|
wacom->num_contacts_left = current_num_contacts;
|
||||||
|
|
||||||
/* There are at most 4 contacts per packet */
|
contacts_to_send = min(num_contacts_left, wacom->num_contacts_left);
|
||||||
contacts_to_send = min(4, wacom->num_contacts_left);
|
|
||||||
|
|
||||||
for (i = 0; i < contacts_to_send; i++) {
|
for (i = 0; i < contacts_to_send; i++) {
|
||||||
int offset = (WACOM_BYTES_PER_24HDT_PACKET * i) + 1;
|
int offset = (byte_per_packet * i) + 1;
|
||||||
bool touch = data[offset] & 0x1 && !wacom->shared->stylus_in_proximity;
|
bool touch = (data[offset] & 0x1) && !wacom->shared->stylus_in_proximity;
|
||||||
int slot = input_mt_get_slot_by_key(input, data[offset + 1]);
|
int slot = input_mt_get_slot_by_key(input, data[offset + 1]);
|
||||||
|
|
||||||
if (slot < 0)
|
if (slot < 0)
|
||||||
@ -1044,18 +1074,23 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)
|
|||||||
|
|
||||||
if (touch) {
|
if (touch) {
|
||||||
int t_x = get_unaligned_le16(&data[offset + 2]);
|
int t_x = get_unaligned_le16(&data[offset + 2]);
|
||||||
int c_x = get_unaligned_le16(&data[offset + 4]);
|
int t_y = get_unaligned_le16(&data[offset + 4 + y_offset]);
|
||||||
int t_y = get_unaligned_le16(&data[offset + 6]);
|
|
||||||
int c_y = get_unaligned_le16(&data[offset + 8]);
|
|
||||||
int w = get_unaligned_le16(&data[offset + 10]);
|
|
||||||
int h = get_unaligned_le16(&data[offset + 12]);
|
|
||||||
|
|
||||||
input_report_abs(input, ABS_MT_POSITION_X, t_x);
|
input_report_abs(input, ABS_MT_POSITION_X, t_x);
|
||||||
input_report_abs(input, ABS_MT_POSITION_Y, t_y);
|
input_report_abs(input, ABS_MT_POSITION_Y, t_y);
|
||||||
input_report_abs(input, ABS_MT_TOUCH_MAJOR, min(w,h));
|
|
||||||
input_report_abs(input, ABS_MT_WIDTH_MAJOR, min(w, h) + int_dist(t_x, t_y, c_x, c_y));
|
if (wacom->features.type != WACOM_27QHDT) {
|
||||||
input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h));
|
int c_x = get_unaligned_le16(&data[offset + 4]);
|
||||||
input_report_abs(input, ABS_MT_ORIENTATION, w > h);
|
int c_y = get_unaligned_le16(&data[offset + 8]);
|
||||||
|
int w = get_unaligned_le16(&data[offset + 10]);
|
||||||
|
int h = get_unaligned_le16(&data[offset + 12]);
|
||||||
|
|
||||||
|
input_report_abs(input, ABS_MT_TOUCH_MAJOR, min(w,h));
|
||||||
|
input_report_abs(input, ABS_MT_WIDTH_MAJOR,
|
||||||
|
min(w, h) + int_dist(t_x, t_y, c_x, c_y));
|
||||||
|
input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h));
|
||||||
|
input_report_abs(input, ABS_MT_ORIENTATION, w > h);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input_mt_report_pointer_emulation(input, true);
|
input_mt_report_pointer_emulation(input, true);
|
||||||
@ -1064,6 +1099,7 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)
|
|||||||
if (wacom->num_contacts_left <= 0)
|
if (wacom->num_contacts_left <= 0)
|
||||||
wacom->num_contacts_left = 0;
|
wacom->num_contacts_left = 0;
|
||||||
|
|
||||||
|
wacom->shared->touch_down = (wacom->num_contacts_left > 0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1092,7 +1128,7 @@ static int wacom_mt_touch(struct wacom_wac *wacom)
|
|||||||
|
|
||||||
for (i = 0; i < contacts_to_send; i++) {
|
for (i = 0; i < contacts_to_send; i++) {
|
||||||
int offset = (WACOM_BYTES_PER_MT_PACKET + x_offset) * i + 3;
|
int offset = (WACOM_BYTES_PER_MT_PACKET + x_offset) * i + 3;
|
||||||
bool touch = data[offset] & 0x1;
|
bool touch = (data[offset] & 0x1) && !wacom->shared->stylus_in_proximity;
|
||||||
int id = get_unaligned_le16(&data[offset + 1]);
|
int id = get_unaligned_le16(&data[offset + 1]);
|
||||||
int slot = input_mt_get_slot_by_key(input, id);
|
int slot = input_mt_get_slot_by_key(input, id);
|
||||||
|
|
||||||
@ -1114,6 +1150,7 @@ static int wacom_mt_touch(struct wacom_wac *wacom)
|
|||||||
if (wacom->num_contacts_left < 0)
|
if (wacom->num_contacts_left < 0)
|
||||||
wacom->num_contacts_left = 0;
|
wacom->num_contacts_left = 0;
|
||||||
|
|
||||||
|
wacom->shared->touch_down = (wacom->num_contacts_left > 0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1514,13 +1551,6 @@ static void wacom_wac_finger_report(struct hid_device *hdev,
|
|||||||
wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(hdev);
|
wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(hdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define WACOM_PEN_FIELD(f) (((f)->logical == HID_DG_STYLUS) || \
|
|
||||||
((f)->physical == HID_DG_STYLUS) || \
|
|
||||||
((f)->application == HID_DG_PEN))
|
|
||||||
#define WACOM_FINGER_FIELD(f) (((f)->logical == HID_DG_FINGER) || \
|
|
||||||
((f)->physical == HID_DG_FINGER) || \
|
|
||||||
((f)->application == HID_DG_TOUCHSCREEN))
|
|
||||||
|
|
||||||
void wacom_wac_usage_mapping(struct hid_device *hdev,
|
void wacom_wac_usage_mapping(struct hid_device *hdev,
|
||||||
struct hid_field *field, struct hid_usage *usage)
|
struct hid_field *field, struct hid_usage *usage)
|
||||||
{
|
{
|
||||||
@ -1891,6 +1921,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
|
|||||||
case WACOM_21UX2:
|
case WACOM_21UX2:
|
||||||
case WACOM_22HD:
|
case WACOM_22HD:
|
||||||
case WACOM_24HD:
|
case WACOM_24HD:
|
||||||
|
case WACOM_27QHD:
|
||||||
case DTK:
|
case DTK:
|
||||||
case CINTIQ_HYBRID:
|
case CINTIQ_HYBRID:
|
||||||
sync = wacom_intuos_irq(wacom_wac);
|
sync = wacom_intuos_irq(wacom_wac);
|
||||||
@ -1901,6 +1932,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WACOM_24HDT:
|
case WACOM_24HDT:
|
||||||
|
case WACOM_27QHDT:
|
||||||
sync = wacom_24hdt_irq(wacom_wac);
|
sync = wacom_24hdt_irq(wacom_wac);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2086,8 +2118,14 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev,
|
|||||||
wacom_abs_set_axis(input_dev, wacom_wac);
|
wacom_abs_set_axis(input_dev, wacom_wac);
|
||||||
|
|
||||||
switch (features->type) {
|
switch (features->type) {
|
||||||
|
case GRAPHIRE_BT:
|
||||||
|
__clear_bit(ABS_MISC, input_dev->absbit);
|
||||||
|
|
||||||
case WACOM_MO:
|
case WACOM_MO:
|
||||||
case WACOM_G4:
|
case WACOM_G4:
|
||||||
|
input_set_abs_params(input_dev, ABS_DISTANCE, 0,
|
||||||
|
features->distance_max,
|
||||||
|
0, 0);
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
case GRAPHIRE:
|
case GRAPHIRE:
|
||||||
@ -2106,52 +2144,15 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev,
|
|||||||
__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
|
__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GRAPHIRE_BT:
|
case WACOM_27QHD:
|
||||||
__clear_bit(ABS_MISC, input_dev->absbit);
|
|
||||||
input_set_abs_params(input_dev, ABS_DISTANCE, 0,
|
|
||||||
features->distance_max,
|
|
||||||
0, 0);
|
|
||||||
|
|
||||||
input_set_capability(input_dev, EV_REL, REL_WHEEL);
|
|
||||||
|
|
||||||
__set_bit(BTN_LEFT, input_dev->keybit);
|
|
||||||
__set_bit(BTN_RIGHT, input_dev->keybit);
|
|
||||||
__set_bit(BTN_MIDDLE, input_dev->keybit);
|
|
||||||
|
|
||||||
__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
|
|
||||||
__set_bit(BTN_TOOL_PEN, input_dev->keybit);
|
|
||||||
__set_bit(BTN_TOOL_MOUSE, input_dev->keybit);
|
|
||||||
__set_bit(BTN_STYLUS, input_dev->keybit);
|
|
||||||
__set_bit(BTN_STYLUS2, input_dev->keybit);
|
|
||||||
|
|
||||||
__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WACOM_24HD:
|
case WACOM_24HD:
|
||||||
input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
|
|
||||||
input_abs_set_res(input_dev, ABS_Z, 287);
|
|
||||||
input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0);
|
|
||||||
/* fall through */
|
|
||||||
|
|
||||||
case DTK:
|
case DTK:
|
||||||
__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
|
|
||||||
|
|
||||||
wacom_setup_cintiq(wacom_wac);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WACOM_22HD:
|
case WACOM_22HD:
|
||||||
case WACOM_21UX2:
|
case WACOM_21UX2:
|
||||||
case WACOM_BEE:
|
case WACOM_BEE:
|
||||||
case CINTIQ:
|
case CINTIQ:
|
||||||
input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
|
|
||||||
input_abs_set_res(input_dev, ABS_Z, 287);
|
|
||||||
|
|
||||||
__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
|
|
||||||
|
|
||||||
wacom_setup_cintiq(wacom_wac);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WACOM_13HD:
|
case WACOM_13HD:
|
||||||
|
case CINTIQ_HYBRID:
|
||||||
input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
|
input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
|
||||||
input_abs_set_res(input_dev, ABS_Z, 287);
|
input_abs_set_res(input_dev, ABS_Z, 287);
|
||||||
__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
|
__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
|
||||||
@ -2161,6 +2162,10 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev,
|
|||||||
case INTUOS3:
|
case INTUOS3:
|
||||||
case INTUOS3L:
|
case INTUOS3L:
|
||||||
case INTUOS3S:
|
case INTUOS3S:
|
||||||
|
case INTUOS4:
|
||||||
|
case INTUOS4WL:
|
||||||
|
case INTUOS4L:
|
||||||
|
case INTUOS4S:
|
||||||
input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
|
input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
|
||||||
input_abs_set_res(input_dev, ABS_Z, 287);
|
input_abs_set_res(input_dev, ABS_Z, 287);
|
||||||
/* fall through */
|
/* fall through */
|
||||||
@ -2199,17 +2204,6 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INTUOS4:
|
|
||||||
case INTUOS4WL:
|
|
||||||
case INTUOS4L:
|
|
||||||
case INTUOS4S:
|
|
||||||
input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
|
|
||||||
input_abs_set_res(input_dev, ABS_Z, 287);
|
|
||||||
wacom_setup_intuos(wacom_wac);
|
|
||||||
|
|
||||||
__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WACOM_24HDT:
|
case WACOM_24HDT:
|
||||||
if (features->device_type == BTN_TOOL_FINGER) {
|
if (features->device_type == BTN_TOOL_FINGER) {
|
||||||
input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, features->x_max, 0, 0);
|
input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, features->x_max, 0, 0);
|
||||||
@ -2219,6 +2213,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev,
|
|||||||
}
|
}
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
|
case WACOM_27QHDT:
|
||||||
case MTSCREEN:
|
case MTSCREEN:
|
||||||
case MTTPC:
|
case MTTPC:
|
||||||
case MTTPC_B:
|
case MTTPC_B:
|
||||||
@ -2305,14 +2300,6 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev,
|
|||||||
0, 0);
|
0, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CINTIQ_HYBRID:
|
|
||||||
input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
|
|
||||||
input_abs_set_res(input_dev, ABS_Z, 287);
|
|
||||||
__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
|
|
||||||
|
|
||||||
wacom_setup_cintiq(wacom_wac);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2374,6 +2361,19 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
|
|||||||
input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0);
|
input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WACOM_27QHD:
|
||||||
|
__set_bit(KEY_PROG1, input_dev->keybit);
|
||||||
|
__set_bit(KEY_PROG2, input_dev->keybit);
|
||||||
|
__set_bit(KEY_PROG3, input_dev->keybit);
|
||||||
|
input_set_abs_params(input_dev, ABS_X, -2048, 2048, 0, 0);
|
||||||
|
input_abs_set_res(input_dev, ABS_X, 1024); /* points/g */
|
||||||
|
input_set_abs_params(input_dev, ABS_Y, -2048, 2048, 0, 0);
|
||||||
|
input_abs_set_res(input_dev, ABS_Y, 1024);
|
||||||
|
input_set_abs_params(input_dev, ABS_Z, -2048, 2048, 0, 0);
|
||||||
|
input_abs_set_res(input_dev, ABS_Z, 1024);
|
||||||
|
__set_bit(INPUT_PROP_ACCELEROMETER, input_dev->propbit);
|
||||||
|
break;
|
||||||
|
|
||||||
case DTK:
|
case DTK:
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++)
|
||||||
__set_bit(BTN_0 + i, input_dev->keybit);
|
__set_bit(BTN_0 + i, input_dev->keybit);
|
||||||
@ -2724,6 +2724,18 @@ static const struct wacom_features wacom_features_0xF6 =
|
|||||||
{ "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */
|
{ "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */
|
||||||
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10,
|
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10,
|
||||||
.check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
|
.check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
|
||||||
|
static const struct wacom_features wacom_features_0x32A =
|
||||||
|
{ "Wacom Cintiq 27QHD", 119740, 67520, 2047,
|
||||||
|
63, WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
|
||||||
|
WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
|
||||||
|
static const struct wacom_features wacom_features_0x32B =
|
||||||
|
{ "Wacom Cintiq 27QHD touch", 119740, 67520, 2047, 63,
|
||||||
|
WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
|
||||||
|
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
|
||||||
|
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0x32C };
|
||||||
|
static const struct wacom_features wacom_features_0x32C =
|
||||||
|
{ "Wacom Cintiq 27QHD touch", .type = WACOM_27QHDT,
|
||||||
|
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0x32B, .touch_max = 10 };
|
||||||
static const struct wacom_features wacom_features_0x3F =
|
static const struct wacom_features wacom_features_0x3F =
|
||||||
{ "Wacom Cintiq 21UX", 87200, 65600, 1023, 63,
|
{ "Wacom Cintiq 21UX", 87200, 65600, 1023, 63,
|
||||||
CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
|
CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
|
||||||
@ -3090,6 +3102,9 @@ const struct hid_device_id wacom_ids[] = {
|
|||||||
{ USB_DEVICE_WACOM(0x315) },
|
{ USB_DEVICE_WACOM(0x315) },
|
||||||
{ USB_DEVICE_WACOM(0x317) },
|
{ USB_DEVICE_WACOM(0x317) },
|
||||||
{ USB_DEVICE_WACOM(0x323) },
|
{ USB_DEVICE_WACOM(0x323) },
|
||||||
|
{ USB_DEVICE_WACOM(0x32A) },
|
||||||
|
{ USB_DEVICE_WACOM(0x32B) },
|
||||||
|
{ USB_DEVICE_WACOM(0x32C) },
|
||||||
{ USB_DEVICE_WACOM(0x32F) },
|
{ USB_DEVICE_WACOM(0x32F) },
|
||||||
{ USB_DEVICE_WACOM(0x4001) },
|
{ USB_DEVICE_WACOM(0x4001) },
|
||||||
{ USB_DEVICE_WACOM(0x4004) },
|
{ USB_DEVICE_WACOM(0x4004) },
|
||||||
|
@ -10,9 +10,10 @@
|
|||||||
#define WACOM_WAC_H
|
#define WACOM_WAC_H
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <linux/hid.h>
|
||||||
|
|
||||||
/* maximum packet length for USB devices */
|
/* maximum packet length for USB devices */
|
||||||
#define WACOM_PKGLEN_MAX 68
|
#define WACOM_PKGLEN_MAX 192
|
||||||
|
|
||||||
#define WACOM_NAME_MAX 64
|
#define WACOM_NAME_MAX 64
|
||||||
|
|
||||||
@ -36,6 +37,7 @@
|
|||||||
/* wacom data size per MT contact */
|
/* wacom data size per MT contact */
|
||||||
#define WACOM_BYTES_PER_MT_PACKET 11
|
#define WACOM_BYTES_PER_MT_PACKET 11
|
||||||
#define WACOM_BYTES_PER_24HDT_PACKET 14
|
#define WACOM_BYTES_PER_24HDT_PACKET 14
|
||||||
|
#define WACOM_BYTES_PER_QHDTHID_PACKET 6
|
||||||
|
|
||||||
/* device IDs */
|
/* device IDs */
|
||||||
#define STYLUS_DEVICE_ID 0x02
|
#define STYLUS_DEVICE_ID 0x02
|
||||||
@ -57,6 +59,8 @@
|
|||||||
#define WACOM_REPORT_TPCMT 13
|
#define WACOM_REPORT_TPCMT 13
|
||||||
#define WACOM_REPORT_TPCMT2 3
|
#define WACOM_REPORT_TPCMT2 3
|
||||||
#define WACOM_REPORT_TPCHID 15
|
#define WACOM_REPORT_TPCHID 15
|
||||||
|
#define WACOM_REPORT_CINTIQ 16
|
||||||
|
#define WACOM_REPORT_CINTIQPAD 17
|
||||||
#define WACOM_REPORT_TPCST 16
|
#define WACOM_REPORT_TPCST 16
|
||||||
#define WACOM_REPORT_DTUS 17
|
#define WACOM_REPORT_DTUS 17
|
||||||
#define WACOM_REPORT_TPC1FGE 18
|
#define WACOM_REPORT_TPC1FGE 18
|
||||||
@ -71,6 +75,14 @@
|
|||||||
#define WACOM_QUIRK_MONITOR 0x0008
|
#define WACOM_QUIRK_MONITOR 0x0008
|
||||||
#define WACOM_QUIRK_BATTERY 0x0010
|
#define WACOM_QUIRK_BATTERY 0x0010
|
||||||
|
|
||||||
|
#define WACOM_PEN_FIELD(f) (((f)->logical == HID_DG_STYLUS) || \
|
||||||
|
((f)->physical == HID_DG_STYLUS) || \
|
||||||
|
((f)->physical == HID_DG_PEN) || \
|
||||||
|
((f)->application == HID_DG_PEN))
|
||||||
|
#define WACOM_FINGER_FIELD(f) (((f)->logical == HID_DG_FINGER) || \
|
||||||
|
((f)->physical == HID_DG_FINGER) || \
|
||||||
|
((f)->application == HID_DG_TOUCHSCREEN))
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PENPARTNER = 0,
|
PENPARTNER = 0,
|
||||||
GRAPHIRE,
|
GRAPHIRE,
|
||||||
@ -100,6 +112,7 @@ enum {
|
|||||||
WACOM_22HD,
|
WACOM_22HD,
|
||||||
DTK,
|
DTK,
|
||||||
WACOM_24HD,
|
WACOM_24HD,
|
||||||
|
WACOM_27QHD,
|
||||||
CINTIQ_HYBRID,
|
CINTIQ_HYBRID,
|
||||||
CINTIQ,
|
CINTIQ,
|
||||||
WACOM_BEE,
|
WACOM_BEE,
|
||||||
@ -108,6 +121,7 @@ enum {
|
|||||||
WIRELESS,
|
WIRELESS,
|
||||||
BAMBOO_PT,
|
BAMBOO_PT,
|
||||||
WACOM_24HDT,
|
WACOM_24HDT,
|
||||||
|
WACOM_27QHDT,
|
||||||
TABLETPC, /* add new TPC below */
|
TABLETPC, /* add new TPC below */
|
||||||
TABLETPCE,
|
TABLETPCE,
|
||||||
TABLETPC2FG,
|
TABLETPC2FG,
|
||||||
@ -180,6 +194,7 @@ struct wacom_wac {
|
|||||||
int tool[2];
|
int tool[2];
|
||||||
int id[2];
|
int id[2];
|
||||||
__u32 serial[2];
|
__u32 serial[2];
|
||||||
|
bool reporting_data;
|
||||||
struct wacom_features features;
|
struct wacom_features features;
|
||||||
struct wacom_shared *shared;
|
struct wacom_shared *shared;
|
||||||
struct input_dev *input;
|
struct input_dev *input;
|
||||||
|
@ -574,7 +574,9 @@ static inline void hid_set_drvdata(struct hid_device *hdev, void *data)
|
|||||||
#define HID_GLOBAL_STACK_SIZE 4
|
#define HID_GLOBAL_STACK_SIZE 4
|
||||||
#define HID_COLLECTION_STACK_SIZE 4
|
#define HID_COLLECTION_STACK_SIZE 4
|
||||||
|
|
||||||
#define HID_SCAN_FLAG_MT_WIN_8 0x00000001
|
#define HID_SCAN_FLAG_MT_WIN_8 BIT(0)
|
||||||
|
#define HID_SCAN_FLAG_VENDOR_SPECIFIC BIT(1)
|
||||||
|
#define HID_SCAN_FLAG_GD_POINTER BIT(2)
|
||||||
|
|
||||||
struct hid_parser {
|
struct hid_parser {
|
||||||
struct hid_global global;
|
struct hid_global global;
|
||||||
|
@ -166,6 +166,7 @@ struct input_keymap_entry {
|
|||||||
#define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */
|
#define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */
|
||||||
#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */
|
#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */
|
||||||
#define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */
|
#define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */
|
||||||
|
#define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */
|
||||||
|
|
||||||
#define INPUT_PROP_MAX 0x1f
|
#define INPUT_PROP_MAX 0x1f
|
||||||
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
|
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user