Commit 5e206459 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull HID updates from Jiri Kosina:

 - rework of generic input handling which ultimately makes the
   processing of tablet events more generic and reliable (Benjamin
   Tissoires)

 - fixes for handling unnumbered reports fully correctly in i2c-hid
   (Angela Czubak, Dmitry Torokhov)

 - untangling of intermingled code for sending and handling output
   reports in i2c-hid (Dmitry Torokhov)

 - Apple magic keyboard support improvements for newer models (José
   Expósito)

 - Apple T2 Macs support improvements (Aun-Ali Zaidi, Paul Pawlowski)

 - driver for Razer Blackwidow keyboards (Jelle van der Waa)

 - driver for SiGma Micro keyboards (Desmond Lim)

 - integration of first part of DIGImend patches in order to ultimately
   vastly improve Linux support of tablets (Nikolai Kondrashov, José
   Expósito)

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (55 commits)
  HID: intel-ish-hid: Use dma_alloc_coherent for firmware update
  Input: docs: add more details on the use of BTN_TOOL
  HID: input: accommodate priorities for slotted devices
  HID: input: remove the need for HID_QUIRK_INVERT
  HID: input: enforce Invert usage to be processed before InRange
  HID: core: for input reports, process the usages by priority list
  HID: compute an ordered list of input fields to process
  HID: input: move up out-of-range processing of input values
  HID: input: rework spaghetti code with switch statements
  HID: input: tag touchscreens as such if the physical is not there
  HID: core: split data fetching from processing in hid_input_field()
  HID: core: de-duplicate some code in hid_input_field()
  HID: core: statically allocate read buffers
  HID: uclogic: Support multiple frame input devices
  HID: uclogic: Define report IDs before their descriptors
  HID: uclogic: Put version first in rdesc namespace
  HID: uclogic: Use "frame" instead of "buttonpad"
  HID: uclogic: Use different constants for frame report IDs
  HID: uclogic: Specify total report size to buttonpad macro
  HID: uclogic: Switch to matching subreport bytes
  ...
parents 14646776 b146dbbd
...@@ -137,7 +137,11 @@ A few EV_KEY codes have special meanings: ...@@ -137,7 +137,11 @@ A few EV_KEY codes have special meanings:
code should be set to a value of 1. When the tool is no longer interacting code should be set to a value of 1. When the tool is no longer interacting
with the input device, the BTN_TOOL_<name> code should be reset to 0. All with the input device, the BTN_TOOL_<name> code should be reset to 0. All
trackpads, tablets, and touchscreens should use at least one BTN_TOOL_<name> trackpads, tablets, and touchscreens should use at least one BTN_TOOL_<name>
code when events are generated. code when events are generated. Likewise all trackpads, tablets, and
touchscreens should export only one BTN_TOOL_<name> at a time. To not break
existing userspace, it is recommended to not switch tool in one EV_SYN frame
but first emitting the old BTN_TOOL_<name> at 0, then emit one SYN_REPORT
and then set the new BTN_TOOL_<name> at 1.
* BTN_TOUCH: * BTN_TOUCH:
......
...@@ -128,6 +128,8 @@ config HID_ACRUX_FF ...@@ -128,6 +128,8 @@ config HID_ACRUX_FF
config HID_APPLE config HID_APPLE
tristate "Apple {i,Power,Mac}Books" tristate "Apple {i,Power,Mac}Books"
depends on HID depends on HID
depends on LEDS_CLASS
depends on NEW_LEDS
default !EXPERT default !EXPERT
help help
Support for some Apple devices which less or more break Support for some Apple devices which less or more break
...@@ -929,6 +931,13 @@ config PLAYSTATION_FF ...@@ -929,6 +931,13 @@ config PLAYSTATION_FF
Say Y here if you would like to enable force feedback support for Say Y here if you would like to enable force feedback support for
PlayStation game controllers. PlayStation game controllers.
config HID_RAZER
tristate "Razer non-fully HID-compliant devices"
depends on HID
help
Support for Razer devices that are not fully compliant with the
HID standard.
config HID_PRIMAX config HID_PRIMAX
tristate "Primax non-fully HID-compliant devices" tristate "Primax non-fully HID-compliant devices"
depends on HID depends on HID
...@@ -984,6 +993,16 @@ config HID_SEMITEK ...@@ -984,6 +993,16 @@ config HID_SEMITEK
- Woo-dy - Woo-dy
- X-Bows Nature/Knight - X-Bows Nature/Knight
config HID_SIGMAMICRO
tristate "SiGma Micro-based keyboards"
depends on USB_HID
help
Support for keyboards that use the SiGma Micro (a.k.a SigmaChip) IC.
Supported devices:
- Landslides KR-700
- Rapoo V500
config HID_SONY config HID_SONY
tristate "Sony PS2/3/4 accessories" tristate "Sony PS2/3/4 accessories"
depends on USB_HID depends on USB_HID
......
...@@ -99,6 +99,7 @@ hid-picolcd-$(CONFIG_DEBUG_FS) += hid-picolcd_debugfs.o ...@@ -99,6 +99,7 @@ hid-picolcd-$(CONFIG_DEBUG_FS) += hid-picolcd_debugfs.o
obj-$(CONFIG_HID_PLANTRONICS) += hid-plantronics.o obj-$(CONFIG_HID_PLANTRONICS) += hid-plantronics.o
obj-$(CONFIG_HID_PLAYSTATION) += hid-playstation.o obj-$(CONFIG_HID_PLAYSTATION) += hid-playstation.o
obj-$(CONFIG_HID_PRIMAX) += hid-primax.o obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
obj-$(CONFIG_HID_RAZER) += hid-razer.o
obj-$(CONFIG_HID_REDRAGON) += hid-redragon.o obj-$(CONFIG_HID_REDRAGON) += hid-redragon.o
obj-$(CONFIG_HID_RETRODE) += hid-retrode.o obj-$(CONFIG_HID_RETRODE) += hid-retrode.o
obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \
...@@ -109,6 +110,7 @@ obj-$(CONFIG_HID_RMI) += hid-rmi.o ...@@ -109,6 +110,7 @@ obj-$(CONFIG_HID_RMI) += hid-rmi.o
obj-$(CONFIG_HID_SAITEK) += hid-saitek.o obj-$(CONFIG_HID_SAITEK) += hid-saitek.o
obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
obj-$(CONFIG_HID_SEMITEK) += hid-semitek.o obj-$(CONFIG_HID_SEMITEK) += hid-semitek.o
obj-$(CONFIG_HID_SIGMAMICRO) += hid-sigmamicro.o
obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
obj-$(CONFIG_HID_SONY) += hid-sony.o obj-$(CONFIG_HID_SONY) += hid-sony.o
obj-$(CONFIG_HID_SPEEDLINK) += hid-speedlink.o obj-$(CONFIG_HID_SPEEDLINK) += hid-speedlink.o
......
...@@ -301,11 +301,8 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i ...@@ -301,11 +301,8 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
pci_set_master(pdev); pci_set_master(pdev);
rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
if (rc) { if (rc) {
rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); dev_err(&pdev->dev, "failed to set DMA mask\n");
if (rc) { return rc;
dev_err(&pdev->dev, "failed to set DMA mask\n");
return rc;
}
} }
privdata->cl_data = devm_kzalloc(&pdev->dev, sizeof(struct amdtp_cl_data), GFP_KERNEL); privdata->cl_data = devm_kzalloc(&pdev->dev, sizeof(struct amdtp_cl_data), GFP_KERNEL);
......
This diff is collapsed.
This diff is collapsed.
...@@ -58,7 +58,7 @@ static int cbas_ec_query_base(struct cros_ec_device *ec_dev, bool get_state, ...@@ -58,7 +58,7 @@ static int cbas_ec_query_base(struct cros_ec_device *ec_dev, bool get_state,
struct cros_ec_command *msg; struct cros_ec_command *msg;
int ret; int ret;
msg = kzalloc(sizeof(*msg) + max(sizeof(u32), sizeof(*params)), msg = kzalloc(struct_size(msg, data, max(sizeof(u32), sizeof(*params))),
GFP_KERNEL); GFP_KERNEL);
if (!msg) if (!msg)
return -ENOMEM; return -ENOMEM;
......
...@@ -167,6 +167,14 @@ ...@@ -167,6 +167,14 @@
#define USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI 0x0272 #define USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI 0x0272
#define USB_DEVICE_ID_APPLE_WELLSPRING9_ISO 0x0273 #define USB_DEVICE_ID_APPLE_WELLSPRING9_ISO 0x0273
#define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS 0x0274 #define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS 0x0274
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K 0x027a
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132 0x027b
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680 0x027c
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213 0x027d
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K 0x027e
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223 0x027f
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K 0x0280
#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F 0x0340
#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a
#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b
#define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240 #define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240
...@@ -606,7 +614,7 @@ ...@@ -606,7 +614,7 @@
#define USB_VENDOR_ID_HUION 0x256c #define USB_VENDOR_ID_HUION 0x256c
#define USB_DEVICE_ID_HUION_TABLET 0x006e #define USB_DEVICE_ID_HUION_TABLET 0x006e
#define USB_DEVICE_ID_HUION_HS64 0x006d #define USB_DEVICE_ID_HUION_TABLET2 0x006d
#define USB_VENDOR_ID_IBM 0x04b3 #define USB_VENDOR_ID_IBM 0x04b3
#define USB_DEVICE_ID_IBM_SCROLLPOINT_III 0x3100 #define USB_DEVICE_ID_IBM_SCROLLPOINT_III 0x3100
...@@ -1030,6 +1038,9 @@ ...@@ -1030,6 +1038,9 @@
#define I2C_PRODUCT_ID_RAYDIUM_3118 0x3118 #define I2C_PRODUCT_ID_RAYDIUM_3118 0x3118
#define USB_VENDOR_ID_RAZER 0x1532 #define USB_VENDOR_ID_RAZER 0x1532
#define USB_DEVICE_ID_RAZER_BLACKWIDOW_ULTIMATE 0x010D
#define USB_DEVICE_ID_RAZER_BLACKWIDOW 0x010e
#define USB_DEVICE_ID_RAZER_BLACKWIDOW_CLASSIC 0x011b
#define USB_DEVICE_ID_RAZER_BLADE_14 0x011D #define USB_DEVICE_ID_RAZER_BLADE_14 0x011D
#define USB_VENDOR_ID_REALTEK 0x0bda #define USB_VENDOR_ID_REALTEK 0x0bda
...@@ -1092,6 +1103,7 @@ ...@@ -1092,6 +1103,7 @@
#define USB_VENDOR_ID_SIGMA_MICRO 0x1c4f #define USB_VENDOR_ID_SIGMA_MICRO 0x1c4f
#define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD 0x0002 #define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD 0x0002
#define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD2 0x0059
#define USB_VENDOR_ID_SIGMATEL 0x066F #define USB_VENDOR_ID_SIGMATEL 0x066F
#define USB_DEVICE_ID_SIGMATEL_STMP3780 0x3780 #define USB_DEVICE_ID_SIGMATEL_STMP3780 0x3780
......
This diff is collapsed.
...@@ -295,6 +295,14 @@ static const struct hid_device_id hid_have_special_driver[] = { ...@@ -295,6 +295,14 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },
...@@ -930,6 +938,14 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { ...@@ -930,6 +938,14 @@ static const struct hid_device_id hid_mouse_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
{ 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) },
{ } { }
......
// SPDX-License-Identifier: GPL-2.0+
/*
* HID driver for gaming keys on Razer Blackwidow gaming keyboards
* Macro Key Keycodes: M1 = 191, M2 = 192, M3 = 193, M4 = 194, M5 = 195
*
* Copyright (c) 2021 Jelle van der Waa <jvanderwaa@redhat.com>
*/
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/sched.h>
#include <linux/usb.h>
#include <linux/wait.h>
#include "hid-ids.h"
#define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
#define RAZER_BLACKWIDOW_TRANSFER_BUF_SIZE 91
static bool macro_key_remapping = 1;
module_param(macro_key_remapping, bool, 0644);
MODULE_PARM_DESC(macro_key_remapping, " on (Y) off (N)");
static unsigned char blackwidow_init[RAZER_BLACKWIDOW_TRANSFER_BUF_SIZE] = {
0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x00
};
static int razer_input_mapping(struct hid_device *hdev,
struct hid_input *hi, struct hid_field *field,
struct hid_usage *usage, unsigned long **bit, int *max)
{
if (!macro_key_remapping)
return 0;
if ((usage->hid & HID_UP_KEYBOARD) != HID_UP_KEYBOARD)
return 0;
switch (usage->hid & ~HID_UP_KEYBOARD) {
case 0x68:
map_key_clear(KEY_MACRO1);
return 1;
case 0x69:
map_key_clear(KEY_MACRO2);
return 1;
case 0x6a:
map_key_clear(KEY_MACRO3);
return 1;
case 0x6b:
map_key_clear(KEY_MACRO4);
return 1;
case 0x6c:
map_key_clear(KEY_MACRO5);
return 1;
}
return 0;
}
static int razer_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
char *buf;
int ret = 0;
ret = hid_parse(hdev);
if (ret)
return ret;
/*
* Only send the enable macro keys command for the third device
* identified as mouse input.
*/
if (hdev->type == HID_TYPE_USBMOUSE) {
buf = kmemdup(blackwidow_init, RAZER_BLACKWIDOW_TRANSFER_BUF_SIZE, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
ret = hid_hw_raw_request(hdev, 0, buf, RAZER_BLACKWIDOW_TRANSFER_BUF_SIZE,
HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
if (ret != RAZER_BLACKWIDOW_TRANSFER_BUF_SIZE)
hid_err(hdev, "failed to enable macro keys: %d\n", ret);
kfree(buf);
}
return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
}
static const struct hid_device_id razer_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER,
USB_DEVICE_ID_RAZER_BLACKWIDOW) },
{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER,
USB_DEVICE_ID_RAZER_BLACKWIDOW_CLASSIC) },
{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER,
USB_DEVICE_ID_RAZER_BLACKWIDOW_ULTIMATE) },
{ }
};
MODULE_DEVICE_TABLE(hid, razer_devices);
static struct hid_driver razer_driver = {
.name = "razer",
.id_table = razer_devices,
.input_mapping = razer_input_mapping,
.probe = razer_probe,
};
module_hid_driver(razer_driver);
MODULE_AUTHOR("Jelle van der Waa <jvanderwaa@redhat.com>");
MODULE_LICENSE("GPL");
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* HID driver for SiGma Micro-based keyboards
*
* Copyright (c) 2016 Kinglong Mee
* Copyright (c) 2021 Desmond Lim
*/
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
#include "hid-ids.h"
static const __u8 sm_0059_rdesc[] = {
0x05, 0x0c, /* Usage Page (Consumer Devices) 0 */
0x09, 0x01, /* Usage (Consumer Control) 2 */
0xa1, 0x01, /* Collection (Application) 4 */
0x85, 0x01, /* Report ID (1) 6 */
0x19, 0x00, /* Usage Minimum (0) 8 */
0x2a, 0x3c, 0x02, /* Usage Maximum (572) 10 */
0x15, 0x00, /* Logical Minimum (0) 13 */
0x26, 0x3c, 0x02, /* Logical Maximum (572) 15 */
0x95, 0x01, /* Report Count (1) 18 */
0x75, 0x10, /* Report Size (16) 20 */
0x81, 0x00, /* Input (Data,Arr,Abs) 22 */
0xc0, /* End Collection 24 */
0x05, 0x01, /* Usage Page (Generic Desktop) 25 */
0x09, 0x80, /* Usage (System Control) 27 */
0xa1, 0x01, /* Collection (Application) 29 */
0x85, 0x02, /* Report ID (2) 31 */
0x19, 0x81, /* Usage Minimum (129) 33 */
0x29, 0x83, /* Usage Maximum (131) 35 */
0x25, 0x01, /* Logical Maximum (1) 37 */
0x75, 0x01, /* Report Size (1) 39 */
0x95, 0x03, /* Report Count (3) 41 */
0x81, 0x02, /* Input (Data,Var,Abs) 43 */
0x95, 0x05, /* Report Count (5) 45 */
0x81, 0x01, /* Input (Cnst,Arr,Abs) 47 */
0xc0, /* End Collection 49 */
0x06, 0x00, 0xff, /* Usage Page (Vendor Defined Page 1) 50 */
0x09, 0x01, /* Usage (Vendor Usage 1) 53 */
0xa1, 0x01, /* Collection (Application) 55 */
0x85, 0x03, /* Report ID (3) 57 */
0x1a, 0xf1, 0x00, /* Usage Minimum (241) 59 */
0x2a, 0xf8, 0x00, /* Usage Maximum (248) 62 */
0x15, 0x00, /* Logical Minimum (0) 65 */
0x25, 0x01, /* Logical Maximum (1) 67 */
0x75, 0x01, /* Report Size (1) 69 */
0x95, 0x08, /* Report Count (8) 71 */
0x81, 0x02, /* Input (Data,Var,Abs) 73 */
0xc0, /* End Collection 75 */
0x05, 0x01, /* Usage Page (Generic Desktop) 76 */
0x09, 0x06, /* Usage (Keyboard) 78 */
0xa1, 0x01, /* Collection (Application) 80 */
0x85, 0x04, /* Report ID (4) 82 */
0x05, 0x07, /* Usage Page (Keyboard) 84 */
0x19, 0xe0, /* Usage Minimum (224) 86 */
0x29, 0xe7, /* Usage Maximum (231) 88 */
0x15, 0x00, /* Logical Minimum (0) 90 */
0x25, 0x01, /* Logical Maximum (1) 92 */
0x75, 0x01, /* Report Size (1) 94 */
0x95, 0x08, /* Report Count (8) 96 */
0x81, 0x00, /* Input (Data,Arr,Abs) 98 */
0x95, 0x30, /* Report Count (48) 100 */
0x75, 0x01, /* Report Size (1) 102 */
0x15, 0x00, /* Logical Minimum (0) 104 */
0x25, 0x01, /* Logical Maximum (1) 106 */
0x05, 0x07, /* Usage Page (Keyboard) 108 */
0x19, 0x00, /* Usage Minimum (0) 110 */
0x29, 0x2f, /* Usage Maximum (47) 112 */
0x81, 0x02, /* Input (Data,Var,Abs) 114 */
0xc0, /* End Collection 116 */
0x05, 0x01, /* Usage Page (Generic Desktop) 117 */
0x09, 0x06, /* Usage (Keyboard) 119 */
0xa1, 0x01, /* Collection (Application) 121 */
0x85, 0x05, /* Report ID (5) 123 */
0x95, 0x38, /* Report Count (56) 125 */
0x75, 0x01, /* Report Size (1) 127 */
0x15, 0x00, /* Logical Minimum (0) 129 */
0x25, 0x01, /* Logical Maximum (1) 131 */
0x05, 0x07, /* Usage Page (Keyboard) 133 */
0x19, 0x30, /* Usage Minimum (48) 135 */
0x29, 0x67, /* Usage Maximum (103) 137 */
0x81, 0x02, /* Input (Data,Var,Abs) 139 */
0xc0, /* End Collection 141 */
0x05, 0x01, /* Usage Page (Generic Desktop) 142 */
0x09, 0x06, /* Usage (Keyboard) 144 */
0xa1, 0x01, /* Collection (Application) 146 */
0x85, 0x06, /* Report ID (6) 148 */
0x95, 0x38, /* Report Count (56) 150 */
0x75, 0x01, /* Report Size (1) 152 */
0x15, 0x00, /* Logical Minimum (0) 154 */
0x25, 0x01, /* Logical Maximum (1) 156 */
0x05, 0x07, /* Usage Page (Keyboard) 158 */
0x19, 0x68, /* Usage Minimum (104) 160 */
0x29, 0x9f, /* Usage Maximum (159) 162 */
0x81, 0x02, /* Input (Data,Var,Abs) 164 */
0xc0, /* End Collection 166 */
};
static __u8 *sm_report_fixup(struct hid_device *hdev, __u8 *rdesc,
unsigned int *rsize)
{
if (*rsize == sizeof(sm_0059_rdesc) &&
!memcmp(sm_0059_rdesc, rdesc, *rsize)) {
hid_info(hdev, "Fixing up SiGma Micro report descriptor\n");
rdesc[99] = 0x02;
}
return rdesc;
}
static const struct hid_device_id sm_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_SIGMA_MICRO,
USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD2) },
{ }
};
MODULE_DEVICE_TABLE(hid, sm_devices);
static struct hid_driver sm_driver = {
.name = "sigmamicro",
.id_table = sm_devices,
.report_fixup = sm_report_fixup,
};
module_hid_driver(sm_driver);
MODULE_AUTHOR("Kinglong Mee <kinglongmee@gmail.com>");
MODULE_AUTHOR("Desmond Lim <peckishrine@gmail.com>");
MODULE_DESCRIPTION("SiGma Micro HID driver");
MODULE_LICENSE("GPL");
...@@ -81,24 +81,6 @@ static __u8 *uclogic_report_fixup(struct hid_device *hdev, __u8 *rdesc, ...@@ -81,24 +81,6 @@ static __u8 *uclogic_report_fixup(struct hid_device *hdev, __u8 *rdesc,
return rdesc; return rdesc;
} }
static int uclogic_input_mapping(struct hid_device *hdev,
struct hid_input *hi,
struct hid_field *field,
struct hid_usage *usage,
unsigned long **bit,
int *max)
{
struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev);
struct uclogic_params *params = &drvdata->params;
/* discard the unused pen interface */
if (params->pen_unused && (field->application == HID_DG_PEN))
return -1;
/* let hid-core decide what to do */
return 0;
}
static int uclogic_input_configured(struct hid_device *hdev, static int uclogic_input_configured(struct hid_device *hdev,
struct hid_input *hi) struct hid_input *hi)
{ {
...@@ -246,100 +228,171 @@ static int uclogic_resume(struct hid_device *hdev) ...@@ -246,100 +228,171 @@ static int uclogic_resume(struct hid_device *hdev)
} }
#endif #endif
/**
* uclogic_raw_event_pen - handle raw pen events (pen HID reports).
*
* @drvdata: Driver data.
* @data: Report data buffer, can be modified.
* @size: Report data size, bytes.
*
* Returns:
* Negative value on error (stops event delivery), zero for success.
*/
static int uclogic_raw_event_pen(struct uclogic_drvdata *drvdata,
u8 *data, int size)
{
struct uclogic_params_pen *pen = &drvdata->params.pen;
WARN_ON(drvdata == NULL);
WARN_ON(data == NULL && size != 0);
/* If in-range reports are inverted */
if (pen->inrange ==
UCLOGIC_PARAMS_PEN_INRANGE_INVERTED) {
/* Invert the in-range bit */
data[1] ^= 0x40;
}
/*
* If report contains fragmented high-resolution pen
* coordinates
*/
if (size >= 10 && pen->fragmented_hires) {
u8 pressure_low_byte;
u8 pressure_high_byte;
/* Lift pressure bytes */
pressure_low_byte = data[6];
pressure_high_byte = data[7];
/*
* Move Y coord to make space for high-order X
* coord byte
*/
data[6] = data[5];
data[5] = data[4];
/* Move high-order X coord byte */
data[4] = data[8];
/* Move high-order Y coord byte */
data[7] = data[9];
/* Place pressure bytes */
data[8] = pressure_low_byte;
data[9] = pressure_high_byte;
}
/* If we need to emulate in-range detection */
if (pen->inrange == UCLOGIC_PARAMS_PEN_INRANGE_NONE) {
/* Set in-range bit */
data[1] |= 0x40;
/* (Re-)start in-range timeout */
mod_timer(&drvdata->inrange_timer,
jiffies + msecs_to_jiffies(100));
}
/* If we report tilt and Y direction is flipped */
if (size >= 12 && pen->tilt_y_flipped)
data[11] = -data[11];
return 0;
}
/**
* uclogic_raw_event_frame - handle raw frame events (frame HID reports).
*
* @drvdata: Driver data.
* @frame: The parameters of the frame controls to handle.
* @data: Report data buffer, can be modified.
* @size: Report data size, bytes.
*
* Returns:
* Negative value on error (stops event delivery), zero for success.
*/
static int uclogic_raw_event_frame(
struct uclogic_drvdata *drvdata,
const struct uclogic_params_frame *frame,
u8 *data, int size)
{
WARN_ON(drvdata == NULL);
WARN_ON(data == NULL && size != 0);
/* If need to, and can, set pad device ID for Wacom drivers */
if (frame->dev_id_byte > 0 && frame->dev_id_byte < size) {
data[frame->dev_id_byte] = 0xf;
}
/* If need to, and can, read rotary encoder state change */
if (frame->re_lsb > 0 && frame->re_lsb / 8 < size) {
unsigned int byte = frame->re_lsb / 8;
unsigned int bit = frame->re_lsb % 8;
u8 change;
u8 prev_state = drvdata->re_state;
/* Read Gray-coded state */
u8 state = (data[byte] >> bit) & 0x3;
/* Encode state change into 2-bit signed integer */
if ((prev_state == 1 && state == 0) ||
(prev_state == 2 && state == 3)) {
change = 1;
} else if ((prev_state == 2 && state == 0) ||
(prev_state == 1 && state == 3)) {
change = 3;
} else {
change = 0;
}
/* Write change */
data[byte] = (data[byte] & ~((u8)3 << bit)) |
(change << bit);
/* Remember state */
drvdata->re_state = state;
}
return 0;
}
static int uclogic_raw_event(struct hid_device *hdev, static int uclogic_raw_event(struct hid_device *hdev,
struct hid_report *report, struct hid_report *report,
u8 *data, int size) u8 *data, int size)
{ {
unsigned int report_id = report->id;
struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev); struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev);
struct uclogic_params *params = &drvdata->params; struct uclogic_params *params = &drvdata->params;
struct uclogic_params_pen_subreport *subreport;
struct uclogic_params_pen_subreport *subreport_list_end;
size_t i;
/* Tweak pen reports, if necessary */ /* Do not handle anything but input reports */
if (!params->pen_unused && if (report->type != HID_INPUT_REPORT)
(report->type == HID_INPUT_REPORT) && return 0;
(report->id == params->pen.id) &&
(size >= 2)) {
/* If it's the "virtual" frame controls report */
if (params->frame.id != 0 &&
data[1] & params->pen_frame_flag) {
/* Change to virtual frame controls report ID */
data[0] = params->frame.id;
return 0;
}
/* If in-range reports are inverted */
if (params->pen.inrange ==
UCLOGIC_PARAMS_PEN_INRANGE_INVERTED) {
/* Invert the in-range bit */
data[1] ^= 0x40;
}
/*
* If report contains fragmented high-resolution pen
* coordinates
*/
if (size >= 10 && params->pen.fragmented_hires) {
u8 pressure_low_byte;
u8 pressure_high_byte;
/* Lift pressure bytes */
pressure_low_byte = data[6];
pressure_high_byte = data[7];
/*
* Move Y coord to make space for high-order X
* coord byte
*/
data[6] = data[5];
data[5] = data[4];
/* Move high-order X coord byte */
data[4] = data[8];
/* Move high-order Y coord byte */
data[7] = data[9];
/* Place pressure bytes */
data[8] = pressure_low_byte;
data[9] = pressure_high_byte;
}
/* If we need to emulate in-range detection */
if (params->pen.inrange == UCLOGIC_PARAMS_PEN_INRANGE_NONE) {
/* Set in-range bit */
data[1] |= 0x40;
/* (Re-)start in-range timeout */
mod_timer(&drvdata->inrange_timer,
jiffies + msecs_to_jiffies(100));
}
}
/* Tweak frame control reports, if necessary */ while (true) {
if ((report->type == HID_INPUT_REPORT) && /* Tweak pen reports, if necessary */
(report->id == params->frame.id)) { if ((report_id == params->pen.id) && (size >= 2)) {
/* If need to, and can, set pad device ID for Wacom drivers */ subreport_list_end =
if (params->frame.dev_id_byte > 0 && params->pen.subreport_list +
params->frame.dev_id_byte < size) { ARRAY_SIZE(params->pen.subreport_list);
data[params->frame.dev_id_byte] = 0xf; /* Try to match a subreport */
} for (subreport = params->pen.subreport_list;
/* If need to, and can, read rotary encoder state change */ subreport < subreport_list_end; subreport++) {
if (params->frame.re_lsb > 0 && if (subreport->value != 0 &&
params->frame.re_lsb / 8 < size) { subreport->value == data[1]) {
unsigned int byte = params->frame.re_lsb / 8; break;
unsigned int bit = params->frame.re_lsb % 8; }
}
u8 change; /* If a subreport matched */
u8 prev_state = drvdata->re_state; if (subreport < subreport_list_end) {
/* Read Gray-coded state */ /* Change to subreport ID, and restart */
u8 state = (data[byte] >> bit) & 0x3; report_id = data[0] = subreport->id;
/* Encode state change into 2-bit signed integer */ continue;
if ((prev_state == 1 && state == 0) ||
(prev_state == 2 && state == 3)) {
change = 1;
} else if ((prev_state == 2 && state == 0) ||
(prev_state == 1 && state == 3)) {
change = 3;
} else { } else {
change = 0; return uclogic_raw_event_pen(drvdata, data, size);
}
}
/* Tweak frame control reports, if necessary */
for (i = 0; i < ARRAY_SIZE(params->frame_list); i++) {
if (report_id == params->frame_list[i].id) {
return uclogic_raw_event_frame(
drvdata, &params->frame_list[i],
data, size);
} }
/* Write change */
data[byte] = (data[byte] & ~((u8)3 << bit)) |
(change << bit);
/* Remember state */
drvdata->re_state = state;
} }
break;
} }
return 0; return 0;
...@@ -373,7 +426,7 @@ static const struct hid_device_id uclogic_devices[] = { ...@@ -373,7 +426,7 @@ static const struct hid_device_id uclogic_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_HUION, { HID_USB_DEVICE(USB_VENDOR_ID_HUION,
USB_DEVICE_ID_HUION_TABLET) }, USB_DEVICE_ID_HUION_TABLET) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HUION, { HID_USB_DEVICE(USB_VENDOR_ID_HUION,
USB_DEVICE_ID_HUION_HS64) }, USB_DEVICE_ID_HUION_TABLET2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TRUST, { HID_USB_DEVICE(USB_VENDOR_ID_TRUST,
USB_DEVICE_ID_TRUST_PANORA_TABLET) }, USB_DEVICE_ID_TRUST_PANORA_TABLET) },
{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
...@@ -415,7 +468,6 @@ static struct hid_driver uclogic_driver = { ...@@ -415,7 +468,6 @@ static struct hid_driver uclogic_driver = {
.remove = uclogic_remove, .remove = uclogic_remove,
.report_fixup = uclogic_report_fixup, .report_fixup = uclogic_report_fixup,
.raw_event = uclogic_raw_event, .raw_event = uclogic_raw_event,
.input_mapping = uclogic_input_mapping,
.input_configured = uclogic_input_configured, .input_configured = uclogic_input_configured,
#ifdef CONFIG_PM #ifdef CONFIG_PM
.resume = uclogic_resume, .resume = uclogic_resume,
......
This diff is collapsed.
...@@ -33,6 +33,25 @@ enum uclogic_params_pen_inrange { ...@@ -33,6 +33,25 @@ enum uclogic_params_pen_inrange {
extern const char *uclogic_params_pen_inrange_to_str( extern const char *uclogic_params_pen_inrange_to_str(
enum uclogic_params_pen_inrange inrange); enum uclogic_params_pen_inrange inrange);
/*
* Pen report's subreport data.
*/
struct uclogic_params_pen_subreport {
/*
* The value of the second byte of the pen report indicating this
* subreport. If zero, the subreport should be considered invalid and
* not matched.
*/
__u8 value;
/*
* The ID to be assigned to the report, if the second byte of the pen
* report is equal to "value". Only valid if "value" is not zero.
*/
__u8 id;
};
/* /*
* Tablet interface's pen input parameters. * Tablet interface's pen input parameters.
* *
...@@ -54,6 +73,8 @@ struct uclogic_params_pen { ...@@ -54,6 +73,8 @@ struct uclogic_params_pen {
unsigned int desc_size; unsigned int desc_size;
/* Report ID, if reports should be tweaked, zero if not */ /* Report ID, if reports should be tweaked, zero if not */
unsigned int id; unsigned int id;
/* The list of subreports */
struct uclogic_params_pen_subreport subreport_list[1];
/* Type of in-range reporting, only valid if "id" is not zero */ /* Type of in-range reporting, only valid if "id" is not zero */
enum uclogic_params_pen_inrange inrange; enum uclogic_params_pen_inrange inrange;
/* /*
...@@ -62,6 +83,12 @@ struct uclogic_params_pen { ...@@ -62,6 +83,12 @@ struct uclogic_params_pen {
* Only valid if "id" is not zero. * Only valid if "id" is not zero.
*/ */
bool fragmented_hires; bool fragmented_hires;
/*
* True if the pen reports tilt in bytes at offset 10 (X) and 11 (Y),
* and the Y tilt direction is flipped.
* Only valid if "id" is not zero.
*/
bool tilt_y_flipped;
}; };
/* /*
...@@ -132,28 +159,16 @@ struct uclogic_params { ...@@ -132,28 +159,16 @@ struct uclogic_params {
* Only valid, if "desc_ptr" is not NULL. * Only valid, if "desc_ptr" is not NULL.
*/ */
unsigned int desc_size; unsigned int desc_size;
/*
* True, if pen usage in report descriptor is invalid, when present.
* Only valid, if "invalid" is false.
*/
bool pen_unused;
/* /*
* Pen parameters and optional report descriptor part. * Pen parameters and optional report descriptor part.
* Only valid if "pen_unused" is valid and false.
*/
struct uclogic_params_pen pen;
/*
* Frame control parameters and optional report descriptor part.
* Only valid, if "invalid" is false. * Only valid, if "invalid" is false.
*/ */
struct uclogic_params_frame frame; struct uclogic_params_pen pen;
/* /*
* Bitmask matching frame controls "sub-report" flag in the second * The list of frame control parameters and optional report descriptor
* byte of the pen report, or zero if it's not expected. * parts. Only valid, if "invalid" is false.
* Only valid if both "pen" and "frame" are valid, and "frame.id" is
* not zero.
*/ */
__u8 pen_frame_flag; struct uclogic_params_frame frame_list[1];
}; };
/* Initialize a tablet interface and discover its parameters */ /* Initialize a tablet interface and discover its parameters */
...@@ -162,39 +177,40 @@ extern int uclogic_params_init(struct uclogic_params *params, ...@@ -162,39 +177,40 @@ extern int uclogic_params_init(struct uclogic_params *params,
/* Tablet interface parameters *printf format string */ /* Tablet interface parameters *printf format string */
#define UCLOGIC_PARAMS_FMT_STR \ #define UCLOGIC_PARAMS_FMT_STR \
".invalid = %s\n" \ ".invalid = %s\n" \
".desc_ptr = %p\n" \ ".desc_ptr = %p\n" \
".desc_size = %u\n" \ ".desc_size = %u\n" \
".pen_unused = %s\n" \ ".pen.desc_ptr = %p\n" \
".pen.desc_ptr = %p\n" \ ".pen.desc_size = %u\n" \
".pen.desc_size = %u\n" \ ".pen.id = %u\n" \
".pen.id = %u\n" \ ".pen.subreport_list[0] = {0x%02hhx, %hhu}\n" \
".pen.inrange = %s\n" \ ".pen.inrange = %s\n" \
".pen.fragmented_hires = %s\n" \ ".pen.fragmented_hires = %s\n" \
".frame.desc_ptr = %p\n" \ ".pen.tilt_y_flipped = %s\n" \
".frame.desc_size = %u\n" \ ".frame_list[0].desc_ptr = %p\n" \
".frame.id = %u\n" \ ".frame_list[0].desc_size = %u\n" \
".frame.re_lsb = %u\n" \ ".frame_list[0].id = %u\n" \
".frame.dev_id_byte = %u\n" \ ".frame_list[0].re_lsb = %u\n" \
".pen_frame_flag = 0x%02x\n" ".frame_list[0].dev_id_byte = %u\n"
/* Tablet interface parameters *printf format arguments */ /* Tablet interface parameters *printf format arguments */
#define UCLOGIC_PARAMS_FMT_ARGS(_params) \ #define UCLOGIC_PARAMS_FMT_ARGS(_params) \
((_params)->invalid ? "true" : "false"), \ ((_params)->invalid ? "true" : "false"), \
(_params)->desc_ptr, \ (_params)->desc_ptr, \
(_params)->desc_size, \ (_params)->desc_size, \
((_params)->pen_unused ? "true" : "false"), \
(_params)->pen.desc_ptr, \ (_params)->pen.desc_ptr, \
(_params)->pen.desc_size, \ (_params)->pen.desc_size, \
(_params)->pen.id, \ (_params)->pen.id, \
(_params)->pen.subreport_list[0].value, \
(_params)->pen.subreport_list[0].id, \
uclogic_params_pen_inrange_to_str((_params)->pen.inrange), \ uclogic_params_pen_inrange_to_str((_params)->pen.inrange), \
((_params)->pen.fragmented_hires ? "true" : "false"), \ ((_params)->pen.fragmented_hires ? "true" : "false"), \
(_params)->frame.desc_ptr, \ ((_params)->pen.tilt_y_flipped ? "true" : "false"), \
(_params)->frame.desc_size, \ (_params)->frame_list[0].desc_ptr, \
(_params)->frame.id, \ (_params)->frame_list[0].desc_size, \
(_params)->frame.re_lsb, \ (_params)->frame_list[0].id, \
(_params)->frame.dev_id_byte, \ (_params)->frame_list[0].re_lsb, \
(_params)->pen_frame_flag (_params)->frame_list[0].dev_id_byte
/* Get a replacement report descriptor for a tablet's interface. */ /* Get a replacement report descriptor for a tablet's interface. */
extern int uclogic_params_get_desc(const struct uclogic_params *params, extern int uclogic_params_get_desc(const struct uclogic_params *params,
......
...@@ -532,7 +532,7 @@ const size_t uclogic_rdesc_twha60_fixed1_size = ...@@ -532,7 +532,7 @@ const size_t uclogic_rdesc_twha60_fixed1_size =
sizeof(uclogic_rdesc_twha60_fixed1_arr); sizeof(uclogic_rdesc_twha60_fixed1_arr);
/* Fixed report descriptor template for (tweaked) v1 pen reports */ /* Fixed report descriptor template for (tweaked) v1 pen reports */
const __u8 uclogic_rdesc_pen_v1_template_arr[] = { const __u8 uclogic_rdesc_v1_pen_template_arr[] = {
0x05, 0x0D, /* Usage Page (Digitizer), */ 0x05, 0x0D, /* Usage Page (Digitizer), */
0x09, 0x02, /* Usage (Pen), */ 0x09, 0x02, /* Usage (Pen), */
0xA1, 0x01, /* Collection (Application), */ 0xA1, 0x01, /* Collection (Application), */
...@@ -582,11 +582,11 @@ const __u8 uclogic_rdesc_pen_v1_template_arr[] = { ...@@ -582,11 +582,11 @@ const __u8 uclogic_rdesc_pen_v1_template_arr[] = {
0xC0 /* End Collection */ 0xC0 /* End Collection */
}; };
const size_t uclogic_rdesc_pen_v1_template_size = const size_t uclogic_rdesc_v1_pen_template_size =
sizeof(uclogic_rdesc_pen_v1_template_arr); sizeof(uclogic_rdesc_v1_pen_template_arr);
/* Fixed report descriptor template for (tweaked) v2 pen reports */ /* Fixed report descriptor template for (tweaked) v2 pen reports */
const __u8 uclogic_rdesc_pen_v2_template_arr[] = { const __u8 uclogic_rdesc_v2_pen_template_arr[] = {
0x05, 0x0D, /* Usage Page (Digitizer), */ 0x05, 0x0D, /* Usage Page (Digitizer), */
0x09, 0x02, /* Usage (Pen), */ 0x09, 0x02, /* Usage (Pen), */
0xA1, 0x01, /* Collection (Application), */ 0xA1, 0x01, /* Collection (Application), */
...@@ -633,25 +633,35 @@ const __u8 uclogic_rdesc_pen_v2_template_arr[] = { ...@@ -633,25 +633,35 @@ const __u8 uclogic_rdesc_pen_v2_template_arr[] = {
0x27, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM), 0x27, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM),
/* Logical Maximum (PLACEHOLDER), */ /* Logical Maximum (PLACEHOLDER), */
0x81, 0x02, /* Input (Variable), */ 0x81, 0x02, /* Input (Variable), */
0x81, 0x03, /* Input (Constant, Variable), */ 0x54, /* Unit Exponent (0), */
0x65, 0x14, /* Unit (Degrees), */
0x35, 0xC4, /* Physical Minimum (-60), */
0x45, 0x3C, /* Physical Maximum (60), */
0x15, 0xC4, /* Logical Minimum (-60), */
0x25, 0x3C, /* Logical Maximum (60), */
0x75, 0x08, /* Report Size (8), */
0x95, 0x02, /* Report Count (2), */
0x09, 0x3D, /* Usage (X Tilt), */
0x09, 0x3E, /* Usage (Y Tilt), */
0x81, 0x02, /* Input (Variable), */
0xC0, /* End Collection, */ 0xC0, /* End Collection, */
0xC0 /* End Collection */ 0xC0 /* End Collection */
}; };
const size_t uclogic_rdesc_pen_v2_template_size = const size_t uclogic_rdesc_v2_pen_template_size =
sizeof(uclogic_rdesc_pen_v2_template_arr); sizeof(uclogic_rdesc_v2_pen_template_arr);
/* /*
* Expand to the contents of a generic buttonpad report descriptor. * Expand to the contents of a generic frame report descriptor.
* *
* @_padding: Padding from the end of button bits at bit 44, until * @_id: The report ID to use.
* the end of the report, in bits. * @_size: Size of the report to pad to, including report ID, bytes.
*/ */
#define UCLOGIC_RDESC_BUTTONPAD_BYTES(_padding) \ #define UCLOGIC_RDESC_FRAME_BYTES(_id, _size) \
0x05, 0x01, /* Usage Page (Desktop), */ \ 0x05, 0x01, /* Usage Page (Desktop), */ \
0x09, 0x07, /* Usage (Keypad), */ \ 0x09, 0x07, /* Usage (Keypad), */ \
0xA1, 0x01, /* Collection (Application), */ \ 0xA1, 0x01, /* Collection (Application), */ \
0x85, 0xF7, /* Report ID (247), */ \ 0x85, (_id), /* Report ID (_id), */ \
0x14, /* Logical Minimum (0), */ \ 0x14, /* Logical Minimum (0), */ \
0x25, 0x01, /* Logical Maximum (1), */ \ 0x25, 0x01, /* Logical Maximum (1), */ \
0x75, 0x01, /* Report Size (1), */ \ 0x75, 0x01, /* Report Size (1), */ \
...@@ -679,30 +689,31 @@ const size_t uclogic_rdesc_pen_v2_template_size = ...@@ -679,30 +689,31 @@ const size_t uclogic_rdesc_pen_v2_template_size =
0xA0, /* Collection (Physical), */ \ 0xA0, /* Collection (Physical), */ \
0x05, 0x09, /* Usage Page (Button), */ \ 0x05, 0x09, /* Usage Page (Button), */ \
0x19, 0x01, /* Usage Minimum (01h), */ \ 0x19, 0x01, /* Usage Minimum (01h), */ \
0x29, 0x02, /* Usage Maximum (02h), */ \ 0x29, 0x03, /* Usage Maximum (03h), */ \
0x95, 0x02, /* Report Count (2), */ \ 0x95, 0x03, /* Report Count (3), */ \
0x81, 0x02, /* Input (Variable), */ \ 0x81, 0x02, /* Input (Variable), */ \
0x95, _padding, /* Report Count (_padding), */ \ 0x95, ((_size) * 8 - 45), \
/* Report Count (padding), */ \
0x81, 0x01, /* Input (Constant), */ \ 0x81, 0x01, /* Input (Constant), */ \
0xC0, /* End Collection, */ \ 0xC0, /* End Collection, */ \
0xC0 /* End Collection */ 0xC0 /* End Collection */
/* Fixed report descriptor for (tweaked) v1 buttonpad reports */ /* Fixed report descriptor for (tweaked) v1 frame reports */
const __u8 uclogic_rdesc_buttonpad_v1_arr[] = { const __u8 uclogic_rdesc_v1_frame_arr[] = {
UCLOGIC_RDESC_BUTTONPAD_BYTES(20) UCLOGIC_RDESC_FRAME_BYTES(UCLOGIC_RDESC_V1_FRAME_ID, 8)
}; };
const size_t uclogic_rdesc_buttonpad_v1_size = const size_t uclogic_rdesc_v1_frame_size =
sizeof(uclogic_rdesc_buttonpad_v1_arr); sizeof(uclogic_rdesc_v1_frame_arr);
/* Fixed report descriptor for (tweaked) v2 buttonpad reports */ /* Fixed report descriptor for (tweaked) v2 frame reports */
const __u8 uclogic_rdesc_buttonpad_v2_arr[] = { const __u8 uclogic_rdesc_v2_frame_arr[] = {
UCLOGIC_RDESC_BUTTONPAD_BYTES(52) UCLOGIC_RDESC_FRAME_BYTES(UCLOGIC_RDESC_V2_FRAME_ID, 12)
}; };
const size_t uclogic_rdesc_buttonpad_v2_size = const size_t uclogic_rdesc_v2_frame_size =
sizeof(uclogic_rdesc_buttonpad_v2_arr); sizeof(uclogic_rdesc_v2_frame_arr);
/* Fixed report descriptor for Ugee EX07 buttonpad */ /* Fixed report descriptor for Ugee EX07 frame */
const __u8 uclogic_rdesc_ugee_ex07_buttonpad_arr[] = { const __u8 uclogic_rdesc_ugee_ex07_frame_arr[] = {
0x05, 0x01, /* Usage Page (Desktop), */ 0x05, 0x01, /* Usage Page (Desktop), */
0x09, 0x07, /* Usage (Keypad), */ 0x09, 0x07, /* Usage (Keypad), */
0xA1, 0x01, /* Collection (Application), */ 0xA1, 0x01, /* Collection (Application), */
...@@ -725,8 +736,8 @@ const __u8 uclogic_rdesc_ugee_ex07_buttonpad_arr[] = { ...@@ -725,8 +736,8 @@ const __u8 uclogic_rdesc_ugee_ex07_buttonpad_arr[] = {
0xC0, /* End Collection, */ 0xC0, /* End Collection, */
0xC0 /* End Collection */ 0xC0 /* End Collection */
}; };
const size_t uclogic_rdesc_ugee_ex07_buttonpad_size = const size_t uclogic_rdesc_ugee_ex07_frame_size =
sizeof(uclogic_rdesc_ugee_ex07_buttonpad_arr); sizeof(uclogic_rdesc_ugee_ex07_frame_arr);
/* Fixed report descriptor for Ugee G5 frame controls */ /* Fixed report descriptor for Ugee G5 frame controls */
const __u8 uclogic_rdesc_ugee_g5_frame_arr[] = { const __u8 uclogic_rdesc_ugee_g5_frame_arr[] = {
......
...@@ -104,36 +104,36 @@ enum uclogic_rdesc_pen_ph_id { ...@@ -104,36 +104,36 @@ enum uclogic_rdesc_pen_ph_id {
UCLOGIC_RDESC_PH_HEAD, UCLOGIC_RDESC_PEN_PH_ID_##_ID UCLOGIC_RDESC_PH_HEAD, UCLOGIC_RDESC_PEN_PH_ID_##_ID
/* Report ID for v1 pen reports */ /* Report ID for v1 pen reports */
#define UCLOGIC_RDESC_PEN_V1_ID 0x07 #define UCLOGIC_RDESC_V1_PEN_ID 0x07
/* Fixed report descriptor template for (tweaked) v1 pen reports */ /* Fixed report descriptor template for (tweaked) v1 pen reports */
extern const __u8 uclogic_rdesc_pen_v1_template_arr[]; extern const __u8 uclogic_rdesc_v1_pen_template_arr[];
extern const size_t uclogic_rdesc_pen_v1_template_size; extern const size_t uclogic_rdesc_v1_pen_template_size;
/* Report ID for v2 pen reports */ /* Report ID for v2 pen reports */
#define UCLOGIC_RDESC_PEN_V2_ID 0x08 #define UCLOGIC_RDESC_V2_PEN_ID 0x08
/* Fixed report descriptor template for (tweaked) v2 pen reports */ /* Fixed report descriptor template for (tweaked) v2 pen reports */
extern const __u8 uclogic_rdesc_pen_v2_template_arr[]; extern const __u8 uclogic_rdesc_v2_pen_template_arr[];
extern const size_t uclogic_rdesc_pen_v2_template_size; extern const size_t uclogic_rdesc_v2_pen_template_size;
/* Fixed report descriptor for (tweaked) v1 buttonpad reports */ /* Report ID for tweaked v1 frame reports */
extern const __u8 uclogic_rdesc_buttonpad_v1_arr[]; #define UCLOGIC_RDESC_V1_FRAME_ID 0xf7
extern const size_t uclogic_rdesc_buttonpad_v1_size;
/* Report ID for tweaked v1 buttonpad reports */ /* Fixed report descriptor for (tweaked) v1 frame reports */
#define UCLOGIC_RDESC_BUTTONPAD_V1_ID 0xf7 extern const __u8 uclogic_rdesc_v1_frame_arr[];
extern const size_t uclogic_rdesc_v1_frame_size;
/* Fixed report descriptor for (tweaked) v2 buttonpad reports */ /* Report ID for tweaked v2 frame reports */
extern const __u8 uclogic_rdesc_buttonpad_v2_arr[]; #define UCLOGIC_RDESC_V2_FRAME_ID 0xf7
extern const size_t uclogic_rdesc_buttonpad_v2_size;
/* Report ID for tweaked v2 buttonpad reports */ /* Fixed report descriptor for (tweaked) v2 frame reports */
#define UCLOGIC_RDESC_BUTTONPAD_V2_ID 0xf7 extern const __u8 uclogic_rdesc_v2_frame_arr[];
extern const size_t uclogic_rdesc_v2_frame_size;
/* Fixed report descriptor for Ugee EX07 buttonpad */ /* Fixed report descriptor for Ugee EX07 frame */
extern const __u8 uclogic_rdesc_ugee_ex07_buttonpad_arr[]; extern const __u8 uclogic_rdesc_ugee_ex07_frame_arr[];
extern const size_t uclogic_rdesc_ugee_ex07_buttonpad_size; extern const size_t uclogic_rdesc_ugee_ex07_frame_size;
/* Fixed report descriptor for XP-Pen Deco 01 frame controls */ /* Fixed report descriptor for XP-Pen Deco 01 frame controls */
extern const __u8 uclogic_rdesc_xppen_deco01_frame_arr[]; extern const __u8 uclogic_rdesc_xppen_deco01_frame_arr[];
......
This diff is collapsed.
...@@ -661,21 +661,12 @@ static int ish_fw_xfer_direct_dma(struct ishtp_cl_data *client_data, ...@@ -661,21 +661,12 @@ static int ish_fw_xfer_direct_dma(struct ishtp_cl_data *client_data,
*/ */
payload_max_size &= ~(L1_CACHE_BYTES - 1); payload_max_size &= ~(L1_CACHE_BYTES - 1);
dma_buf = kmalloc(payload_max_size, GFP_KERNEL | GFP_DMA32); dma_buf = dma_alloc_coherent(devc, payload_max_size, &dma_buf_phy, GFP_KERNEL);
if (!dma_buf) { if (!dma_buf) {
client_data->flag_retry = true; client_data->flag_retry = true;
return -ENOMEM; return -ENOMEM;
} }
dma_buf_phy = dma_map_single(devc, dma_buf, payload_max_size,
DMA_TO_DEVICE);
if (dma_mapping_error(devc, dma_buf_phy)) {
dev_err(cl_data_to_dev(client_data), "DMA map failed\n");
client_data->flag_retry = true;
rv = -ENOMEM;
goto end_err_dma_buf_release;
}
ldr_xfer_dma_frag.fragment.hdr.command = LOADER_CMD_XFER_FRAGMENT; ldr_xfer_dma_frag.fragment.hdr.command = LOADER_CMD_XFER_FRAGMENT;
ldr_xfer_dma_frag.fragment.xfer_mode = LOADER_XFER_MODE_DIRECT_DMA; ldr_xfer_dma_frag.fragment.xfer_mode = LOADER_XFER_MODE_DIRECT_DMA;
ldr_xfer_dma_frag.ddr_phys_addr = (u64)dma_buf_phy; ldr_xfer_dma_frag.ddr_phys_addr = (u64)dma_buf_phy;
...@@ -695,14 +686,7 @@ static int ish_fw_xfer_direct_dma(struct ishtp_cl_data *client_data, ...@@ -695,14 +686,7 @@ static int ish_fw_xfer_direct_dma(struct ishtp_cl_data *client_data,
ldr_xfer_dma_frag.fragment.size = fragment_size; ldr_xfer_dma_frag.fragment.size = fragment_size;
memcpy(dma_buf, &fw->data[fragment_offset], fragment_size); memcpy(dma_buf, &fw->data[fragment_offset], fragment_size);
dma_sync_single_for_device(devc, dma_buf_phy, /* Flush cache to be sure the data is in main memory. */
payload_max_size,
DMA_TO_DEVICE);
/*
* Flush cache here because the dma_sync_single_for_device()
* does not do for x86.
*/
clflush_cache_range(dma_buf, payload_max_size); clflush_cache_range(dma_buf, payload_max_size);
dev_dbg(cl_data_to_dev(client_data), dev_dbg(cl_data_to_dev(client_data),
...@@ -725,15 +709,8 @@ static int ish_fw_xfer_direct_dma(struct ishtp_cl_data *client_data, ...@@ -725,15 +709,8 @@ static int ish_fw_xfer_direct_dma(struct ishtp_cl_data *client_data,
fragment_offset += fragment_size; fragment_offset += fragment_size;
} }
dma_unmap_single(devc, dma_buf_phy, payload_max_size, DMA_TO_DEVICE);
kfree(dma_buf);
return 0;
end_err_resp_buf_release: end_err_resp_buf_release:
/* Free ISH buffer if not done already, in error case */ dma_free_coherent(devc, payload_max_size, dma_buf, dma_buf_phy);
dma_unmap_single(devc, dma_buf_phy, payload_max_size, DMA_TO_DEVICE);
end_err_dma_buf_release:
kfree(dma_buf);
return rv; return rv;
} }
......
...@@ -342,12 +342,12 @@ struct hid_item { ...@@ -342,12 +342,12 @@ struct hid_item {
* HID device quirks. * HID device quirks.
*/ */
/* /*
* Increase this if you need to configure more HID quirks at module load time * Increase this if you need to configure more HID quirks at module load time
*/ */
#define MAX_USBHID_BOOT_QUIRKS 4 #define MAX_USBHID_BOOT_QUIRKS 4
#define HID_QUIRK_INVERT BIT(0) /* BIT(0) reserved for backward compatibility, was HID_QUIRK_INVERT */
#define HID_QUIRK_NOTOUCH BIT(1) #define HID_QUIRK_NOTOUCH BIT(1)
#define HID_QUIRK_IGNORE BIT(2) #define HID_QUIRK_IGNORE BIT(2)
#define HID_QUIRK_NOGET BIT(3) #define HID_QUIRK_NOGET BIT(3)
...@@ -476,31 +476,50 @@ struct hid_field { ...@@ -476,31 +476,50 @@ struct hid_field {
unsigned report_count; /* number of this field in the report */ unsigned report_count; /* number of this field in the report */
unsigned report_type; /* (input,output,feature) */ unsigned report_type; /* (input,output,feature) */
__s32 *value; /* last known value(s) */ __s32 *value; /* last known value(s) */
__s32 *new_value; /* newly read value(s) */
__s32 *usages_priorities; /* priority of each usage when reading the report
* bits 8-16 are reserved for hid-input usage
*/
__s32 logical_minimum; __s32 logical_minimum;
__s32 logical_maximum; __s32 logical_maximum;
__s32 physical_minimum; __s32 physical_minimum;
__s32 physical_maximum; __s32 physical_maximum;
__s32 unit_exponent; __s32 unit_exponent;
unsigned unit; unsigned unit;
bool ignored; /* this field is ignored in this event */
struct hid_report *report; /* associated report */ struct hid_report *report; /* associated report */
unsigned index; /* index into report->field[] */ unsigned index; /* index into report->field[] */
/* hidinput data */ /* hidinput data */
struct hid_input *hidinput; /* associated input structure */ struct hid_input *hidinput; /* associated input structure */
__u16 dpad; /* dpad input code */ __u16 dpad; /* dpad input code */
unsigned int slot_idx; /* slot index in a report */
}; };
#define HID_MAX_FIELDS 256 #define HID_MAX_FIELDS 256
struct hid_field_entry {
struct list_head list;
struct hid_field *field;
unsigned int index;
__s32 priority;
};
struct hid_report { struct hid_report {
struct list_head list; struct list_head list;
struct list_head hidinput_list; struct list_head hidinput_list;
struct list_head field_entry_list; /* ordered list of input fields */
unsigned int id; /* id of this report */ unsigned int id; /* id of this report */
unsigned int type; /* report type */ unsigned int type; /* report type */
unsigned int application; /* application usage for this report */ unsigned int application; /* application usage for this report */
struct hid_field *field[HID_MAX_FIELDS]; /* fields of the report */ struct hid_field *field[HID_MAX_FIELDS]; /* fields of the report */
struct hid_field_entry *field_entries; /* allocated memory of input field_entry */
unsigned maxfield; /* maximum valid field index */ unsigned maxfield; /* maximum valid field index */
unsigned size; /* size of the report (bits) */ unsigned size; /* size of the report (bits) */
struct hid_device *device; /* associated device */ struct hid_device *device; /* associated device */
/* tool related state */
bool tool_active; /* whether the current tool is active */
unsigned int tool; /* BTN_TOOL_* */
}; };
#define HID_MAX_IDS 256 #define HID_MAX_IDS 256
......
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