mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-01-11 17:10:13 +00:00
Wireless/new version of the Elecom trackball mouse M-XT3DRBK has a product id that differs from the existing M-XT3DRBK. The report descriptor format also seems to have changed and matches other (newer?) models instead (except for six buttons instead of eight). This patch follows the same format as the patch for the M-XT3URBK (018F) by Naoki Ueki (Nov 3rd 2025) to enable the sixth mouse button. dmesg output: [ 292.074664] usb 1-2: new full-speed USB device number 7 using xhci_hcd [ 292.218667] usb 1-2: New USB device found, idVendor=056e, idProduct=018c, bcdDevice= 1.00 [ 292.218676] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [ 292.218679] usb 1-2: Product: ELECOM TrackBall Mouse [ 292.218681] usb 1-2: Manufacturer: ELECOM usbhid-dump output: 001:006:000:DESCRIPTOR 1765072638.050578 05 01 09 02 A1 01 09 01 A1 00 85 01 05 09 19 01 29 05 15 00 25 01 95 08 75 01 81 02 95 01 75 00 81 01 05 01 09 30 09 31 16 00 80 26 FF 7F 75 10 95 02 81 06 C0 A1 00 05 01 09 38 15 81 25 7F 75 08 95 01 81 06 C0 A1 00 05 0C 0A 38 02 95 01 75 08 15 81 25 7F 81 06 C0 C0 06 01 FF 09 00 A1 01 85 02 09 00 15 00 26 FF 00 75 08 95 07 81 02 C0 05 0C 09 01 A1 01 85 05 15 00 26 3C 02 19 00 2A 3C 02 75 10 95 01 81 00 C0 05 01 09 80 A1 01 85 03 19 81 29 83 15 00 25 01 95 03 75 01 81 02 95 01 75 05 81 01 C0 06 BC FF 09 88 A1 01 85 04 95 01 75 08 15 00 26 FF 00 19 00 2A FF 00 81 00 C0 06 02 FF 09 02 A1 01 85 06 09 02 15 00 26 FF 00 75 08 95 07 B1 02 C0 Signed-off-by: Arnoud Willemsen <mail@lynthium.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
158 lines
5.5 KiB
C
158 lines
5.5 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* HID driver for ELECOM devices:
|
|
* - BM084 Bluetooth Mouse
|
|
* - EX-G Trackballs (M-XT3DRBK, M-XT3URBK, M-XT4DRBK)
|
|
* - DEFT Trackballs (M-DT1DRBK, M-DT1URBK, M-DT2DRBK, M-DT2URBK)
|
|
* - HUGE Trackballs (M-HT1DRBK, M-HT1URBK)
|
|
*
|
|
* Copyright (c) 2010 Richard Nauber <Richard.Nauber@gmail.com>
|
|
* Copyright (c) 2016 Yuxuan Shui <yshuiv7@gmail.com>
|
|
* Copyright (c) 2017 Diego Elio Pettenò <flameeyes@flameeyes.eu>
|
|
* Copyright (c) 2017 Alex Manoussakis <amanou@gnu.org>
|
|
* Copyright (c) 2017 Tomasz Kramkowski <tk@the-tk.com>
|
|
* Copyright (c) 2020 YOSHIOKA Takuma <lo48576@hard-wi.red>
|
|
* Copyright (c) 2022 Takahiro Fujii <fujii@xaxxi.net>
|
|
*/
|
|
|
|
/*
|
|
*/
|
|
|
|
#include <linux/device.h>
|
|
#include <linux/hid.h>
|
|
#include <linux/module.h>
|
|
|
|
#include "hid-ids.h"
|
|
|
|
/*
|
|
* Certain ELECOM mice misreport their button count meaning that they only work
|
|
* correctly with the ELECOM mouse assistant software which is unavailable for
|
|
* Linux. A four extra INPUT reports and a FEATURE report are described by the
|
|
* report descriptor but it does not appear that these enable software to
|
|
* control what the extra buttons map to. The only simple and straightforward
|
|
* solution seems to involve fixing up the report descriptor.
|
|
*/
|
|
#define MOUSE_BUTTONS_MAX 8
|
|
static void mouse_button_fixup(struct hid_device *hdev,
|
|
__u8 *rdesc, unsigned int rsize,
|
|
unsigned int button_bit_count,
|
|
unsigned int padding_bit,
|
|
unsigned int button_report_size,
|
|
unsigned int button_usage_maximum,
|
|
int nbuttons)
|
|
{
|
|
if (rsize < 32 || rdesc[button_bit_count] != 0x95 ||
|
|
rdesc[button_report_size] != 0x75 ||
|
|
rdesc[button_report_size + 1] != 0x01 ||
|
|
rdesc[button_usage_maximum] != 0x29 || rdesc[padding_bit] != 0x75)
|
|
return;
|
|
hid_info(hdev, "Fixing up Elecom mouse button count\n");
|
|
nbuttons = clamp(nbuttons, 0, MOUSE_BUTTONS_MAX);
|
|
rdesc[button_bit_count + 1] = nbuttons;
|
|
rdesc[button_usage_maximum + 1] = nbuttons;
|
|
rdesc[padding_bit + 1] = MOUSE_BUTTONS_MAX - nbuttons;
|
|
}
|
|
|
|
static const __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
|
unsigned int *rsize)
|
|
{
|
|
switch (hdev->product) {
|
|
case USB_DEVICE_ID_ELECOM_BM084:
|
|
/* The BM084 Bluetooth mouse includes a non-existing horizontal
|
|
* wheel in the HID descriptor. */
|
|
if (*rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) {
|
|
hid_info(hdev, "Fixing up Elecom BM084 report descriptor\n");
|
|
rdesc[47] = 0x00;
|
|
}
|
|
break;
|
|
case USB_DEVICE_ID_ELECOM_M_XGL20DLBK:
|
|
/*
|
|
* Report descriptor format:
|
|
* 20: button bit count
|
|
* 28: padding bit count
|
|
* 22: button report size
|
|
* 14: button usage maximum
|
|
*/
|
|
mouse_button_fixup(hdev, rdesc, *rsize, 20, 28, 22, 14, 8);
|
|
break;
|
|
case USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB:
|
|
case USB_DEVICE_ID_ELECOM_M_XT3URBK_018F:
|
|
case USB_DEVICE_ID_ELECOM_M_XT3DRBK_00FC:
|
|
case USB_DEVICE_ID_ELECOM_M_XT4DRBK:
|
|
/*
|
|
* Report descriptor format:
|
|
* 12: button bit count
|
|
* 30: padding bit count
|
|
* 14: button report size
|
|
* 20: button usage maximum
|
|
*/
|
|
mouse_button_fixup(hdev, rdesc, *rsize, 12, 30, 14, 20, 6);
|
|
break;
|
|
case USB_DEVICE_ID_ELECOM_M_DT1URBK:
|
|
case USB_DEVICE_ID_ELECOM_M_DT1DRBK:
|
|
case USB_DEVICE_ID_ELECOM_M_HT1URBK_010C:
|
|
case USB_DEVICE_ID_ELECOM_M_HT1URBK_019B:
|
|
case USB_DEVICE_ID_ELECOM_M_HT1DRBK_010D:
|
|
/*
|
|
* Report descriptor format:
|
|
* 12: button bit count
|
|
* 30: padding bit count
|
|
* 14: button report size
|
|
* 20: button usage maximum
|
|
*/
|
|
mouse_button_fixup(hdev, rdesc, *rsize, 12, 30, 14, 20, 8);
|
|
break;
|
|
case USB_DEVICE_ID_ELECOM_M_XT3DRBK_018C:
|
|
/*
|
|
* Report descriptor format:
|
|
* 22: button bit count
|
|
* 30: padding bit count
|
|
* 24: button report size
|
|
* 16: button usage maximum
|
|
*/
|
|
mouse_button_fixup(hdev, rdesc, *rsize, 22, 30, 24, 16, 6);
|
|
break;
|
|
case USB_DEVICE_ID_ELECOM_M_DT2DRBK:
|
|
case USB_DEVICE_ID_ELECOM_M_HT1DRBK_011C:
|
|
/*
|
|
* Report descriptor format:
|
|
* 22: button bit count
|
|
* 30: padding bit count
|
|
* 24: button report size
|
|
* 16: button usage maximum
|
|
*/
|
|
mouse_button_fixup(hdev, rdesc, *rsize, 22, 30, 24, 16, 8);
|
|
break;
|
|
}
|
|
return rdesc;
|
|
}
|
|
|
|
static const struct hid_device_id elecom_devices[] = {
|
|
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XGL20DLBK) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_018F) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK_00FC) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK_018C) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT2DRBK) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_010C) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_019B) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1DRBK_010D) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1DRBK_011C) },
|
|
{ }
|
|
};
|
|
MODULE_DEVICE_TABLE(hid, elecom_devices);
|
|
|
|
static struct hid_driver elecom_driver = {
|
|
.name = "elecom",
|
|
.id_table = elecom_devices,
|
|
.report_fixup = elecom_report_fixup
|
|
};
|
|
module_hid_driver(elecom_driver);
|
|
|
|
MODULE_DESCRIPTION("HID driver for ELECOM devices");
|
|
MODULE_LICENSE("GPL");
|