diff options
author | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2023-02-22 12:27:57 +0300 |
---|---|---|
committer | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2023-02-22 12:27:57 +0300 |
commit | 06db2af35e5f44cebf36c1dc122f5769f630d2f8 (patch) | |
tree | 02830ad872b359dc6972b1c85bbc66b03d283653 /drivers/hid | |
parent | 0b028189d1019ca352da108643b8f1503ee25a0e (diff) | |
parent | 3f16ba1c0768de6cdc6f65105757ef04dbfd8e5c (diff) | |
download | linux-06db2af35e5f44cebf36c1dc122f5769f630d2f8.tar.xz |
Merge branch 'for-6.3/hid-core' into for-linus
- constify hid_ll_driver (Thomas Weißschuh)
- map standard Battery System Charging to upower (José Expósito)
- couple of assorted fixes and new handling of HID usages (Jingyuan
Liang & Ronald Tschalär)
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/.kunitconfig | 1 | ||||
-rw-r--r-- | drivers/hid/Kconfig | 1 | ||||
-rw-r--r-- | drivers/hid/amd-sfh-hid/amd_sfh_hid.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 12 | ||||
-rw-r--r-- | drivers/hid/hid-debug.c | 1 | ||||
-rw-r--r-- | drivers/hid/hid-hyperv.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-input-test.c | 80 | ||||
-rw-r--r-- | drivers/hid/hid-input.c | 44 | ||||
-rw-r--r-- | drivers/hid/hid-letsketch.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-logitech-dj.c | 4 | ||||
-rw-r--r-- | drivers/hid/hid-sensor-hub.c | 6 | ||||
-rw-r--r-- | drivers/hid/hid-steam.c | 2 | ||||
-rw-r--r-- | drivers/hid/i2c-hid/i2c-hid-core.c | 3 | ||||
-rw-r--r-- | drivers/hid/intel-ish-hid/ishtp-hid.c | 2 | ||||
-rw-r--r-- | drivers/hid/surface-hid/surface_hid_core.c | 2 | ||||
-rw-r--r-- | drivers/hid/uhid.c | 3 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 9 |
17 files changed, 148 insertions, 28 deletions
diff --git a/drivers/hid/.kunitconfig b/drivers/hid/.kunitconfig index 04daeff5c970..675a8209c7ae 100644 --- a/drivers/hid/.kunitconfig +++ b/drivers/hid/.kunitconfig @@ -1,5 +1,6 @@ CONFIG_KUNIT=y CONFIG_USB=y CONFIG_USB_HID=y +CONFIG_HID_BATTERY_STRENGTH=y CONFIG_HID_UCLOGIC=y CONFIG_HID_KUNIT_TEST=y diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index e2a5d30c8895..d253b3ff2e0c 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -1264,6 +1264,7 @@ config HID_MCP2221 config HID_KUNIT_TEST tristate "KUnit tests for HID" if !KUNIT_ALL_TESTS depends on KUNIT=y + depends on HID_BATTERY_STRENGTH depends on HID_UCLOGIC default KUNIT_ALL_TESTS help diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c index 1b18291fc5af..705b52337068 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c @@ -112,7 +112,7 @@ void amdtp_hid_wakeup(struct hid_device *hid) } } -static struct hid_ll_driver amdtp_hid_ll_driver = { +static const struct hid_ll_driver amdtp_hid_ll_driver = { .parse = amdtp_hid_parse, .start = amdtp_hid_start, .stop = amdtp_hid_stop, diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 5c72aef3d3dd..53e4d5831caf 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -41,11 +41,6 @@ #define DRIVER_DESC "HID core driver" -int hid_debug = 0; -module_param_named(debug, hid_debug, int, 0600); -MODULE_PARM_DESC(debug, "toggle HID debugging messages"); -EXPORT_SYMBOL_GPL(hid_debug); - static int hid_ignore_special_drivers = 0; module_param_named(ignore_special_drivers, hid_ignore_special_drivers, int, 0600); MODULE_PARM_DESC(ignore_special_drivers, "Ignore any special drivers and handle all devices by generic driver"); @@ -804,7 +799,8 @@ static void hid_scan_collection(struct hid_parser *parser, unsigned type) int i; if (((parser->global.usage_page << 16) == HID_UP_SENSOR) && - type == HID_COLLECTION_PHYSICAL) + (type == HID_COLLECTION_PHYSICAL || + type == HID_COLLECTION_APPLICATION)) hid->group = HID_GROUP_SENSOR_HUB; if (hid->vendor == USB_VENDOR_ID_MICROSOFT && @@ -2912,10 +2908,6 @@ static int __init hid_init(void) { int ret; - if (hid_debug) - pr_warn("hid_debug is now used solely for parser and driver debugging.\n" - "debugfs is now used for inspecting the device (report descriptor, reports)\n"); - ret = bus_register(&hid_bus_type); if (ret) { pr_err("can't register hid bus\n"); diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index e213bdde543a..e7ef1ea107c9 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -975,6 +975,7 @@ static const char *keys[KEY_MAX + 1] = { [KEY_CAMERA_ACCESS_DISABLE] = "CameraAccessDisable", [KEY_CAMERA_ACCESS_TOGGLE] = "CameraAccessToggle", [KEY_DICTATE] = "Dictate", + [KEY_MICMUTE] = "MicrophoneMute", [KEY_BRIGHTNESS_MIN] = "BrightnessMin", [KEY_BRIGHTNESS_MAX] = "BrightnessMax", [KEY_BRIGHTNESS_AUTO] = "BrightnessAuto", diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c index cf12f17e6533..819eb38eb5df 100644 --- a/drivers/hid/hid-hyperv.c +++ b/drivers/hid/hid-hyperv.c @@ -424,7 +424,7 @@ static int mousevsc_hid_raw_request(struct hid_device *hid, return 0; } -static struct hid_ll_driver mousevsc_ll_driver = { +static const struct hid_ll_driver mousevsc_ll_driver = { .parse = mousevsc_hid_parse, .open = mousevsc_hid_open, .close = mousevsc_hid_close, diff --git a/drivers/hid/hid-input-test.c b/drivers/hid/hid-input-test.c new file mode 100644 index 000000000000..77c2d45ac62a --- /dev/null +++ b/drivers/hid/hid-input-test.c @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * HID to Linux Input mapping + * + * Copyright (c) 2022 José Expósito <jose.exposito89@gmail.com> + */ + +#include <kunit/test.h> + +static void hid_test_input_set_battery_charge_status(struct kunit *test) +{ + struct hid_device *dev; + bool handled; + + dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); + + handled = hidinput_set_battery_charge_status(dev, HID_DG_HEIGHT, 0); + KUNIT_EXPECT_FALSE(test, handled); + KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_UNKNOWN); + + handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 0); + KUNIT_EXPECT_TRUE(test, handled); + KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_DISCHARGING); + + handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 1); + KUNIT_EXPECT_TRUE(test, handled); + KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_CHARGING); +} + +static void hid_test_input_get_battery_property(struct kunit *test) +{ + struct power_supply *psy; + struct hid_device *dev; + union power_supply_propval val; + int ret; + + dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); + dev->battery_avoid_query = true; + + psy = kunit_kzalloc(test, sizeof(*psy), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, psy); + psy->drv_data = dev; + + dev->battery_status = HID_BATTERY_UNKNOWN; + dev->battery_charge_status = POWER_SUPPLY_STATUS_CHARGING; + ret = hidinput_get_battery_property(psy, POWER_SUPPLY_PROP_STATUS, &val); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, val.intval, POWER_SUPPLY_STATUS_UNKNOWN); + + dev->battery_status = HID_BATTERY_REPORTED; + dev->battery_charge_status = POWER_SUPPLY_STATUS_CHARGING; + ret = hidinput_get_battery_property(psy, POWER_SUPPLY_PROP_STATUS, &val); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, val.intval, POWER_SUPPLY_STATUS_CHARGING); + + dev->battery_status = HID_BATTERY_REPORTED; + dev->battery_charge_status = POWER_SUPPLY_STATUS_DISCHARGING; + ret = hidinput_get_battery_property(psy, POWER_SUPPLY_PROP_STATUS, &val); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, val.intval, POWER_SUPPLY_STATUS_DISCHARGING); +} + +static struct kunit_case hid_input_tests[] = { + KUNIT_CASE(hid_test_input_set_battery_charge_status), + KUNIT_CASE(hid_test_input_get_battery_property), + { } +}; + +static struct kunit_suite hid_input_test_suite = { + .name = "hid_input", + .test_cases = hid_input_tests, +}; + +kunit_test_suite(hid_input_test_suite); + +MODULE_DESCRIPTION("HID input KUnit tests"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>"); diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 77c8c49852b5..743e518b9836 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -486,7 +486,7 @@ static int hidinput_get_battery_property(struct power_supply *psy, if (dev->battery_status == HID_BATTERY_UNKNOWN) val->intval = POWER_SUPPLY_STATUS_UNKNOWN; else - val->intval = POWER_SUPPLY_STATUS_DISCHARGING; + val->intval = dev->battery_charge_status; break; case POWER_SUPPLY_PROP_SCOPE: @@ -554,6 +554,7 @@ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, dev->battery_max = max; dev->battery_report_type = report_type; dev->battery_report_id = field->report->id; + dev->battery_charge_status = POWER_SUPPLY_STATUS_DISCHARGING; /* * Stylus is normally not connected to the device and thus we @@ -620,6 +621,20 @@ static void hidinput_update_battery(struct hid_device *dev, int value) power_supply_changed(dev->battery); } } + +static bool hidinput_set_battery_charge_status(struct hid_device *dev, + unsigned int usage, int value) +{ + switch (usage) { + case HID_BAT_CHARGING: + dev->battery_charge_status = value ? + POWER_SUPPLY_STATUS_CHARGING : + POWER_SUPPLY_STATUS_DISCHARGING; + return true; + } + + return false; +} #else /* !CONFIG_HID_BATTERY_STRENGTH */ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, struct hid_field *field, bool is_percentage) @@ -634,6 +649,12 @@ static void hidinput_cleanup_battery(struct hid_device *dev) static void hidinput_update_battery(struct hid_device *dev, int value) { } + +static bool hidinput_set_battery_charge_status(struct hid_device *dev, + unsigned int usage, int value) +{ + return false; +} #endif /* CONFIG_HID_BATTERY_STRENGTH */ static bool hidinput_field_in_collection(struct hid_device *device, struct hid_field *field, @@ -793,6 +814,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel break; } + if ((usage->hid & 0xf0) == 0xa0) { /* SystemControl */ + switch (usage->hid & 0xf) { + case 0x9: map_key_clear(KEY_MICMUTE); break; + default: goto ignore; + } + break; + } + if ((usage->hid & 0xf0) == 0xb0) { /* SC - Display */ switch (usage->hid & 0xf) { case 0x05: map_key_clear(KEY_SWITCHVIDEOMODE); break; @@ -1223,6 +1252,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel hidinput_setup_battery(device, HID_INPUT_REPORT, field, true); usage->type = EV_PWR; return; + case HID_BAT_CHARGING: + usage->type = EV_PWR; + return; } goto unknown; @@ -1465,7 +1497,11 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct return; if (usage->type == EV_PWR) { - hidinput_update_battery(hid, value); + bool handled = hidinput_set_battery_charge_status(hid, usage->hid, value); + + if (!handled) + hidinput_update_battery(hid, value); + return; } @@ -2321,3 +2357,7 @@ void hidinput_disconnect(struct hid_device *hid) cancel_work_sync(&hid->led_work); } EXPORT_SYMBOL_GPL(hidinput_disconnect); + +#ifdef CONFIG_HID_KUNIT_TEST +#include "hid-input-test.c" +#endif diff --git a/drivers/hid/hid-letsketch.c b/drivers/hid/hid-letsketch.c index 74d17cf518ba..97f047f18136 100644 --- a/drivers/hid/hid-letsketch.c +++ b/drivers/hid/hid-letsketch.c @@ -238,7 +238,7 @@ static int letsketch_probe(struct hid_device *hdev, const struct hid_device_id * char buf[256]; int i, ret; - if (!hid_is_using_ll_driver(hdev, &usb_hid_driver)) + if (!hid_is_usb(hdev)) return -ENODEV; intf = to_usb_interface(hdev->dev.parent); diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index c358778e070b..62180414efcc 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -554,7 +554,7 @@ static const u8 hid_reportid_size_map[NUMBER_OF_HID_REPORTS] = { #define LOGITECH_DJ_INTERFACE_NUMBER 0x02 -static struct hid_ll_driver logi_dj_ll_driver; +static const struct hid_ll_driver logi_dj_ll_driver; static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev); static void delayedwork_callback(struct work_struct *work); @@ -1506,7 +1506,7 @@ static bool logi_dj_ll_may_wakeup(struct hid_device *hid) return hid_hw_may_wakeup(djrcv_dev->hidpp); } -static struct hid_ll_driver logi_dj_ll_driver = { +static const struct hid_ll_driver logi_dj_ll_driver = { .parse = logi_dj_ll_parse, .start = logi_dj_ll_start, .stop = logi_dj_ll_stop, diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 6abd3e2a9094..83237b86c8ff 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -397,7 +397,8 @@ int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev, for (i = 0; i < report->maxfield; ++i) { field = report->field[i]; if (field->maxusage) { - if (field->physical == usage_id && + if ((field->physical == usage_id || + field->application == usage_id) && (field->logical == attr_usage_id || field->usage[0].hid == attr_usage_id) && @@ -506,7 +507,8 @@ static int sensor_hub_raw_event(struct hid_device *hdev, collection->usage); callback = sensor_hub_get_callback(hdev, - report->field[i]->physical, + report->field[i]->physical ? report->field[i]->physical : + report->field[i]->application, report->field[i]->usage[0].collection_index, &hsdev, &priv); if (!callback) { diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c index 8ee43cb225fc..29ec8b34741a 100644 --- a/drivers/hid/hid-steam.c +++ b/drivers/hid/hid-steam.c @@ -674,7 +674,7 @@ static int steam_client_ll_raw_request(struct hid_device *hdev, report_type, reqtype); } -static struct hid_ll_driver steam_client_ll_driver = { +static const struct hid_ll_driver steam_client_ll_driver = { .parse = steam_client_ll_parse, .start = steam_client_ll_start, .stop = steam_client_ll_stop, diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index b86b62f97108..af98ac31c8d4 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -842,7 +842,7 @@ static void i2c_hid_close(struct hid_device *hid) clear_bit(I2C_HID_STARTED, &ihid->flags); } -struct hid_ll_driver i2c_hid_ll_driver = { +static const struct hid_ll_driver i2c_hid_ll_driver = { .parse = i2c_hid_parse, .start = i2c_hid_start, .stop = i2c_hid_stop, @@ -851,7 +851,6 @@ struct hid_ll_driver i2c_hid_ll_driver = { .output_report = i2c_hid_output_report, .raw_request = i2c_hid_raw_request, }; -EXPORT_SYMBOL_GPL(i2c_hid_ll_driver); static int i2c_hid_init_irq(struct i2c_client *client) { diff --git a/drivers/hid/intel-ish-hid/ishtp-hid.c b/drivers/hid/intel-ish-hid/ishtp-hid.c index 14c271d7d8a9..00c6f0ebf356 100644 --- a/drivers/hid/intel-ish-hid/ishtp-hid.c +++ b/drivers/hid/intel-ish-hid/ishtp-hid.c @@ -183,7 +183,7 @@ void ishtp_hid_wakeup(struct hid_device *hid) wake_up_interruptible(&hid_data->hid_wait); } -static struct hid_ll_driver ishtp_hid_ll_driver = { +static const struct hid_ll_driver ishtp_hid_ll_driver = { .parse = ishtp_hid_parse, .start = ishtp_hid_start, .stop = ishtp_hid_stop, diff --git a/drivers/hid/surface-hid/surface_hid_core.c b/drivers/hid/surface-hid/surface_hid_core.c index 87637f813de2..a3e9cceddfac 100644 --- a/drivers/hid/surface-hid/surface_hid_core.c +++ b/drivers/hid/surface-hid/surface_hid_core.c @@ -174,7 +174,7 @@ static int surface_hid_raw_request(struct hid_device *hid, unsigned char reportn return -EIO; } -static struct hid_ll_driver surface_hid_ll_driver = { +static const struct hid_ll_driver surface_hid_ll_driver = { .start = surface_hid_start, .stop = surface_hid_stop, .open = surface_hid_open, diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 2a918aeb0af1..f161c95a1ad2 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -387,7 +387,7 @@ static int uhid_hid_output_report(struct hid_device *hid, __u8 *buf, return uhid_hid_output_raw(hid, buf, count, HID_OUTPUT_REPORT); } -struct hid_ll_driver uhid_hid_driver = { +static const struct hid_ll_driver uhid_hid_driver = { .start = uhid_hid_start, .stop = uhid_hid_stop, .open = uhid_hid_open, @@ -396,7 +396,6 @@ struct hid_ll_driver uhid_hid_driver = { .raw_request = uhid_hid_raw_request, .output_report = uhid_hid_output_report, }; -EXPORT_SYMBOL_GPL(uhid_hid_driver); #ifdef CONFIG_COMPAT diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index be4c731aaa65..257dd73e37bf 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -1318,7 +1318,7 @@ static bool usbhid_may_wakeup(struct hid_device *hid) return device_may_wakeup(&dev->dev); } -struct hid_ll_driver usb_hid_driver = { +static const struct hid_ll_driver usb_hid_driver = { .parse = usbhid_parse, .start = usbhid_start, .stop = usbhid_stop, @@ -1332,7 +1332,12 @@ struct hid_ll_driver usb_hid_driver = { .idle = usbhid_idle, .may_wakeup = usbhid_may_wakeup, }; -EXPORT_SYMBOL_GPL(usb_hid_driver); + +bool hid_is_usb(const struct hid_device *hdev) +{ + return hdev->ll_driver == &usb_hid_driver; +} +EXPORT_SYMBOL_GPL(hid_is_usb); static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *id) { |