Merge branches 'for-3.15/upstream-fixes' and 'for-3.16/upstream' into for-linus
Conflicts: drivers/hid/hid-sensor-hub.c
このコミットが含まれているのは:
@@ -608,7 +608,10 @@ config HID_SAITEK
|
||||
Support for Saitek devices that are not fully compliant with the
|
||||
HID standard.
|
||||
|
||||
Currently only supports the PS1000 controller.
|
||||
Supported devices:
|
||||
- PS1000 Dual Analog Pad
|
||||
- R.A.T.7 Gaming Mouse
|
||||
- M.M.O.7 Gaming Mouse
|
||||
|
||||
config HID_SAMSUNG
|
||||
tristate "Samsung InfraRed remote control or keyboards"
|
||||
|
@@ -1878,7 +1878,11 @@ static const struct hid_device_id hid_have_special_driver[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_RYOS_MK_PRO) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_SAVU) },
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_HID_SAITEK)
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7) },
|
||||
#endif
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
|
||||
|
@@ -165,6 +165,8 @@ static const struct hid_usage_entry hid_usage_table[] = {
|
||||
{0, 0x53, "DeviceIndex"},
|
||||
{0, 0x54, "ContactCount"},
|
||||
{0, 0x55, "ContactMaximumNumber"},
|
||||
{0, 0x5A, "SecondaryBarrelSwitch"},
|
||||
{0, 0x5B, "TransducerSerialNumber"},
|
||||
{ 15, 0, "PhysicalInterfaceDevice" },
|
||||
{0, 0x00, "Undefined"},
|
||||
{0, 0x01, "Physical_Interface_Device"},
|
||||
@@ -272,6 +274,85 @@ static const struct hid_usage_entry hid_usage_table[] = {
|
||||
{0, 0xAA, "Shared_Parameter_Blocks"},
|
||||
{0, 0xAB, "Create_New_Effect_Report"},
|
||||
{0, 0xAC, "RAM_Pool_Available"},
|
||||
{ 0x20, 0, "Sensor" },
|
||||
{ 0x20, 0x01, "Sensor" },
|
||||
{ 0x20, 0x10, "Biometric" },
|
||||
{ 0x20, 0x11, "BiometricHumanPresence" },
|
||||
{ 0x20, 0x12, "BiometricHumanProximity" },
|
||||
{ 0x20, 0x13, "BiometricHumanTouch" },
|
||||
{ 0x20, 0x20, "Electrical" },
|
||||
{ 0x20, 0x21, "ElectricalCapacitance" },
|
||||
{ 0x20, 0x22, "ElectricalCurrent" },
|
||||
{ 0x20, 0x23, "ElectricalPower" },
|
||||
{ 0x20, 0x24, "ElectricalInductance" },
|
||||
{ 0x20, 0x25, "ElectricalResistance" },
|
||||
{ 0x20, 0x26, "ElectricalVoltage" },
|
||||
{ 0x20, 0x27, "ElectricalPoteniometer" },
|
||||
{ 0x20, 0x28, "ElectricalFrequency" },
|
||||
{ 0x20, 0x29, "ElectricalPeriod" },
|
||||
{ 0x20, 0x30, "Environmental" },
|
||||
{ 0x20, 0x31, "EnvironmentalAtmosphericPressure" },
|
||||
{ 0x20, 0x32, "EnvironmentalHumidity" },
|
||||
{ 0x20, 0x33, "EnvironmentalTemperature" },
|
||||
{ 0x20, 0x34, "EnvironmentalWindDirection" },
|
||||
{ 0x20, 0x35, "EnvironmentalWindSpeed" },
|
||||
{ 0x20, 0x40, "Light" },
|
||||
{ 0x20, 0x41, "LightAmbientLight" },
|
||||
{ 0x20, 0x42, "LightConsumerInfrared" },
|
||||
{ 0x20, 0x50, "Location" },
|
||||
{ 0x20, 0x51, "LocationBroadcast" },
|
||||
{ 0x20, 0x52, "LocationDeadReckoning" },
|
||||
{ 0x20, 0x53, "LocationGPS" },
|
||||
{ 0x20, 0x54, "LocationLookup" },
|
||||
{ 0x20, 0x55, "LocationOther" },
|
||||
{ 0x20, 0x56, "LocationStatic" },
|
||||
{ 0x20, 0x57, "LocationTriangulation" },
|
||||
{ 0x20, 0x60, "Mechanical" },
|
||||
{ 0x20, 0x61, "MechanicalBooleanSwitch" },
|
||||
{ 0x20, 0x62, "MechanicalBooleanSwitchArray" },
|
||||
{ 0x20, 0x63, "MechanicalMultivalueSwitch" },
|
||||
{ 0x20, 0x64, "MechanicalForce" },
|
||||
{ 0x20, 0x65, "MechanicalPressure" },
|
||||
{ 0x20, 0x66, "MechanicalStrain" },
|
||||
{ 0x20, 0x67, "MechanicalWeight" },
|
||||
{ 0x20, 0x68, "MechanicalHapticVibrator" },
|
||||
{ 0x20, 0x69, "MechanicalHallEffectSwitch" },
|
||||
{ 0x20, 0x70, "Motion" },
|
||||
{ 0x20, 0x71, "MotionAccelerometer1D" },
|
||||
{ 0x20, 0x72, "MotionAccelerometer2D" },
|
||||
{ 0x20, 0x73, "MotionAccelerometer3D" },
|
||||
{ 0x20, 0x74, "MotionGyrometer1D" },
|
||||
{ 0x20, 0x75, "MotionGyrometer2D" },
|
||||
{ 0x20, 0x76, "MotionGyrometer3D" },
|
||||
{ 0x20, 0x77, "MotionMotionDetector" },
|
||||
{ 0x20, 0x78, "MotionSpeedometer" },
|
||||
{ 0x20, 0x79, "MotionAccelerometer" },
|
||||
{ 0x20, 0x7A, "MotionGyrometer" },
|
||||
{ 0x20, 0x80, "Orientation" },
|
||||
{ 0x20, 0x81, "OrientationCompass1D" },
|
||||
{ 0x20, 0x82, "OrientationCompass2D" },
|
||||
{ 0x20, 0x83, "OrientationCompass3D" },
|
||||
{ 0x20, 0x84, "OrientationInclinometer1D" },
|
||||
{ 0x20, 0x85, "OrientationInclinometer2D" },
|
||||
{ 0x20, 0x86, "OrientationInclinometer3D" },
|
||||
{ 0x20, 0x87, "OrientationDistance1D" },
|
||||
{ 0x20, 0x88, "OrientationDistance2D" },
|
||||
{ 0x20, 0x89, "OrientationDistance3D" },
|
||||
{ 0x20, 0x8A, "OrientationDeviceOrientation" },
|
||||
{ 0x20, 0x8B, "OrientationCompass" },
|
||||
{ 0x20, 0x8C, "OrientationInclinometer" },
|
||||
{ 0x20, 0x8D, "OrientationDistance" },
|
||||
{ 0x20, 0x90, "Scanner" },
|
||||
{ 0x20, 0x91, "ScannerBarcode" },
|
||||
{ 0x20, 0x91, "ScannerRFID" },
|
||||
{ 0x20, 0x91, "ScannerNFC" },
|
||||
{ 0x20, 0xA0, "Time" },
|
||||
{ 0x20, 0xA1, "TimeAlarmTimer" },
|
||||
{ 0x20, 0xA2, "TimeRealTimeClock" },
|
||||
{ 0x20, 0xE0, "Other" },
|
||||
{ 0x20, 0xE1, "OtherCustom" },
|
||||
{ 0x20, 0xE2, "OtherGeneric" },
|
||||
{ 0x20, 0xE3, "OtherGenericEnumerator" },
|
||||
{ 0x84, 0, "Power Device" },
|
||||
{ 0x84, 0x02, "PresentStatus" },
|
||||
{ 0x84, 0x03, "ChangeStatus" },
|
||||
@@ -855,6 +936,16 @@ static const char *keys[KEY_MAX + 1] = {
|
||||
[KEY_KBDILLUMDOWN] = "KbdIlluminationDown",
|
||||
[KEY_KBDILLUMUP] = "KbdIlluminationUp",
|
||||
[KEY_SWITCHVIDEOMODE] = "SwitchVideoMode",
|
||||
[KEY_BUTTONCONFIG] = "ButtonConfig",
|
||||
[KEY_TASKMANAGER] = "TaskManager",
|
||||
[KEY_JOURNAL] = "Journal",
|
||||
[KEY_CONTROLPANEL] = "ControlPanel",
|
||||
[KEY_APPSELECT] = "AppSelect",
|
||||
[KEY_SCREENSAVER] = "ScreenSaver",
|
||||
[KEY_VOICECOMMAND] = "VoiceCommand",
|
||||
[KEY_BRIGHTNESS_MIN] = "BrightnessMin",
|
||||
[KEY_BRIGHTNESS_MAX] = "BrightnessMax",
|
||||
[KEY_BRIGHTNESS_AUTO] = "BrightnessAuto",
|
||||
};
|
||||
|
||||
static const char *relatives[REL_MAX + 1] = {
|
||||
|
@@ -463,6 +463,7 @@
|
||||
|
||||
#define USB_VENDOR_ID_STM_0 0x0483
|
||||
#define USB_DEVICE_ID_STM_HID_SENSOR 0x91d1
|
||||
#define USB_DEVICE_ID_STM_HID_SENSOR_1 0x9100
|
||||
|
||||
#define USB_VENDOR_ID_ION 0x15e4
|
||||
#define USB_DEVICE_ID_ICADE 0x0132
|
||||
@@ -633,6 +634,9 @@
|
||||
#define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713
|
||||
#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730
|
||||
#define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c
|
||||
#define USB_DEVICE_ID_MS_SURFACE_PRO_2 0x0799
|
||||
#define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7
|
||||
#define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9
|
||||
|
||||
#define USB_VENDOR_ID_MOJO 0x8282
|
||||
#define USB_DEVICE_ID_RETRO_ADAPTER 0x3201
|
||||
@@ -764,11 +768,16 @@
|
||||
#define USB_VENDOR_ID_SAITEK 0x06a3
|
||||
#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
|
||||
#define USB_DEVICE_ID_SAITEK_PS1000 0x0621
|
||||
#define USB_DEVICE_ID_SAITEK_RAT7 0x0cd7
|
||||
#define USB_DEVICE_ID_SAITEK_MMO7 0x0cd0
|
||||
|
||||
#define USB_VENDOR_ID_SAMSUNG 0x0419
|
||||
#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001
|
||||
#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600
|
||||
|
||||
#define USB_VENDOR_ID_SEMICO 0x1a2c
|
||||
#define USB_DEVICE_ID_SEMICO_USB_KEYKOARD 0x0023
|
||||
|
||||
#define USB_VENDOR_ID_SENNHEISER 0x1395
|
||||
#define USB_DEVICE_ID_SENNHEISER_BTD500USB 0x002c
|
||||
|
||||
|
@@ -684,9 +684,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
||||
break;
|
||||
|
||||
case 0x46: /* TabletPick */
|
||||
case 0x5a: /* SecondaryBarrelSwitch */
|
||||
map_key_clear(BTN_STYLUS2);
|
||||
break;
|
||||
|
||||
case 0x5b: /* TransducerSerialNumber */
|
||||
set_bit(MSC_SERIAL, input->mscbit);
|
||||
break;
|
||||
|
||||
default: goto unknown;
|
||||
}
|
||||
break;
|
||||
@@ -721,6 +726,13 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
||||
case 0x06c: map_key_clear(KEY_YELLOW); break;
|
||||
case 0x06d: map_key_clear(KEY_ZOOM); break;
|
||||
|
||||
case 0x06f: map_key_clear(KEY_BRIGHTNESSUP); break;
|
||||
case 0x070: map_key_clear(KEY_BRIGHTNESSDOWN); break;
|
||||
case 0x072: map_key_clear(KEY_BRIGHTNESS_TOGGLE); break;
|
||||
case 0x073: map_key_clear(KEY_BRIGHTNESS_MIN); break;
|
||||
case 0x074: map_key_clear(KEY_BRIGHTNESS_MAX); break;
|
||||
case 0x075: map_key_clear(KEY_BRIGHTNESS_AUTO); break;
|
||||
|
||||
case 0x082: map_key_clear(KEY_VIDEO_NEXT); break;
|
||||
case 0x083: map_key_clear(KEY_LAST); break;
|
||||
case 0x084: map_key_clear(KEY_ENTER); break;
|
||||
@@ -761,6 +773,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
||||
case 0x0bf: map_key_clear(KEY_SLOW); break;
|
||||
|
||||
case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break;
|
||||
case 0x0cf: map_key_clear(KEY_VOICECOMMAND); break;
|
||||
case 0x0e0: map_abs_clear(ABS_VOLUME); break;
|
||||
case 0x0e2: map_key_clear(KEY_MUTE); break;
|
||||
case 0x0e5: map_key_clear(KEY_BASSBOOST); break;
|
||||
@@ -768,6 +781,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
||||
case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break;
|
||||
case 0x0f5: map_key_clear(KEY_SLOW); break;
|
||||
|
||||
case 0x181: map_key_clear(KEY_BUTTONCONFIG); break;
|
||||
case 0x182: map_key_clear(KEY_BOOKMARKS); break;
|
||||
case 0x183: map_key_clear(KEY_CONFIG); break;
|
||||
case 0x184: map_key_clear(KEY_WORDPROCESSOR); break;
|
||||
@@ -781,6 +795,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
||||
case 0x18c: map_key_clear(KEY_VOICEMAIL); break;
|
||||
case 0x18d: map_key_clear(KEY_ADDRESSBOOK); break;
|
||||
case 0x18e: map_key_clear(KEY_CALENDAR); break;
|
||||
case 0x18f: map_key_clear(KEY_TASKMANAGER); break;
|
||||
case 0x190: map_key_clear(KEY_JOURNAL); break;
|
||||
case 0x191: map_key_clear(KEY_FINANCE); break;
|
||||
case 0x192: map_key_clear(KEY_CALC); break;
|
||||
case 0x193: map_key_clear(KEY_PLAYER); break;
|
||||
@@ -789,12 +805,15 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
||||
case 0x199: map_key_clear(KEY_CHAT); break;
|
||||
case 0x19c: map_key_clear(KEY_LOGOFF); break;
|
||||
case 0x19e: map_key_clear(KEY_COFFEE); break;
|
||||
case 0x19f: map_key_clear(KEY_CONTROLPANEL); break;
|
||||
case 0x1a2: map_key_clear(KEY_APPSELECT); break;
|
||||
case 0x1a3: map_key_clear(KEY_NEXT); break;
|
||||
case 0x1a4: map_key_clear(KEY_PREVIOUS); break;
|
||||
case 0x1a6: map_key_clear(KEY_HELP); break;
|
||||
case 0x1a7: map_key_clear(KEY_DOCUMENTS); break;
|
||||
case 0x1ab: map_key_clear(KEY_SPELLCHECK); break;
|
||||
case 0x1ae: map_key_clear(KEY_KEYBOARD); break;
|
||||
case 0x1b1: map_key_clear(KEY_SCREENSAVER); break;
|
||||
case 0x1b4: map_key_clear(KEY_FILE); break;
|
||||
case 0x1b6: map_key_clear(KEY_IMAGES); break;
|
||||
case 0x1b7: map_key_clear(KEY_AUDIO); break;
|
||||
|
@@ -114,7 +114,7 @@ int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report)
|
||||
|
||||
rdev->priv = data;
|
||||
rdev->driver_type = RC_DRIVER_IR_RAW;
|
||||
rdev->allowed_protos = RC_BIT_ALL;
|
||||
rc_set_allowed_protocols(rdev, RC_BIT_ALL);
|
||||
rdev->open = picolcd_cir_open;
|
||||
rdev->close = picolcd_cir_close;
|
||||
rdev->input_name = data->hdev->name;
|
||||
|
@@ -1,10 +1,17 @@
|
||||
/*
|
||||
* HID driver for Saitek devices, currently only the PS1000 (USB gamepad).
|
||||
* HID driver for Saitek devices.
|
||||
*
|
||||
* PS1000 (USB gamepad):
|
||||
* Fixes the HID report descriptor by removing a non-existent axis and
|
||||
* clearing the constant bit on the input reports for buttons and d-pad.
|
||||
* (This module is based on "hid-ortek".)
|
||||
*
|
||||
* Copyright (c) 2012 Andreas Hübner
|
||||
*
|
||||
* R.A.T.7, M.M.O.7 (USB gaming mice):
|
||||
* Fixes the mode button which cycles through three constantly pressed
|
||||
* buttons. All three press events are mapped to one button and the
|
||||
* missing release event is generated immediately.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -21,12 +28,57 @@
|
||||
|
||||
#include "hid-ids.h"
|
||||
|
||||
#define SAITEK_FIX_PS1000 0x0001
|
||||
#define SAITEK_RELEASE_MODE_RAT7 0x0002
|
||||
#define SAITEK_RELEASE_MODE_MMO7 0x0004
|
||||
|
||||
struct saitek_sc {
|
||||
unsigned long quirks;
|
||||
int mode;
|
||||
};
|
||||
|
||||
static int saitek_probe(struct hid_device *hdev,
|
||||
const struct hid_device_id *id)
|
||||
{
|
||||
unsigned long quirks = id->driver_data;
|
||||
struct saitek_sc *ssc;
|
||||
int ret;
|
||||
|
||||
ssc = devm_kzalloc(&hdev->dev, sizeof(*ssc), GFP_KERNEL);
|
||||
if (ssc == NULL) {
|
||||
hid_err(hdev, "can't alloc saitek descriptor\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ssc->quirks = quirks;
|
||||
ssc->mode = -1;
|
||||
|
||||
hid_set_drvdata(hdev, ssc);
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret) {
|
||||
hid_err(hdev, "parse failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||
if (ret) {
|
||||
hid_err(hdev, "hw start failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __u8 *saitek_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
unsigned int *rsize)
|
||||
{
|
||||
if (*rsize == 137 && rdesc[20] == 0x09 && rdesc[21] == 0x33
|
||||
&& rdesc[94] == 0x81 && rdesc[95] == 0x03
|
||||
&& rdesc[110] == 0x81 && rdesc[111] == 0x03) {
|
||||
struct saitek_sc *ssc = hid_get_drvdata(hdev);
|
||||
|
||||
if ((ssc->quirks & SAITEK_FIX_PS1000) && *rsize == 137 &&
|
||||
rdesc[20] == 0x09 && rdesc[21] == 0x33 &&
|
||||
rdesc[94] == 0x81 && rdesc[95] == 0x03 &&
|
||||
rdesc[110] == 0x81 && rdesc[111] == 0x03) {
|
||||
|
||||
hid_info(hdev, "Fixing up Saitek PS1000 report descriptor\n");
|
||||
|
||||
@@ -42,8 +94,93 @@ static __u8 *saitek_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
return rdesc;
|
||||
}
|
||||
|
||||
static int saitek_raw_event(struct hid_device *hdev,
|
||||
struct hid_report *report, u8 *raw_data, int size)
|
||||
{
|
||||
struct saitek_sc *ssc = hid_get_drvdata(hdev);
|
||||
|
||||
if (ssc->quirks & SAITEK_RELEASE_MODE_RAT7 && size == 7) {
|
||||
/* R.A.T.7 uses bits 13, 14, 15 for the mode */
|
||||
int mode = -1;
|
||||
if (raw_data[1] & 0x01)
|
||||
mode = 0;
|
||||
else if (raw_data[1] & 0x02)
|
||||
mode = 1;
|
||||
else if (raw_data[1] & 0x04)
|
||||
mode = 2;
|
||||
|
||||
/* clear mode bits */
|
||||
raw_data[1] &= ~0x07;
|
||||
|
||||
if (mode != ssc->mode) {
|
||||
hid_dbg(hdev, "entered mode %d\n", mode);
|
||||
if (ssc->mode != -1) {
|
||||
/* use bit 13 as the mode button */
|
||||
raw_data[1] |= 0x04;
|
||||
}
|
||||
ssc->mode = mode;
|
||||
}
|
||||
} else if (ssc->quirks & SAITEK_RELEASE_MODE_MMO7 && size == 8) {
|
||||
|
||||
/* M.M.O.7 uses bits 8, 22, 23 for the mode */
|
||||
int mode = -1;
|
||||
if (raw_data[1] & 0x80)
|
||||
mode = 0;
|
||||
else if (raw_data[2] & 0x01)
|
||||
mode = 1;
|
||||
else if (raw_data[2] & 0x02)
|
||||
mode = 2;
|
||||
|
||||
/* clear mode bits */
|
||||
raw_data[1] &= ~0x80;
|
||||
raw_data[2] &= ~0x03;
|
||||
|
||||
if (mode != ssc->mode) {
|
||||
hid_dbg(hdev, "entered mode %d\n", mode);
|
||||
if (ssc->mode != -1) {
|
||||
/* use bit 8 as the mode button, bits 22
|
||||
* and 23 do not represent buttons
|
||||
* according to the HID report descriptor
|
||||
*/
|
||||
raw_data[1] |= 0x80;
|
||||
}
|
||||
ssc->mode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int saitek_event(struct hid_device *hdev, struct hid_field *field,
|
||||
struct hid_usage *usage, __s32 value)
|
||||
{
|
||||
struct saitek_sc *ssc = hid_get_drvdata(hdev);
|
||||
struct input_dev *input = field->hidinput->input;
|
||||
|
||||
if (usage->type == EV_KEY && value &&
|
||||
(((ssc->quirks & SAITEK_RELEASE_MODE_RAT7) &&
|
||||
usage->code - BTN_MOUSE == 10) ||
|
||||
((ssc->quirks & SAITEK_RELEASE_MODE_MMO7) &&
|
||||
usage->code - BTN_MOUSE == 15))) {
|
||||
|
||||
input_report_key(input, usage->code, 1);
|
||||
|
||||
/* report missing release event */
|
||||
input_report_key(input, usage->code, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct hid_device_id saitek_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000)},
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000),
|
||||
.driver_data = SAITEK_FIX_PS1000 },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7),
|
||||
.driver_data = SAITEK_RELEASE_MODE_RAT7 },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7),
|
||||
.driver_data = SAITEK_RELEASE_MODE_MMO7 },
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -52,7 +189,10 @@ MODULE_DEVICE_TABLE(hid, saitek_devices);
|
||||
static struct hid_driver saitek_driver = {
|
||||
.name = "saitek",
|
||||
.id_table = saitek_devices,
|
||||
.report_fixup = saitek_report_fixup
|
||||
.probe = saitek_probe,
|
||||
.report_fixup = saitek_report_fixup,
|
||||
.raw_event = saitek_raw_event,
|
||||
.event = saitek_event,
|
||||
};
|
||||
module_hid_driver(saitek_driver);
|
||||
|
||||
|
@@ -705,8 +705,17 @@ static const struct hid_device_id sensor_hub_devices[] = {
|
||||
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1,
|
||||
USB_DEVICE_ID_INTEL_HID_SENSOR_1),
|
||||
.driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
|
||||
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROSOFT,
|
||||
USB_DEVICE_ID_MS_SURFACE_PRO_2),
|
||||
.driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
|
||||
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROSOFT,
|
||||
USB_DEVICE_ID_MS_TOUCH_COVER_2),
|
||||
.driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
|
||||
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROSOFT,
|
||||
USB_DEVICE_ID_MS_TYPE_COVER_2),
|
||||
.driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
|
||||
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0,
|
||||
USB_DEVICE_ID_STM_HID_SENSOR),
|
||||
USB_DEVICE_ID_STM_HID_SENSOR_1),
|
||||
.driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
|
||||
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_TEXAS_INSTRUMENTS,
|
||||
USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA),
|
||||
|
@@ -441,12 +441,11 @@ static int uhid_dev_create2(struct uhid_device *uhid,
|
||||
if (uhid->rd_size <= 0 || uhid->rd_size > HID_MAX_DESCRIPTOR_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
uhid->rd_data = kmalloc(uhid->rd_size, GFP_KERNEL);
|
||||
uhid->rd_data = kmemdup(ev->u.create2.rd_data, uhid->rd_size,
|
||||
GFP_KERNEL);
|
||||
if (!uhid->rd_data)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(uhid->rd_data, ev->u.create2.rd_data, uhid->rd_size);
|
||||
|
||||
hid = hid_allocate_device();
|
||||
if (IS_ERR(hid)) {
|
||||
ret = PTR_ERR(hid);
|
||||
|
@@ -115,6 +115,7 @@ static const struct hid_blacklist {
|
||||
{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS1, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS2, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_HD, HID_QUIRK_NO_INIT_REPORTS },
|
||||
|
新しいイシューから参照
ユーザーをブロックする