Skip to content

Commit

Permalink
Merge tag 'for-linus-2022052401' of git://git.kernel.org/pub/scm/linu…
Browse files Browse the repository at this point in the history
…x/kernel/git/hid/hid

Pull HID updates from Jiri Kosina:

 - support for pens with 3 buttons with Wacom driver (Joshua Dickens)

 - support for HID_DG_SCANTIME to report the timestamp for pen and touch
   events in Wacom driver (Joshua Dickens)

 - support for sensor discovery in amd-sfh driver (Basavaraj Natikar)

 - support for wider variety of Huion tablets ported from DIGImend
   project (José Expósito, Nikolai Kondrashov)

 - new device IDs and other assorted small code cleanups

* tag 'for-linus-2022052401' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (44 commits)
  HID: apple: Properly handle function keys on Keychron keyboards
  HID: uclogic: Switch to Digitizer usage for styluses
  HID: uclogic: Add pen support for XP-PEN Star 06
  HID: uclogic: Differentiate touch ring and touch strip
  HID: uclogic: Always shift touch reports to zero
  HID: uclogic: Do not focus on touch ring only
  HID: uclogic: Return raw parameters from v2 pen init
  HID: uclogic: Move param printing to a function
  HID: core: Display "SENSOR HUB" for sensor hub bus string in hid_info
  HID: amd_sfh: Move bus declaration outside of amd-sfh
  HID: amd_sfh: Add physical location to HID device
  HID: amd_sfh: Modify the hid name
  HID: amd_sfh: Modify the bus name
  HID: amd_sfh: Add sensor name by index for debug info
  HID: amd_sfh: Add support for sensor discovery
  HID: bigben: fix slab-out-of-bounds Write in bigben_probe
  Hid: wacom: Fix kernel test robot warning
  HID: uclogic: Disable pen usage for Huion keyboard interfaces
  HID: uclogic: Support disabling pen usage
  HID: uclogic: Pass keyboard reports as is
  ...
  • Loading branch information
Linus Torvalds committed May 24, 2022
2 parents d8e0f97 + 07d1721 commit aa051d3
Show file tree
Hide file tree
Showing 31 changed files with 1,054 additions and 188 deletions.
9 changes: 8 additions & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -1044,7 +1044,6 @@ F: arch/arm64/boot/dts/amd/amd-seattle-xgbe*.dtsi
F: drivers/net/ethernet/amd/xgbe/

AMD SENSOR FUSION HUB DRIVER
M: Nehal Shah <nehal-bakulchandra.shah@amd.com>
M: Basavaraj Natikar <basavaraj.natikar@amd.com>
L: linux-input@vger.kernel.org
S: Maintained
Expand Down Expand Up @@ -8766,6 +8765,14 @@ F: drivers/hid/hid-sensor-*
F: drivers/iio/*/hid-*
F: include/linux/hid-sensor-*

HID WACOM DRIVER
M: Ping Cheng <ping.cheng@wacom.com>
M: Jason Gerecke <jason.gerecke@wacom.com>
L: linux-input@vger.kernel.org
S: Maintained
F: drivers/hid/wacom.h
F: drivers/hid/wacom_*

HIGH-RESOLUTION TIMERS, CLOCKEVENTS
M: Thomas Gleixner <tglx@linutronix.de>
L: linux-kernel@vger.kernel.org
Expand Down
8 changes: 8 additions & 0 deletions drivers/hid/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,14 @@ config HID_MAYFLASH
Say Y here if you have HJZ Mayflash PS3 game controller adapters
and want to enable force feedback support.

config HID_MEGAWORLD_FF
tristate "Mega World based game controller force feedback support"
depends on USB_HID
select INPUT_FF_MEMLESS
help
Say Y here if you have a Mega World based game controller and want
to have force feedback support for it.

config HID_REDRAGON
tristate "Redragon keyboards"
depends on HID
Expand Down
1 change: 1 addition & 0 deletions drivers/hid/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o
obj-$(CONFIG_HID_MALTRON) += hid-maltron.o
obj-$(CONFIG_HID_MCP2221) += hid-mcp2221.o
obj-$(CONFIG_HID_MAYFLASH) += hid-mf.o
obj-$(CONFIG_HID_MEGAWORLD_FF) += hid-megaworld.o
obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o
obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o
obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o
Expand Down
45 changes: 39 additions & 6 deletions drivers/hid/amd-sfh-hid/amd_sfh_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,24 @@ u32 amd_sfh_wait_for_response(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts)
return sensor_sts;
}

const char *get_sensor_name(int idx)
{
switch (idx) {
case accel_idx:
return "accelerometer";
case gyro_idx:
return "gyroscope";
case mag_idx:
return "magnetometer";
case als_idx:
return "ALS";
case HPD_IDX:
return "HPD";
default:
return "unknown sensor type";
}
}

int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
{
struct amd_input_data *in_data = &privdata->in_data;
Expand Down Expand Up @@ -219,13 +237,27 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
(privdata, cl_data->sensor_idx[i], SENSOR_DISABLED);
if (status != SENSOR_ENABLED)
cl_data->sensor_sts[i] = SENSOR_DISABLED;
dev_dbg(dev, "sid 0x%x status 0x%x\n",
cl_data->sensor_idx[i], cl_data->sensor_sts[i]);
dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n",
cl_data->sensor_idx[i],
get_sensor_name(cl_data->sensor_idx[i]),
cl_data->sensor_sts[i]);
goto cleanup;
}
}
dev_dbg(dev, "sid 0x%x status 0x%x\n",
cl_data->sensor_idx[i], cl_data->sensor_sts[i]);
dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n",
cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]),
cl_data->sensor_sts[i]);
}
if (privdata->mp2_ops->discovery_status &&
privdata->mp2_ops->discovery_status(privdata) == 0) {
amd_sfh_hid_client_deinit(privdata);
for (i = 0; i < cl_data->num_hid_devices; i++) {
devm_kfree(dev, cl_data->feature_report[i]);
devm_kfree(dev, in_data->input_report[i]);
devm_kfree(dev, cl_data->report_descr[i]);
}
dev_warn(dev, "Failed to discover, sensors not enabled\n");
return -EOPNOTSUPP;
}
schedule_delayed_work(&cl_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP));
return 0;
Expand Down Expand Up @@ -257,8 +289,9 @@ int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata)
(privdata, cl_data->sensor_idx[i], SENSOR_DISABLED);
if (status != SENSOR_ENABLED)
cl_data->sensor_sts[i] = SENSOR_DISABLED;
dev_dbg(&privdata->pdev->dev, "stopping sid 0x%x status 0x%x\n",
cl_data->sensor_idx[i], cl_data->sensor_sts[i]);
dev_dbg(&privdata->pdev->dev, "stopping sid 0x%x (%s) status 0x%x\n",
cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]),
cl_data->sensor_sts[i]);
}
}

Expand Down
9 changes: 7 additions & 2 deletions drivers/hid/amd-sfh-hid/amd_sfh_hid.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <linux/sched.h>

#include "amd_sfh_hid.h"
#include "amd_sfh_pcie.h"

#define AMD_SFH_RESPONSE_TIMEOUT 1500

Expand Down Expand Up @@ -120,6 +121,8 @@ static struct hid_ll_driver amdtp_hid_ll_driver = {

int amdtp_hid_probe(u32 cur_hid_dev, struct amdtp_cl_data *cli_data)
{
struct amd_mp2_dev *mp2 = container_of(cli_data->in_data, struct amd_mp2_dev, in_data);
struct device *dev = &mp2->pdev->dev;
struct hid_device *hid;
struct amdtp_hid_data *hid_data;
int rc;
Expand All @@ -141,10 +144,12 @@ int amdtp_hid_probe(u32 cur_hid_dev, struct amdtp_cl_data *cli_data)

hid->driver_data = hid_data;
cli_data->hid_sensor_hubs[cur_hid_dev] = hid;
hid->bus = BUS_AMD_AMDTP;
strscpy(hid->phys, dev->driver ? dev->driver->name : dev_name(dev),
sizeof(hid->phys));
hid->bus = BUS_AMD_SFH;
hid->vendor = AMD_SFH_HID_VENDOR;
hid->product = AMD_SFH_HID_PRODUCT;
snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "hid-amdtp",
snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "hid-amdsfh",
hid->vendor, hid->product);

rc = hid_add_device(hid);
Expand Down
1 change: 0 additions & 1 deletion drivers/hid/amd-sfh-hid/amd_sfh_hid.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#define AMDSFH_HID_H

#define MAX_HID_DEVICES 5
#define BUS_AMD_AMDTP 0x20
#define AMD_SFH_HID_VENDOR 0x1022
#define AMD_SFH_HID_PRODUCT 0x0001

Expand Down
17 changes: 13 additions & 4 deletions drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,12 @@ static int amd_sfh_irq_init_v2(struct amd_mp2_dev *privdata)
return 0;
}

static int amd_sfh_dis_sts_v2(struct amd_mp2_dev *privdata)
{
return (readl(privdata->mmio + AMD_P2C_MSG(1)) &
SENSOR_DISCOVERY_STATUS_MASK) >> SENSOR_DISCOVERY_STATUS_SHIFT;
}

void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info)
{
union sfh_cmd_param cmd_param;
Expand Down Expand Up @@ -245,6 +251,7 @@ static const struct amd_mp2_ops amd_sfh_ops_v2 = {
.response = amd_sfh_wait_response_v2,
.clear_intr = amd_sfh_clear_intr_v2,
.init_intr = amd_sfh_irq_init_v2,
.discovery_status = amd_sfh_dis_sts_v2,
};

static const struct amd_mp2_ops amd_sfh_ops = {
Expand Down Expand Up @@ -346,8 +353,9 @@ static int __maybe_unused amd_mp2_pci_resume(struct device *dev)
(mp2, cl_data->sensor_idx[i], SENSOR_ENABLED);
if (status == SENSOR_ENABLED)
cl_data->sensor_sts[i] = SENSOR_ENABLED;
dev_dbg(dev, "resume sid 0x%x status 0x%x\n",
cl_data->sensor_idx[i], cl_data->sensor_sts[i]);
dev_dbg(dev, "suspend sid 0x%x (%s) status 0x%x\n",
cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]),
cl_data->sensor_sts[i]);
}
}

Expand All @@ -371,8 +379,9 @@ static int __maybe_unused amd_mp2_pci_suspend(struct device *dev)
(mp2, cl_data->sensor_idx[i], SENSOR_DISABLED);
if (status != SENSOR_ENABLED)
cl_data->sensor_sts[i] = SENSOR_DISABLED;
dev_dbg(dev, "suspend sid 0x%x status 0x%x\n",
cl_data->sensor_idx[i], cl_data->sensor_sts[i]);
dev_dbg(dev, "suspend sid 0x%x (%s) status 0x%x\n",
cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]),
cl_data->sensor_sts[i]);
}
}

Expand Down
5 changes: 5 additions & 0 deletions drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@

#define AMD_SFH_IDLE_LOOP 200

#define SENSOR_DISCOVERY_STATUS_MASK GENMASK(5, 3)
#define SENSOR_DISCOVERY_STATUS_SHIFT 3

/* SFH Command register */
union sfh_cmd_base {
u32 ul;
Expand Down Expand Up @@ -135,6 +138,7 @@ int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata);
u32 amd_sfh_wait_for_response(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts);
void amd_mp2_suspend(struct amd_mp2_dev *mp2);
void amd_mp2_resume(struct amd_mp2_dev *mp2);
const char *get_sensor_name(int idx);

struct amd_mp2_ops {
void (*start)(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info);
Expand All @@ -143,5 +147,6 @@ struct amd_mp2_ops {
int (*response)(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts);
void (*clear_intr)(struct amd_mp2_dev *privdata);
int (*init_intr)(struct amd_mp2_dev *privdata);
int (*discovery_status)(struct amd_mp2_dev *privdata);
};
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ static const u8 accel3_report_descriptor[] = {
0xC0 /* HID end collection */
};

const u8 gyro3_report_descriptor[] = {
static const u8 gyro3_report_descriptor[] = {
0x05, 0x20, /* Usage page */
0x09, 0x76, /* Motion type Gyro3D */
0xA1, 0x00, /* HID Collection (Physical) */
Expand Down Expand Up @@ -340,7 +340,7 @@ const u8 gyro3_report_descriptor[] = {
0xC0, /* HID end collection */
};

const u8 comp3_report_descriptor[] = {
static const u8 comp3_report_descriptor[] = {
0x05, 0x20, /* Usage page */
0x09, 0x83, /* Motion type Orientation compass 3D */
0xA1, 0x00, /* HID Collection (Physical) */
Expand Down Expand Up @@ -512,7 +512,7 @@ const u8 comp3_report_descriptor[] = {
0xC0 /* HID end collection */
};

const u8 als_report_descriptor[] = {
static const u8 als_report_descriptor[] = {
0x05, 0x20, /* HID usage page sensor */
0x09, 0x41, /* HID usage sensor type Ambientlight */
0xA1, 0x00, /* HID Collection (Physical) */
Expand Down
22 changes: 18 additions & 4 deletions drivers/hid/hid-apple.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/string.h>

#include "hid-ids.h"

Expand All @@ -35,16 +36,17 @@
#define APPLE_NUMLOCK_EMULATION BIT(8)
#define APPLE_RDESC_BATTERY BIT(9)
#define APPLE_BACKLIGHT_CTL BIT(10)
#define APPLE_IS_KEYCHRON BIT(11)

#define APPLE_FLAG_FKEY 0x01

#define HID_COUNTRY_INTERNATIONAL_ISO 13
#define APPLE_BATTERY_TIMEOUT_MS 60000

static unsigned int fnmode = 1;
static unsigned int fnmode = 3;
module_param(fnmode, uint, 0644);
MODULE_PARM_DESC(fnmode, "Mode of fn key on Apple keyboards (0 = disabled, "
"[1] = fkeyslast, 2 = fkeysfirst)");
"1 = fkeyslast, 2 = fkeysfirst, [3] = auto)");

static int iso_layout = -1;
module_param(iso_layout, int, 0644);
Expand Down Expand Up @@ -349,6 +351,7 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
const struct apple_key_translation *trans, *table;
bool do_translate;
u16 code = 0;
unsigned int real_fnmode;

u16 fn_keycode = (swap_fn_leftctrl) ? (KEY_LEFTCTRL) : (KEY_FN);

Expand All @@ -359,7 +362,13 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
return 1;
}

if (fnmode) {
if (fnmode == 3) {
real_fnmode = (asc->quirks & APPLE_IS_KEYCHRON) ? 2 : 1;
} else {
real_fnmode = fnmode;
}

if (real_fnmode) {
if (hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI ||
hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO ||
hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS ||
Expand Down Expand Up @@ -406,7 +415,7 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,

if (!code) {
if (trans->flags & APPLE_FLAG_FKEY) {
switch (fnmode) {
switch (real_fnmode) {
case 1:
do_translate = !asc->fn_on;
break;
Expand Down Expand Up @@ -660,6 +669,11 @@ static int apple_input_configured(struct hid_device *hdev,
asc->quirks &= ~APPLE_HAS_FN;
}

if (strncmp(hdev->name, "Keychron", 8) == 0) {
hid_info(hdev, "Keychron keyboard detected; function keys will default to fnmode=2 behavior\n");
asc->quirks |= APPLE_IS_KEYCHRON;
}

return 0;
}

Expand Down
6 changes: 6 additions & 0 deletions drivers/hid/hid-bigbenff.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,12 @@ static int bigben_probe(struct hid_device *hid,
bigben->report = list_entry(report_list->next,
struct hid_report, list);

if (list_empty(&hid->inputs)) {
hid_err(hid, "no inputs found\n");
error = -ENODEV;
goto error_hw_stop;
}

hidinput = list_first_entry(&hid->inputs, struct hid_input, list);
set_bit(FF_RUMBLE, hidinput->input->ffbit);

Expand Down
4 changes: 4 additions & 0 deletions drivers/hid/hid-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2222,6 +2222,10 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
case BUS_VIRTUAL:
bus = "VIRTUAL";
break;
case BUS_INTEL_ISHTP:
case BUS_AMD_SFH:
bus = "SENSOR HUB";
break;
default:
bus = "<UNKNOWN>";
}
Expand Down
2 changes: 0 additions & 2 deletions drivers/hid/hid-elan.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ static int elan_input_configured(struct hid_device *hdev, struct hid_input *hi)
ret = input_mt_init_slots(input, ELAN_MAX_FINGERS, INPUT_MT_POINTER);
if (ret) {
hid_err(hdev, "Failed to init elan MT slots: %d\n", ret);
input_free_device(input);
return ret;
}

Expand All @@ -200,7 +199,6 @@ static int elan_input_configured(struct hid_device *hdev, struct hid_input *hi)
hid_err(hdev, "Failed to register elan input device: %d\n",
ret);
input_mt_destroy_slots(input);
input_free_device(input);
return ret;
}

Expand Down
7 changes: 7 additions & 0 deletions drivers/hid/hid-ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -761,13 +761,16 @@
#define USB_VENDOR_ID_LENOVO 0x17ef
#define USB_DEVICE_ID_LENOVO_TPKBD 0x6009
#define USB_DEVICE_ID_LENOVO_CUSBKBD 0x6047
#define USB_DEVICE_ID_LENOVO_TPIIUSBKBD 0x60ee
#define USB_DEVICE_ID_LENOVO_CBTKBD 0x6048
#define USB_DEVICE_ID_LENOVO_TPIIBTKBD 0x60e1
#define USB_DEVICE_ID_LENOVO_SCROLLPOINT_OPTICAL 0x6049
#define USB_DEVICE_ID_LENOVO_TP10UBKBD 0x6062
#define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067
#define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085
#define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3
#define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5
#define USB_DEVICE_ID_LENOVO_X12_TAB 0x60fe
#define USB_DEVICE_ID_LENOVO_OPTICAL_USB_MOUSE_600E 0x600e
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019 0x6019
Expand Down Expand Up @@ -868,6 +871,9 @@
#define USB_VENDOR_ID_MCS 0x16d0
#define USB_DEVICE_ID_MCS_GAMEPADBLOCK 0x0bcc

#define USB_VENDOR_MEGAWORLD 0x07b5
#define USB_DEVICE_ID_MEGAWORLD_GAMEPAD 0x0312

#define USB_VENDOR_ID_MGE 0x0463
#define USB_DEVICE_ID_MGE_UPS 0xffff
#define USB_DEVICE_ID_MGE_UPS1 0x0001
Expand Down Expand Up @@ -1272,6 +1278,7 @@
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_G540 0x0075
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_G640 0x0094
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01 0x0042
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06 0x0078
#define USB_DEVICE_ID_UGEE_TABLET_G5 0x0074
#define USB_DEVICE_ID_UGEE_TABLET_EX07S 0x0071
#define USB_DEVICE_ID_UGEE_TABLET_RAINBOW_CV720 0x0055
Expand Down
Loading

0 comments on commit aa051d3

Please sign in to comment.