summaryrefslogtreecommitdiff
path: root/drivers/hid/hid-input.c
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2023-02-22 12:27:57 +0300
committerBenjamin Tissoires <benjamin.tissoires@redhat.com>2023-02-22 12:27:57 +0300
commit06db2af35e5f44cebf36c1dc122f5769f630d2f8 (patch)
tree02830ad872b359dc6972b1c85bbc66b03d283653 /drivers/hid/hid-input.c
parent0b028189d1019ca352da108643b8f1503ee25a0e (diff)
parent3f16ba1c0768de6cdc6f65105757ef04dbfd8e5c (diff)
downloadlinux-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/hid-input.c')
-rw-r--r--drivers/hid/hid-input.c44
1 files changed, 42 insertions, 2 deletions
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