Skip to content

Commit

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

Pull HID updates from Jiri Kosina:
 "Highlights:

   - support for USI style pens (Tero Kristo, Mika Westerberg)

   - quirk for devices that need inverted X/Y axes (Alistair Francis)

   - small core code cleanups and deduplication (Benjamin Tissoires)

   - Apple Magic Keyboard support improvements (José Expósito, Alex
     Henrie, Benjamin Berg)

   - locking performance improvement for hidraw code (André Almeida)

   - PM wakeup support for i2c-hid driver (Matthias Kaehlcke

   - new driver to support for LetSketch device (Hans de Goede)

   - proper batter reporting for hid-magicmouse USB-connected devices
     (José Expósito)"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (32 commits)
  HID: magicmouse: Fix an error handling path in magicmouse_probe()
  HID: address kernel-doc warnings
  HID: intel-ish-hid: ishtp-fw-loader: Fix a kernel-doc formatting issue
  HID: intel-ish-hid: ipc: Specify no cache snooping on TGL and ADL
  HID: hid-uclogic-params: Invalid parameter check in uclogic_params_frame_init_v1_buttonpad
  HID: hid-uclogic-params: Invalid parameter check in uclogic_params_huion_init
  HID: hid-uclogic-params: Invalid parameter check in uclogic_params_get_str_desc
  HID: hid-uclogic-params: Invalid parameter check in uclogic_params_init
  HID: Add new Letsketch tablet driver
  HID: apple: Add Magic Keyboard 2021 with fingerprint reader FN key mapping
  HID: apple: Add 2021 magic keyboard FN key mapping
  HID: magicmouse: set Magic Trackpad 2021 name
  HID: magicmouse: set device name when it has been personalized
  HID: apple: Add 2021 Magic Keyboard with number pad
  HID: apple: Add 2021 Magic Keyboard with fingerprint reader
  HID: i2c-hid-of: Expose the touchscreen-inverted properties
  HID: quirks: Allow inverting the absolute X/Y values
  HID: hidraw: Replace hidraw device table mutex with a rwsem
  HID: thrustmaster use swap() to make code cleaner
  HID: debug: Add USI usages
  ...
  • Loading branch information
Linus Torvalds committed Jan 11, 2022
2 parents 4a11090 + cd598d2 commit 26b88fb
Show file tree
Hide file tree
Showing 26 changed files with 863 additions and 178 deletions.
2 changes: 2 additions & 0 deletions Documentation/devicetree/bindings/input/hid-over-i2c.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ device-specific compatible properties, which should be used in addition to the
- vdd-supply: phandle of the regulator that provides the supply voltage.
- post-power-on-delay-ms: time required by the device after enabling its regulators
or powering it on, before it is ready for communication.
- touchscreen-inverted-x: See touchscreen.txt
- touchscreen-inverted-y: See touchscreen.txt

Example:

Expand Down
13 changes: 13 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -8542,6 +8542,12 @@ F: drivers/hid/
F: include/linux/hid*
F: include/uapi/linux/hid*

HID LOGITECH DRIVERS
R: Filipe Laíns <lains@riseup.net>
L: linux-input@vger.kernel.org
S: Maintained
F: drivers/hid/hid-logitech-*

HID PLAYSTATION DRIVER
M: Roderick Colenbrander <roderick.colenbrander@sony.com>
L: linux-input@vger.kernel.org
Expand Down Expand Up @@ -10804,6 +10810,13 @@ S: Maintained
W: http://legousb.sourceforge.net/
F: drivers/usb/misc/legousbtower.c

LETSKETCH HID TABLET DRIVER
M: Hans de Goede <hdegoede@redhat.com>
L: linux-input@vger.kernel.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git
F: drivers/hid/hid-letsketch.c

LG LAPTOP EXTRAS
M: Matan Ziv-Av <matan@svgalib.org>
L: platform-driver-x86@vger.kernel.org
Expand Down
14 changes: 14 additions & 0 deletions drivers/hid/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,20 @@ config HID_LENOVO
- ThinkPad Compact Bluetooth Keyboard with TrackPoint (supports Fn keys)
- ThinkPad Compact USB Keyboard with TrackPoint (supports Fn keys)

config HID_LETSKETCH
tristate "Letsketch WP9620N tablets"
depends on USB_HID
help
Driver for the LetSketch / VSON WP9620N drawing tablet. This
drawing tablet is also sold under other brand names such as Case U,
presumably this driver will work for all of them. But it has only been
tested with a LetSketch WP9620N model.

These tablets also work without a special HID driver, but then only
part of the active area works and both the pad and stylus buttons are
hardwired to special key-combos. E.g. the 2 stylus buttons send right
mouse clicks / resp. "e" key presses.

config HID_LOGITECH
tristate "Logitech devices"
depends on USB_HID
Expand Down
1 change: 1 addition & 0 deletions drivers/hid/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o
obj-$(CONFIG_HID_KYE) += hid-kye.o
obj-$(CONFIG_HID_LCPOWER) += hid-lcpower.o
obj-$(CONFIG_HID_LENOVO) += hid-lenovo.o
obj-$(CONFIG_HID_LETSKETCH) += hid-letsketch.o
obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o
obj-$(CONFIG_HID_LOGITECH) += hid-lg-g15.o
obj-$(CONFIG_HID_LOGITECH_DJ) += hid-logitech-dj.o
Expand Down
146 changes: 133 additions & 13 deletions drivers/hid/hid-apple.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,28 @@

#include <linux/device.h>
#include <linux/hid.h>
#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/timer.h>

#include "hid-ids.h"

#define APPLE_RDESC_JIS 0x0001
#define APPLE_IGNORE_MOUSE 0x0002
#define APPLE_HAS_FN 0x0004
/* 0x0008 reserved, was: APPLE_HIDDEV */
#define APPLE_ISO_TILDE_QUIRK 0x0010
#define APPLE_MIGHTYMOUSE 0x0020
#define APPLE_INVERT_HWHEEL 0x0040
/* 0x0080 reserved, was: APPLE_IGNORE_HIDINPUT */
#define APPLE_NUMLOCK_EMULATION 0x0100
#define APPLE_RDESC_JIS BIT(0)
#define APPLE_IGNORE_MOUSE BIT(1)
#define APPLE_HAS_FN BIT(2)
/* BIT(3) reserved, was: APPLE_HIDDEV */
#define APPLE_ISO_TILDE_QUIRK BIT(4)
#define APPLE_MIGHTYMOUSE BIT(5)
#define APPLE_INVERT_HWHEEL BIT(6)
/* BIT(7) reserved, was: APPLE_IGNORE_HIDINPUT */
#define APPLE_NUMLOCK_EMULATION BIT(8)
#define APPLE_RDESC_BATTERY BIT(9)

#define APPLE_FLAG_FKEY 0x01

#define HID_COUNTRY_INTERNATIONAL_ISO 13
#define APPLE_BATTERY_TIMEOUT_MS 60000

static unsigned int fnmode = 1;
module_param(fnmode, uint, 0644);
Expand All @@ -58,10 +62,12 @@ MODULE_PARM_DESC(swap_fn_leftctrl, "Swap the Fn and left Control keys. "
"[0] = as-is, Mac layout, 1 = swapped, PC layout)");

struct apple_sc {
struct hid_device *hdev;
unsigned long quirks;
unsigned int fn_on;
unsigned int fn_found;
DECLARE_BITMAP(pressed_numlock, KEY_CNT);
struct timer_list battery_timer;
};

struct apple_key_translation {
Expand All @@ -70,6 +76,28 @@ struct apple_key_translation {
u8 flags;
};

static const struct apple_key_translation apple2021_fn_keys[] = {
{ KEY_BACKSPACE, KEY_DELETE },
{ KEY_ENTER, KEY_INSERT },
{ KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
{ KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
{ KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY },
{ KEY_F4, KEY_SEARCH, APPLE_FLAG_FKEY },
{ KEY_F5, KEY_MICMUTE, APPLE_FLAG_FKEY },
{ KEY_F6, KEY_SLEEP, APPLE_FLAG_FKEY },
{ KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY },
{ KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY },
{ KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY },
{ KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY },
{ KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
{ KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
{ KEY_UP, KEY_PAGEUP },
{ KEY_DOWN, KEY_PAGEDOWN },
{ KEY_LEFT, KEY_HOME },
{ KEY_RIGHT, KEY_END },
{ }
};

static const struct apple_key_translation macbookair_fn_keys[] = {
{ KEY_BACKSPACE, KEY_DELETE },
{ KEY_ENTER, KEY_INSERT },
Expand Down Expand Up @@ -214,7 +242,11 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
}

if (fnmode) {
if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI &&
if (hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021 ||
hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021 ||
hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021)
table = apple2021_fn_keys;
else if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI &&
hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS)
table = macbookair_fn_keys;
else if (hid->product < 0x21d || hid->product >= 0x300)
Expand Down Expand Up @@ -333,6 +365,43 @@ static int apple_event(struct hid_device *hdev, struct hid_field *field,
return 0;
}

static int apple_fetch_battery(struct hid_device *hdev)
{
#ifdef CONFIG_HID_BATTERY_STRENGTH
struct apple_sc *asc = hid_get_drvdata(hdev);
struct hid_report_enum *report_enum;
struct hid_report *report;

if (!(asc->quirks & APPLE_RDESC_BATTERY) || !hdev->battery)
return -1;

report_enum = &hdev->report_enum[hdev->battery_report_type];
report = report_enum->report_id_hash[hdev->battery_report_id];

if (!report || report->maxfield < 1)
return -1;

if (hdev->battery_capacity == hdev->battery_max)
return -1;

hid_hw_request(hdev, report, HID_REQ_GET_REPORT);
return 0;
#else
return -1;
#endif
}

static void apple_battery_timer_tick(struct timer_list *t)
{
struct apple_sc *asc = from_timer(asc, t, battery_timer);
struct hid_device *hdev = asc->hdev;

if (apple_fetch_battery(hdev) == 0) {
mod_timer(&asc->battery_timer,
jiffies + msecs_to_jiffies(APPLE_BATTERY_TIMEOUT_MS));
}
}

/*
* MacBook JIS keyboard has wrong logical maximum
* Magic Keyboard JIS has wrong logical maximum
Expand All @@ -354,6 +423,30 @@ static __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
"fixing up MacBook JIS keyboard report descriptor\n");
rdesc[53] = rdesc[59] = 0xe7;
}

/*
* Change the usage from:
* 0x06, 0x00, 0xff, // Usage Page (Vendor Defined Page 1) 0
* 0x09, 0x0b, // Usage (Vendor Usage 0x0b) 3
* To:
* 0x05, 0x01, // Usage Page (Generic Desktop) 0
* 0x09, 0x06, // Usage (Keyboard) 2
*/
if ((asc->quirks & APPLE_RDESC_BATTERY) && *rsize == 83 &&
rdesc[46] == 0x84 && rdesc[58] == 0x85) {
hid_info(hdev,
"fixing up Magic Keyboard battery report descriptor\n");
*rsize = *rsize - 1;
rdesc = kmemdup(rdesc + 1, *rsize, GFP_KERNEL);
if (!rdesc)
return NULL;

rdesc[0] = 0x05;
rdesc[1] = 0x01;
rdesc[2] = 0x09;
rdesc[3] = 0x06;
}

return rdesc;
}

Expand All @@ -376,6 +469,9 @@ static void apple_setup_input(struct input_dev *input)
for (trans = apple_iso_keyboard; trans->from; trans++)
set_bit(trans->to, input->keybit);

for (trans = apple2021_fn_keys; trans->from; trans++)
set_bit(trans->to, input->keybit);

if (swap_fn_leftctrl) {
for (trans = swapped_fn_leftctrl_keys; trans->from; trans++)
set_bit(trans->to, input->keybit);
Expand Down Expand Up @@ -428,7 +524,7 @@ static int apple_input_configured(struct hid_device *hdev,

if ((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) {
hid_info(hdev, "Fn key not found (Apple Wireless Keyboard clone?), disabling Fn key handling\n");
asc->quirks = 0;
asc->quirks &= ~APPLE_HAS_FN;
}

return 0;
Expand All @@ -447,6 +543,7 @@ static int apple_probe(struct hid_device *hdev,
return -ENOMEM;
}

asc->hdev = hdev;
asc->quirks = quirks;

hid_set_drvdata(hdev, asc);
Expand All @@ -463,9 +560,23 @@ static int apple_probe(struct hid_device *hdev,
return ret;
}

timer_setup(&asc->battery_timer, apple_battery_timer_tick, 0);
mod_timer(&asc->battery_timer,
jiffies + msecs_to_jiffies(APPLE_BATTERY_TIMEOUT_MS));
apple_fetch_battery(hdev);

return 0;
}

static void apple_remove(struct hid_device *hdev)
{
struct apple_sc *asc = hid_get_drvdata(hdev);

del_timer_sync(&asc->battery_timer);

hid_hw_stop(hdev);
}

static const struct hid_device_id apple_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE),
.driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL },
Expand Down Expand Up @@ -540,11 +651,11 @@ static const struct hid_device_id apple_devices[] = {
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
Expand Down Expand Up @@ -640,6 +751,14 @@ static const struct hid_device_id apple_devices[] = {
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021),
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },

{ }
};
Expand All @@ -650,6 +769,7 @@ static struct hid_driver apple_driver = {
.id_table = apple_devices,
.report_fixup = apple_report_fixup,
.probe = apple_probe,
.remove = apple_remove,
.event = apple_event,
.input_mapping = apple_input_mapping,
.input_mapped = apple_input_mapped,
Expand Down
Loading

0 comments on commit 26b88fb

Please sign in to comment.