From f567d6ef8606fb427636e824c867229ecb5aefab Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Sun, 7 Feb 2021 16:47:40 +0200 Subject: HID: plantronics: Workaround for double volume key presses Plantronics Blackwire 3220 Series (047f:c056) sends HID reports twice for each volume key press. This patch adds a quirk to hid-plantronics for this product ID, which will ignore the second volume key press if it happens within 5 ms from the last one that was handled. The patch was tested on the mentioned model only, it shouldn't affect other models, however, this quirk might be needed for them too. Auto-repeat (when a key is held pressed) is not affected, because the rate is about 3 times per second, which is far less frequent than once in 5 ms. Fixes: 81bb773faed7 ("HID: plantronics: Update to map volume up/down controls") Signed-off-by: Maxim Mikityanskiy Signed-off-by: Jiri Kosina --- include/linux/hid.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index ef702b3f56e3..3e33eb14118c 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -262,6 +262,8 @@ struct hid_item { #define HID_CP_SELECTION 0x000c0080 #define HID_CP_MEDIASELECTION 0x000c0087 #define HID_CP_SELECTDISC 0x000c00ba +#define HID_CP_VOLUMEUP 0x000c00e9 +#define HID_CP_VOLUMEDOWN 0x000c00ea #define HID_CP_PLAYBACKSPEED 0x000c00f1 #define HID_CP_PROXIMITY 0x000c0109 #define HID_CP_SPEAKERSYSTEM 0x000c0160 -- cgit v1.2.3-71-gd317 From 9de07a4e8d4cb269f9876b2ffa282b5ffd09e05b Mon Sep 17 00:00:00 2001 From: John Chen Date: Tue, 30 Mar 2021 19:33:19 +0800 Subject: HID: input: map battery capacity (00850065) This is the capacity in percentage, relative to design capacity. Specifically, it is present in Apple Magic Mouse 2. In contrast, usage 00850064 is also the capacity in percentage, but is relative to full capacity. It is not mapped here because I don't have such device. Signed-off-by: John Chen Signed-off-by: Jiri Kosina --- drivers/hid/hid-debug.c | 1 + drivers/hid/hid-input.c | 22 ++++++++++++++++------ include/linux/hid.h | 3 +++ 3 files changed, 20 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index d7eaf9100370..59f8d716d78f 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -417,6 +417,7 @@ static const struct hid_usage_entry hid_usage_table[] = { { 0x85, 0x44, "Charging" }, { 0x85, 0x45, "Discharging" }, { 0x85, 0x4b, "NeedReplacement" }, + { 0x85, 0x65, "AbsoluteStateOfCharge" }, { 0x85, 0x66, "RemainingCapacity" }, { 0x85, 0x68, "RunTimeToEmpty" }, { 0x85, 0x6a, "AverageTimeToFull" }, diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 236bccd37760..18f5e28d475c 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -435,7 +435,8 @@ static int hidinput_get_battery_property(struct power_supply *psy, return ret; } -static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, struct hid_field *field) +static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, + struct hid_field *field, bool is_percentage) { struct power_supply_desc *psy_desc; struct power_supply_config psy_cfg = { .drv_data = dev, }; @@ -475,7 +476,7 @@ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, min = field->logical_minimum; max = field->logical_maximum; - if (quirks & HID_BATTERY_QUIRK_PERCENT) { + if (is_percentage || (quirks & HID_BATTERY_QUIRK_PERCENT)) { min = 0; max = 100; } @@ -552,7 +553,7 @@ static void hidinput_update_battery(struct hid_device *dev, int value) } #else /* !CONFIG_HID_BATTERY_STRENGTH */ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, - struct hid_field *field) + struct hid_field *field, bool is_percentage) { return 0; } @@ -806,7 +807,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel break; case 0x3b: /* Battery Strength */ - hidinput_setup_battery(device, HID_INPUT_REPORT, field); + hidinput_setup_battery(device, HID_INPUT_REPORT, field, false); usage->type = EV_PWR; return; @@ -1068,7 +1069,16 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case HID_UP_GENDEVCTRLS: switch (usage->hid) { case HID_DC_BATTERYSTRENGTH: - hidinput_setup_battery(device, HID_INPUT_REPORT, field); + hidinput_setup_battery(device, HID_INPUT_REPORT, field, false); + usage->type = EV_PWR; + return; + } + goto unknown; + + case HID_UP_BATTERY: + switch (usage->hid) { + case HID_BAT_ABSOLUTESTATEOFCHARGE: + hidinput_setup_battery(device, HID_INPUT_REPORT, field, true); usage->type = EV_PWR; return; } @@ -1672,7 +1682,7 @@ static void report_features(struct hid_device *hid) /* Verify if Battery Strength feature is available */ if (usage->hid == HID_DC_BATTERYSTRENGTH) hidinput_setup_battery(hid, HID_FEATURE_REPORT, - rep->field[i]); + rep->field[i], false); if (drv->feature_mapping) drv->feature_mapping(hid, rep->field[i], usage); diff --git a/include/linux/hid.h b/include/linux/hid.h index ef702b3f56e3..b40e1abbe11d 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -153,6 +153,7 @@ struct hid_item { #define HID_UP_CONSUMER 0x000c0000 #define HID_UP_DIGITIZER 0x000d0000 #define HID_UP_PID 0x000f0000 +#define HID_UP_BATTERY 0x00850000 #define HID_UP_HPVENDOR 0xff7f0000 #define HID_UP_HPVENDOR2 0xff010000 #define HID_UP_MSVENDOR 0xff000000 @@ -297,6 +298,8 @@ struct hid_item { #define HID_DG_TOOLSERIALNUMBER 0x000d005b #define HID_DG_LATENCYMODE 0x000d0060 +#define HID_BAT_ABSOLUTESTATEOFCHARGE 0x00850065 + #define HID_VD_ASUS_CUSTOM_MEDIA_KEYS 0xff310076 /* * HID report types --- Ouch! HID spec says 1 2 3! -- cgit v1.2.3-71-gd317