Commit da287567 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid

Pull HID fixes from Jiri Kosina:

 - regression fix (caused by me applying a wrong version of patch) for
   sensor-hub driver, from Srinivas Pandruvada

 - hid-sony fixes (mostly related to DS4 device) from Roderick
   Colenbrander

 - three device-specific quirks-fixes from Alex Wood, Brendan McGrath
   and Marcel Hasler

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid:
  HID: sensor-hub: Move the memset to sensor_hub_get_feature()
  HID: usbhid: Add quirk for Mayflash/Dragonrise DolphinBar.
  HID: usbhid: Add quirk for the Futaba TOSD-5711BB VFD
  HID: sony: Ignore DS4 dongle reports when no device is connected
  HID: sony: Use DS4 MAC address as unique identifier on USB
  HID: sony: Fix error handling bug when touchpad registration fails
  HID: asus: Fix keyboard support
parents 74e5c265 143fca77
...@@ -64,7 +64,8 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); ...@@ -64,7 +64,8 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
#define QUIRK_SKIP_INPUT_MAPPING BIT(2) #define QUIRK_SKIP_INPUT_MAPPING BIT(2)
#define QUIRK_IS_MULTITOUCH BIT(3) #define QUIRK_IS_MULTITOUCH BIT(3)
#define NOTEBOOK_QUIRKS QUIRK_FIX_NOTEBOOK_REPORT #define KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \
QUIRK_NO_INIT_REPORTS)
#define TOUCHPAD_QUIRKS (QUIRK_NO_INIT_REPORTS | \ #define TOUCHPAD_QUIRKS (QUIRK_NO_INIT_REPORTS | \
QUIRK_SKIP_INPUT_MAPPING | \ QUIRK_SKIP_INPUT_MAPPING | \
QUIRK_IS_MULTITOUCH) QUIRK_IS_MULTITOUCH)
...@@ -170,11 +171,11 @@ static int asus_raw_event(struct hid_device *hdev, ...@@ -170,11 +171,11 @@ static int asus_raw_event(struct hid_device *hdev,
static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi) static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi)
{ {
struct input_dev *input = hi->input;
struct asus_drvdata *drvdata = hid_get_drvdata(hdev); struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
if (drvdata->quirks & QUIRK_IS_MULTITOUCH) { if (drvdata->quirks & QUIRK_IS_MULTITOUCH) {
int ret; int ret;
struct input_dev *input = hi->input;
input_set_abs_params(input, ABS_MT_POSITION_X, 0, MAX_X, 0, 0); input_set_abs_params(input, ABS_MT_POSITION_X, 0, MAX_X, 0, 0);
input_set_abs_params(input, ABS_MT_POSITION_Y, 0, MAX_Y, 0, 0); input_set_abs_params(input, ABS_MT_POSITION_Y, 0, MAX_Y, 0, 0);
...@@ -191,10 +192,10 @@ static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi) ...@@ -191,10 +192,10 @@ static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi)
hid_err(hdev, "Asus input mt init slots failed: %d\n", ret); hid_err(hdev, "Asus input mt init slots failed: %d\n", ret);
return ret; return ret;
} }
drvdata->input = input;
} }
drvdata->input = input;
return 0; return 0;
} }
...@@ -286,7 +287,11 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -286,7 +287,11 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
goto err_stop_hw; goto err_stop_hw;
} }
drvdata->input->name = "Asus TouchPad"; if (drvdata->quirks & QUIRK_IS_MULTITOUCH) {
drvdata->input->name = "Asus TouchPad";
} else {
drvdata->input->name = "Asus Keyboard";
}
if (drvdata->quirks & QUIRK_IS_MULTITOUCH) { if (drvdata->quirks & QUIRK_IS_MULTITOUCH) {
ret = asus_start_multitouch(hdev); ret = asus_start_multitouch(hdev);
...@@ -315,7 +320,7 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc, ...@@ -315,7 +320,7 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
static const struct hid_device_id asus_devices[] = { static const struct hid_device_id asus_devices[] = {
{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK,
USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD), NOTEBOOK_QUIRKS}, USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD), KEYBOARD_QUIRKS},
{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK,
USB_DEVICE_ID_ASUSTEK_TOUCHPAD), TOUCHPAD_QUIRKS }, USB_DEVICE_ID_ASUSTEK_TOUCHPAD), TOUCHPAD_QUIRKS },
{ } { }
......
...@@ -319,6 +319,7 @@ ...@@ -319,6 +319,7 @@
#define USB_VENDOR_ID_DRAGONRISE 0x0079 #define USB_VENDOR_ID_DRAGONRISE 0x0079
#define USB_DEVICE_ID_DRAGONRISE_WIIU 0x1800 #define USB_DEVICE_ID_DRAGONRISE_WIIU 0x1800
#define USB_DEVICE_ID_DRAGONRISE_PS3 0x1801 #define USB_DEVICE_ID_DRAGONRISE_PS3 0x1801
#define USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR 0x1803
#define USB_DEVICE_ID_DRAGONRISE_GAMECUBE 0x1843 #define USB_DEVICE_ID_DRAGONRISE_GAMECUBE 0x1843
#define USB_VENDOR_ID_DWAV 0x0eef #define USB_VENDOR_ID_DWAV 0x0eef
...@@ -365,6 +366,9 @@ ...@@ -365,6 +366,9 @@
#define USB_VENDOR_ID_FLATFROG 0x25b5 #define USB_VENDOR_ID_FLATFROG 0x25b5
#define USB_DEVICE_ID_MULTITOUCH_3200 0x0002 #define USB_DEVICE_ID_MULTITOUCH_3200 0x0002
#define USB_VENDOR_ID_FUTABA 0x0547
#define USB_DEVICE_ID_LED_DISPLAY 0x7000
#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
......
...@@ -212,7 +212,6 @@ int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, ...@@ -212,7 +212,6 @@ int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
__s32 value; __s32 value;
int ret = 0; int ret = 0;
memset(buffer, 0, buffer_size);
mutex_lock(&data->mutex); mutex_lock(&data->mutex);
report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT); report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);
if (!report || (field_index >= report->maxfield)) { if (!report || (field_index >= report->maxfield)) {
...@@ -256,6 +255,8 @@ int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, ...@@ -256,6 +255,8 @@ int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
int buffer_index = 0; int buffer_index = 0;
int i; int i;
memset(buffer, 0, buffer_size);
mutex_lock(&data->mutex); mutex_lock(&data->mutex);
report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT); report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);
if (!report || (field_index >= report->maxfield) || if (!report || (field_index >= report->maxfield) ||
......
...@@ -1099,8 +1099,11 @@ struct sony_sc { ...@@ -1099,8 +1099,11 @@ struct sony_sc {
u8 led_delay_on[MAX_LEDS]; u8 led_delay_on[MAX_LEDS];
u8 led_delay_off[MAX_LEDS]; u8 led_delay_off[MAX_LEDS];
u8 led_count; u8 led_count;
bool ds4_dongle_connected;
}; };
static void sony_set_leds(struct sony_sc *sc);
static inline void sony_schedule_work(struct sony_sc *sc) static inline void sony_schedule_work(struct sony_sc *sc)
{ {
if (!sc->defer_initialization) if (!sc->defer_initialization)
...@@ -1430,6 +1433,31 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, ...@@ -1430,6 +1433,31 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
return -EILSEQ; return -EILSEQ;
} }
} }
/*
* In the case of a DS4 USB dongle, bit[2] of byte 31 indicates
* if a DS4 is actually connected (indicated by '0').
* For non-dongle, this bit is always 0 (connected).
*/
if (sc->hdev->vendor == USB_VENDOR_ID_SONY &&
sc->hdev->product == USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE) {
bool connected = (rd[31] & 0x04) ? false : true;
if (!sc->ds4_dongle_connected && connected) {
hid_info(sc->hdev, "DualShock 4 USB dongle: controller connected\n");
sony_set_leds(sc);
sc->ds4_dongle_connected = true;
} else if (sc->ds4_dongle_connected && !connected) {
hid_info(sc->hdev, "DualShock 4 USB dongle: controller disconnected\n");
sc->ds4_dongle_connected = false;
/* Return 0, so hidraw can get the report. */
return 0;
} else if (!sc->ds4_dongle_connected) {
/* Return 0, so hidraw can get the report. */
return 0;
}
}
dualshock4_parse_report(sc, rd, size); dualshock4_parse_report(sc, rd, size);
} }
...@@ -2390,6 +2418,12 @@ static int sony_check_add(struct sony_sc *sc) ...@@ -2390,6 +2418,12 @@ static int sony_check_add(struct sony_sc *sc)
} }
memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address)); memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address));
snprintf(sc->hdev->uniq, sizeof(sc->hdev->uniq),
"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
sc->mac_address[5], sc->mac_address[4],
sc->mac_address[3], sc->mac_address[2],
sc->mac_address[1], sc->mac_address[0]);
} else if ((sc->quirks & SIXAXIS_CONTROLLER_USB) || } else if ((sc->quirks & SIXAXIS_CONTROLLER_USB) ||
(sc->quirks & NAVIGATION_CONTROLLER_USB)) { (sc->quirks & NAVIGATION_CONTROLLER_USB)) {
buf = kmalloc(SIXAXIS_REPORT_0xF2_SIZE, GFP_KERNEL); buf = kmalloc(SIXAXIS_REPORT_0xF2_SIZE, GFP_KERNEL);
...@@ -2548,7 +2582,7 @@ static int sony_input_configured(struct hid_device *hdev, ...@@ -2548,7 +2582,7 @@ static int sony_input_configured(struct hid_device *hdev,
hid_err(sc->hdev, hid_err(sc->hdev,
"Unable to initialize multi-touch slots: %d\n", "Unable to initialize multi-touch slots: %d\n",
ret); ret);
return ret; goto err_stop;
} }
sony_init_output_report(sc, dualshock4_send_output_report); sony_init_output_report(sc, dualshock4_send_output_report);
......
...@@ -83,11 +83,13 @@ static const struct hid_blacklist { ...@@ -83,11 +83,13 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_ELAN, HID_ANY_ID, HID_QUIRK_ALWAYS_POLL }, { USB_VENDOR_ID_ELAN, HID_ANY_ID, HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
{ 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_FUTABA, USB_DEVICE_ID_LED_DISPLAY, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A, HID_QUIRK_ALWAYS_POLL }, { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A, HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL }, { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment