From patchwork Sat Jul 3 22:01:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Mikityanskiy X-Patchwork-Id: 12357125 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8C170C07E97 for ; Sat, 3 Jul 2021 22:02:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6855660FD8 for ; Sat, 3 Jul 2021 22:02:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229520AbhGCWFG (ORCPT ); Sat, 3 Jul 2021 18:05:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58440 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229813AbhGCWFC (ORCPT ); Sat, 3 Jul 2021 18:05:02 -0400 Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [IPv6:2a00:1450:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D35A5C061762; Sat, 3 Jul 2021 15:02:27 -0700 (PDT) Received: by mail-ej1-x62a.google.com with SMTP id b2so22588036ejg.8; Sat, 03 Jul 2021 15:02:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xm7MxMs6oqkzwyDsDCu2psTMjwceySVOJUdtTYPqDgo=; b=OjP9IlxA0VqhuspZXVfG3U1AGaZn+yfZmq1Gbf9r7VUA961CLdLcRaYpK4kBqt/CTi PgqaLnOcKQ72e/dKvQYEFpAoopiZv6sclQfObJDNoFXsPMwUwkqjzZ5toKBi5hoq9p5k XRCncH61iBvgvvAGL+th4ET7/Zrrec3OEzQMcPkyMYkyb9FtNbJ8FDMioSgc/CDRY4ry Fa5yGyn8Oo7amt4RyeBRk/KEE0ux2vrWxWkkrjEEM7gNxp97zJpTaP/C8mzNVCm4part yn8OC4mayGx9MYJ+vSS0Q8Paw5lCZC/oX4Y26rD9TpSL8RPIx+H47oUHIucTFz05jEXI Tl7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xm7MxMs6oqkzwyDsDCu2psTMjwceySVOJUdtTYPqDgo=; b=UTvs5r8UVKPVxx0oxV1iMsIGY3gIowxtH6cysbnZLsmHAJmSi0OQ8mEfklN3lCUnsN BVjU2iRroaUcoyrWzgVWQoXmzPFS0Y64JgvVoSTJvc1joXQenm9Vf6FclsfCNRWC+gb+ auIRARZ6+ibCWXsA+Y9e1G/B8m4OrmehJv2tP1OH4mITtbFk1PgJbcRusqR4Cj3Rdano 6u8hugBbNGG7YZICuCgvh6AX33OURLsTTMSGzW7urtUTF7B7nIcX8CY7yl6bhtFSPGC2 1/YzGR4ryRSIzdq916oJpLwutf/OWQPtsH5Vpm+IkjQulWquwYUPXsdZh1Hkb2BYf+Xt A7kQ== X-Gm-Message-State: AOAM530OHoQUUomO0guyfAaEp8x/fQYMnWjanJBXQk2aVIBpBCoK//Yc Iv2d9sewQFMeo4yGHI/RtDQ= X-Google-Smtp-Source: ABdhPJz64hZ1wztW37NqkrOS5nSppL6Wnju7K5VElKwHvgADegMu8rB1/7/dbfl3FXMc8C1G5WZVMw== X-Received: by 2002:a17:906:9745:: with SMTP id o5mr6190110ejy.344.1625349746323; Sat, 03 Jul 2021 15:02:26 -0700 (PDT) Received: from warrior.lan ([2a03:7380:2407:bc63:7e28:eb67:305b:8ba0]) by smtp.gmail.com with ESMTPSA id b25sm3186110edv.9.2021.07.03.15.02.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 03 Jul 2021 15:02:26 -0700 (PDT) From: Maxim Mikityanskiy To: Jiri Kosina , Benjamin Tissoires , Dmitry Torokhov , Daniel Kurtz , Oliver Neukum Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, Maxim Mikityanskiy Subject: [PATCH 1/6] HID: hid-input: Add offhook and ring LEDs for headsets Date: Sun, 4 Jul 2021 01:01:57 +0300 Message-Id: <20210703220202.5637-2-maxtram95@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210703220202.5637-1-maxtram95@gmail.com> References: <20210703220202.5637-1-maxtram95@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org A lot of USBHID headsets available on the market have LEDs that indicate ringing and off-hook states when used with VoIP applications. This commit exposes these LEDs via the standard sysfs interface. Signed-off-by: Maxim Mikityanskiy --- drivers/hid/hid-input.c | 2 ++ drivers/input/input-leds.c | 2 ++ include/uapi/linux/input-event-codes.h | 2 ++ 3 files changed, 6 insertions(+) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 4286a51f7f16..44b8243f9924 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -798,6 +798,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x4b: map_led (LED_MISC); break; /* "Generic Indicator" */ case 0x19: map_led (LED_MAIL); break; /* "Message Waiting" */ case 0x4d: map_led (LED_CHARGING); break; /* "External Power Connected" */ + case 0x17: map_led (LED_OFFHOOK); break; /* "Off-Hook" */ + case 0x18: map_led (LED_RING); break; /* "Ring" */ default: goto ignore; } diff --git a/drivers/input/input-leds.c b/drivers/input/input-leds.c index 0b11990ade46..bc6e25b9af25 100644 --- a/drivers/input/input-leds.c +++ b/drivers/input/input-leds.c @@ -33,6 +33,8 @@ static const struct { [LED_MISC] = { "misc" }, [LED_MAIL] = { "mail" }, [LED_CHARGING] = { "charging" }, + [LED_OFFHOOK] = { "offhook" }, + [LED_RING] = { "ring" }, }; struct input_led { diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h index 225ec87d4f22..dd785a5b5076 100644 --- a/include/uapi/linux/input-event-codes.h +++ b/include/uapi/linux/input-event-codes.h @@ -925,6 +925,8 @@ #define LED_MISC 0x08 #define LED_MAIL 0x09 #define LED_CHARGING 0x0a +#define LED_OFFHOOK 0x0b +#define LED_RING 0x0c #define LED_MAX 0x0f #define LED_CNT (LED_MAX+1) From patchwork Sat Jul 3 22:01:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Mikityanskiy X-Patchwork-Id: 12357127 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 94EB1C07E98 for ; Sat, 3 Jul 2021 22:02:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7672261421 for ; Sat, 3 Jul 2021 22:02:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229874AbhGCWFG (ORCPT ); Sat, 3 Jul 2021 18:05:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58446 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229818AbhGCWFC (ORCPT ); Sat, 3 Jul 2021 18:05:02 -0400 Received: from mail-ed1-x52f.google.com (mail-ed1-x52f.google.com [IPv6:2a00:1450:4864:20::52f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8F7B0C061764; Sat, 3 Jul 2021 15:02:28 -0700 (PDT) Received: by mail-ed1-x52f.google.com with SMTP id t3so18394514edc.7; Sat, 03 Jul 2021 15:02:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6NWHzNIVgTYrqzEJ/wMRZOIsI/zAzKZABgGCwsk3RCM=; b=dte5+mQfRU0pGl3J6Xq3F/7bKDp/g9/gsVcHeew4UGwXVYKN/tyrFYnn6JXgUmmmVm /gZESB+JVmF5T5o2DiEiLUrQpe/VgJRZIZxopzVUnFdQ2F6PfT7TxczPdsXIwensQsSB ThDdFLLkUUyTMWtRDtPo+f7u2lCH2ZoXYJOL/aUKab1beuP0y8uhaY973sPqpVsb78Rc KnP3Y85eNIOx7JBSJTAvJfAYDkIvFcHsylufio0GEJMgsnsW4fn/UVma6NWP0NrXGGdW /mZIaoHMbfYbkMVOsgEb5eAojBX6qmYmxVkhaFv087mwvLirHTtYZts5//qkVz1ikU0E P5jw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6NWHzNIVgTYrqzEJ/wMRZOIsI/zAzKZABgGCwsk3RCM=; b=Av9+Xrx/zm5FzcIzlLgI2bC88TxfAscW75SGR/usAtg4GOIOExAOGILBHfMw4+2lBc zCbPvtaxdO14bvbzao5wEet5h7L91l9rBOahnrhTCwFLh4U8jnuAbREy6w8JIrkEIsWq PiGwPIBLekjs2TsYfb0MytBv0I577I0MDP7TXsrSXliZDoZARxDgL0jK3bb8AkzzE0za 8cvVf9z76YFCpYSZhjG6hTi2BKKnZEosE9Yh6zR7HofoELM95xozinrvLJ8gn8meYnK4 9RnCLIQrhiGBFhTke9Uwpfi+phRPoL+y8atSKR1+2xukH1bD3Zc+c1JdJA752Zhs97Je tvqQ== X-Gm-Message-State: AOAM53328xyBL5FAkuwFqLFRnEMXTLvET+ugVDWrSUBLo5EzW2be5aR9 OTL8TyG07gQVTeSUxKlL5Do= X-Google-Smtp-Source: ABdhPJyxrt188AFeT5cWtDDaKJ6m5O7ShihoeaRWzNuWQhLh0RKVAEtLS/yUb9BDqRNYbl8BbVyn/w== X-Received: by 2002:a05:6402:2681:: with SMTP id w1mr7090616edd.275.1625349747157; Sat, 03 Jul 2021 15:02:27 -0700 (PDT) Received: from warrior.lan ([2a03:7380:2407:bc63:7e28:eb67:305b:8ba0]) by smtp.gmail.com with ESMTPSA id b25sm3186110edv.9.2021.07.03.15.02.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 03 Jul 2021 15:02:26 -0700 (PDT) From: Maxim Mikityanskiy To: Jiri Kosina , Benjamin Tissoires , Dmitry Torokhov , Daniel Kurtz , Oliver Neukum Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, Maxim Mikityanskiy Subject: [PATCH 2/6] HID: hid-input: Add phone hook and mic mute buttons for headsets Date: Sun, 4 Jul 2021 01:01:58 +0300 Message-Id: <20210703220202.5637-3-maxtram95@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210703220202.5637-1-maxtram95@gmail.com> References: <20210703220202.5637-1-maxtram95@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org A lot of USBHID headsets available on the market have buttons to toggle microphone mute and to answer the call/hang up. According to the HID Usage Tables specification, these usages are on/off controls, which may be presented by either two buttons, a single toggle button or a mechanical switch. This commit adds a function called hidinput_handle_onoff that handles all these cases in a compliant way. Signed-off-by: Maxim Mikityanskiy --- drivers/hid/hid-input.c | 140 +++++++++++++++++++++++++ include/uapi/linux/input-event-codes.h | 8 ++ 2 files changed, 148 insertions(+) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 44b8243f9924..533a7f429a5f 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -579,6 +579,43 @@ static bool hidinput_field_in_collection(struct hid_device *device, struct hid_f return collection->type == type && collection->usage == usage; } +/** + * hidinput_get_onoff_keycodes - Gets on and off keycodes for OOC usages. + * @usage: HID usage. + * @code_on: Output parameter for the on keycode. + * @code_off: Output parameter for the off keycode. + * + * Returns true if @usage is a supported on/off control (OOC), as defined by HID + * Usage Tables 1.21 (3.4.1.2). + * + * Depending on the OOC type, we need to send either a toggle keycode or + * separate on/off keycodes. This function detects whether @usage is an OOC. If + * yes, and if this OOC is supported, it returns the on and off keycodes + * corresponding to the toggle keycode stored in usage->code. + */ +static bool hidinput_get_onoff_keycodes(struct hid_usage *usage, + u16 *code_on, u16 *code_off) +{ + if (usage->type != EV_KEY) + return false; + + if ((usage->hid & HID_USAGE_PAGE) != HID_UP_TELEPHONY) + return false; + + switch (usage->code) { + case KEY_TOGGLE_PHONE: + *code_on = KEY_PICKUP_PHONE; + *code_off = KEY_HANGUP_PHONE; + return true; + case KEY_MICMUTE: + *code_on = KEY_MICMUTE_ON; + *code_off = KEY_MICMUTE_OFF; + return true; + } + + return false; +} + static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, struct hid_usage *usage) { @@ -586,6 +623,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel struct hid_device *device = input_get_drvdata(input); int max = 0, code; unsigned long *bit = NULL; + u16 code_on, code_off; field->hidinput = hidinput; @@ -887,6 +925,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case HID_UP_TELEPHONY: switch (usage->hid & HID_USAGE) { + case 0x20: map_key_clear(KEY_TOGGLE_PHONE); break; case 0x2f: map_key_clear(KEY_MICMUTE); break; case 0xb0: map_key_clear(KEY_NUMERIC_0); break; case 0xb1: map_key_clear(KEY_NUMERIC_1); break; @@ -1198,6 +1237,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel set_bit(usage->type, input->evbit); + if (hidinput_get_onoff_keycodes(usage, &code_on, &code_off)) { + set_bit(code_on, bit); + set_bit(code_off, bit); + } + /* * This part is *really* controversial: * - HID aims at being generic so we should do our best to export @@ -1314,6 +1358,92 @@ static void hidinput_handle_scroll(struct hid_usage *usage, input_event(input, EV_REL, usage->code, hi_res); } +/** + * hidinput_handle_onoff - Handle on/off control (OOC). + * @field: HID field that corresponds to the event. + * @value: HID value that corresponds to the event. + * @code_toggle: Key code to send when toggling state of the on/off control. + * @code_on: Key code to send when turning on the on/off control. + * @code_off: Key code to send when turning off the on/off control. + * + * Returns true if the event was handled, false if the @field flags are invalid. + * + * Handles on/off control (OOC), as defined by HID Usage Tables 1.21 (3.4.1.2). + * Determines the type of the OOC by looking at @field and sends one of the key + * codes accordingly. Whenever it's possible to distinguish on and off states, + * different key strokes (@code_on, @code_off) are sent, otherwise @code_toggle + * is sent. + */ +static bool hidinput_handle_onoff(struct hid_field *field, __s32 value, unsigned int scan, + __u16 code_toggle, __u16 code_on, __u16 code_off) +{ + struct input_dev *input = field->hidinput->input; + __u16 code = 0; + + /* Two buttons, on and off */ + if ((field->flags & HID_MAIN_ITEM_RELATIVE) && + (field->flags & HID_MAIN_ITEM_NO_PREFERRED) && + (field->logical_minimum == -1) && + (field->logical_maximum == 1)) { + if (value != 1 && value != -1) + return true; + + code = value == 1 ? code_on : code_off; + } + + /* A single button that toggles the on/off state each time it is pressed */ + if ((field->flags & HID_MAIN_ITEM_RELATIVE) && + !(field->flags & HID_MAIN_ITEM_NO_PREFERRED) && + (field->logical_minimum == 0) && + (field->logical_maximum == 1)) { + if (value != 1) + return true; + + code = code_toggle; + } + + /* A toggle switch that maintains the on/off state mechanically */ + if (!(field->flags & HID_MAIN_ITEM_RELATIVE) && + (field->flags & HID_MAIN_ITEM_NO_PREFERRED) && + (field->logical_minimum == 0) && + (field->logical_maximum == 1)) + code = value ? code_on : code_off; + + if (!code) + return false; + + input_event(input, EV_MSC, MSC_SCAN, scan); + input_event(input, EV_KEY, code, 1); + input_sync(input); + input_event(input, EV_KEY, code, 0); + + return true; +} + +/** + * hidinput_handle_onoffs - Handles an OOC event if the HID usage type is OOC. + * @usage: HID usage to check. + * @field: HID field that corresponds to the event. + * @value: HID value that corresponds to the event. + * + * Returns: 1 if @usage is a supported on/off control (OOC), as defined by HID + * Usage Tables 1.21 (3.4.1.2). + * 0 if @usage is not a supported OOC. + * -EINVAL if @usage is not a valid OOC (@field is invalid). + */ +static int hidinput_handle_onoffs(struct hid_usage *usage, struct hid_field *field, __s32 value) +{ + u16 code_on, code_off; + + if (!hidinput_get_onoff_keycodes(usage, &code_on, &code_off)) + return 0; + + if (!hidinput_handle_onoff(field, value, usage->hid, usage->code, code_on, code_off)) + return -EINVAL; + + return 1; +} + void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) { struct input_dev *input; @@ -1438,6 +1568,16 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct value == field->value[usage->usage_index]) return; + switch (hidinput_handle_onoffs(usage, field, value)) { + case 1: + return; + case -EINVAL: + hid_warn_once(hid, "Invalid OOC usage: code %u, flags %#x, min %d, max %d\n", + usage->code, field->flags, + field->logical_minimum, field->logical_maximum); + return; + } + /* report the usage code as scancode if the key status has changed */ if (usage->type == EV_KEY && (!test_bit(usage->code, input->key)) == value) diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h index dd785a5b5076..d490de9ce7fe 100644 --- a/include/uapi/linux/input-event-codes.h +++ b/include/uapi/linux/input-event-codes.h @@ -518,6 +518,7 @@ #define KEY_NOTIFICATION_CENTER 0x1bc /* Show/hide the notification center */ #define KEY_PICKUP_PHONE 0x1bd /* Answer incoming call */ #define KEY_HANGUP_PHONE 0x1be /* Decline incoming call */ +#define KEY_TOGGLE_PHONE 0x1bf /* Toggle phone hook */ #define KEY_DEL_EOL 0x1c0 #define KEY_DEL_EOS 0x1c1 @@ -660,6 +661,13 @@ /* Select an area of screen to be copied */ #define KEY_SELECTIVE_SCREENSHOT 0x27a +/* + * In contrast to KEY_MICMUTE (that toggles the mute state), these set specific + * (on/off) states. + */ +#define KEY_MICMUTE_ON 0x280 +#define KEY_MICMUTE_OFF 0x281 + /* * Some keyboards have keys which do not have a defined meaning, these keys * are intended to be programmed / bound to macros by the user. For most From patchwork Sat Jul 3 22:01:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Mikityanskiy X-Patchwork-Id: 12357131 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BBE49C07E9A for ; Sat, 3 Jul 2021 22:02:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A64C461405 for ; Sat, 3 Jul 2021 22:02:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229909AbhGCWFG (ORCPT ); Sat, 3 Jul 2021 18:05:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58452 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229829AbhGCWFE (ORCPT ); Sat, 3 Jul 2021 18:05:04 -0400 Received: from mail-ej1-x632.google.com (mail-ej1-x632.google.com [IPv6:2a00:1450:4864:20::632]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 64BD6C061762; Sat, 3 Jul 2021 15:02:29 -0700 (PDT) Received: by mail-ej1-x632.google.com with SMTP id bu12so22684410ejb.0; Sat, 03 Jul 2021 15:02:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=+O8+Zi9puyRTTAamekj8g8xOH1F+G/ZtA4Tok7ByIfU=; b=ULOlkg/UY/F+BgGVRQHa5EkdnzLJuQtQFByY+4VGQoSs+vSEEMnncy28a8ECZK/ura /1sN4zzTjkdx8Q95CWpmD3Q01evgSX+xAh1yueFvmGIZdwra21w7iV/rNSt3xwLnAxbG 3c8s3QR8Mdi8d9Z8eRxgdJ/zf2zXZ3VHoNjgPeoVTxSHvAxLXJPDoTu6ckSO6TGUpUK1 +KbsQWDwXqilFoxYWgPhCnOHNY6FgIspcV9YIGtG1tFzXtrxSdRHj6+1Sq5Tk8aNrhIH qXsmNaarr4mFz9rFDn3dqKeURjKmdUVdTzWe51qlWffZIt4h7UmAMs0nMdPRcnzg0407 Yu6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+O8+Zi9puyRTTAamekj8g8xOH1F+G/ZtA4Tok7ByIfU=; b=fQfXTEmy+DduBG2wV2QGuxJcXngbpIm/abehPvHCag0wpdBjQ9PwM3B3AUBclC2zl8 kLZOMSf3HabKu2wRD6OxN2mMkpn+/59g/KQC8PjrKsF91TFasR0RT++sKJkgBeRkXVil ZkNGow5Y+a2xz00xkYrXbBNBVVfkPUxCShlvXxRHo8Evvwo9artyHeV6jUkseC4OdxBt e7B36nXu0FOQKi4O06tlcDMLcQR047I3PEGh5BGOp2rT05p4Hln05b9wxK+xz0y63V1F FibkOK3WjtDkqX7dQttDGC/dlq1Z9Auzfn4nqUsQyy9Q2vNXWjhmESMWqQVgY39u8qqp j1zg== X-Gm-Message-State: AOAM532xJahj96PMkG0II8xYXiewb5bYntW4HO2U/7LuO4gBeIPutebf 44ioUyf05Y7D2KJ9SQVj0GY= X-Google-Smtp-Source: ABdhPJzJ7K4mhloNSty6ggf/97FhlNrNAlsrWISaRetPeTAvablVzrF3VRhJcB3iVt0bHEBjpl2iSA== X-Received: by 2002:a17:907:3da7:: with SMTP id he39mr1745718ejc.512.1625349747961; Sat, 03 Jul 2021 15:02:27 -0700 (PDT) Received: from warrior.lan ([2a03:7380:2407:bc63:7e28:eb67:305b:8ba0]) by smtp.gmail.com with ESMTPSA id b25sm3186110edv.9.2021.07.03.15.02.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 03 Jul 2021 15:02:27 -0700 (PDT) From: Maxim Mikityanskiy To: Jiri Kosina , Benjamin Tissoires , Dmitry Torokhov , Daniel Kurtz , Oliver Neukum Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, Maxim Mikityanskiy Subject: [PATCH 3/6] HID: plantronics: Expose headset LEDs Date: Sun, 4 Jul 2021 01:01:59 +0300 Message-Id: <20210703220202.5637-4-maxtram95@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210703220202.5637-1-maxtram95@gmail.com> References: <20210703220202.5637-1-maxtram95@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org hid-plantronics uses a custom input mapping, where unhandled usages get ignored. Although these headsets have LEDs, they aren't handled in plantronics_input_mapping, hence not exposed to the userspace. This commit fixes it by adding a case for HID_UP_LED. Tested with Plantronics Blackwire 3220 Series (047f:c056). Signed-off-by: Maxim Mikityanskiy --- drivers/hid/hid-plantronics.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/hid/hid-plantronics.c b/drivers/hid/hid-plantronics.c index e81b7cec2d12..ea056235a591 100644 --- a/drivers/hid/hid-plantronics.c +++ b/drivers/hid/hid-plantronics.c @@ -61,6 +61,10 @@ static int plantronics_input_mapping(struct hid_device *hdev, if (field->application == HID_GD_JOYSTICK) goto defaulted; + /* expose LEDs */ + if ((usage->hid & HID_USAGE_PAGE) == HID_UP_LED) + goto defaulted; + /* handle volume up/down mapping */ /* non-standard types or multi-HID interfaces - plt_type is PID */ if (!(plt_type & HID_USAGE_PAGE)) { From patchwork Sat Jul 3 22:02:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Mikityanskiy X-Patchwork-Id: 12357129 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AAFF7C07E99 for ; Sat, 3 Jul 2021 22:02:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8DC8F61454 for ; Sat, 3 Jul 2021 22:02:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229921AbhGCWFH (ORCPT ); Sat, 3 Jul 2021 18:05:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58454 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229823AbhGCWFE (ORCPT ); Sat, 3 Jul 2021 18:05:04 -0400 Received: from mail-ej1-x635.google.com (mail-ej1-x635.google.com [IPv6:2a00:1450:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2F50BC061764; Sat, 3 Jul 2021 15:02:30 -0700 (PDT) Received: by mail-ej1-x635.google.com with SMTP id he13so3940221ejc.11; Sat, 03 Jul 2021 15:02:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tALBXtQ1QYpjrahCLXThf1TVXTbpsMt6bd2sj22kqvg=; b=JgTU80ODSQkCEPo00JEy7wCeECKzOBS367MEfwsjjy0Np/KIMU5fo9COAcTLo7ucA9 iDG2/8MItTQdbi+4jm5AuMMJzQAGmS70VNbg9FYbrPPoidhLaBbanyJs4iigk0qN+61w qGczzrFJrqc5yNndlIjk/amJ2UDkc+5QJY8LnMfUb1dljhUJmG8mynxKYNgleRMh6Sba lYsS+6jhgewE+x4Jr3FC0kvbzRAiDQwzopcCBNJxhp3ktE67rpXVmmcUm9YlenlpC6+u Ji/oadk9ub2Gs/WA16wPoX6yEYmqvkVrXULSBPkqvo2kRVaI5V57f73rZFWtnULBTlGY QzqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tALBXtQ1QYpjrahCLXThf1TVXTbpsMt6bd2sj22kqvg=; b=ODcrtMC3TSbfGBrSF7Yd7UmVXH09ePIFOBxW4pNZ2Q2/lFJdrbvjh/PiJ7snSNKlyq hYLcGavJtsFr9UPe4y7te7o0QbCsNQqI5J5SpbyXbRbRdhffMobJFChtJriT9FzwgY4J wpjp5vkCgdmI6Fc7d0iF40ES3utqfcr0Pm4dxTw07voWbPN20Nz5Hd83UyvRaZwrz2Ec Y8rot9GmNRpSWexthsOPqlujEP2w6Lun6salZC+qRuTO5m4N7Z7DHWYuf0bYVYGnEp0q 1FUZmCqZd/6KvXLKaqK8Axn7hztA/6pluFPQ02vEr5a4Xv+DEXMfa7+8B3EaCSDYDkh1 GW1A== X-Gm-Message-State: AOAM532lrSg94joqdS7axmM9AdRp/JiqAbGBz4h1tAwV9SOaqTXIYzDK YzkJovNxoJ4aCr+dvwqHyr0= X-Google-Smtp-Source: ABdhPJyagU7o4tYpUSj4yV2KcQa0f5n3YrbsG7EcQobX8Kz8NzzQZyVXVku+J2yr1YUgKbMWcJCCdg== X-Received: by 2002:a17:907:9812:: with SMTP id ji18mr6266672ejc.138.1625349748791; Sat, 03 Jul 2021 15:02:28 -0700 (PDT) Received: from warrior.lan ([2a03:7380:2407:bc63:7e28:eb67:305b:8ba0]) by smtp.gmail.com with ESMTPSA id b25sm3186110edv.9.2021.07.03.15.02.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 03 Jul 2021 15:02:28 -0700 (PDT) From: Maxim Mikityanskiy To: Jiri Kosina , Benjamin Tissoires , Dmitry Torokhov , Daniel Kurtz , Oliver Neukum Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, Maxim Mikityanskiy Subject: [PATCH 4/6] HID: plantronics: Expose headset telephony buttons Date: Sun, 4 Jul 2021 01:02:00 +0300 Message-Id: <20210703220202.5637-5-maxtram95@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210703220202.5637-1-maxtram95@gmail.com> References: <20210703220202.5637-1-maxtram95@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org hid-plantronics uses a custom input mapping, where unhandled usages get ignored. Although these headsets have telephony buttons (microphone mute and answer/hangup), they are not handled in plantronics_input_mapping, hence not exposed to the userspace. This commit fixes it by adding a case for HID_UP_TELEPHONY to the "basic telephony compliant" devices. Tested with Plantronics Blackwire 3220 Series (047f:c056). Signed-off-by: Maxim Mikityanskiy --- drivers/hid/hid-plantronics.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/hid/hid-plantronics.c b/drivers/hid/hid-plantronics.c index ea056235a591..19d6cddff86a 100644 --- a/drivers/hid/hid-plantronics.c +++ b/drivers/hid/hid-plantronics.c @@ -84,6 +84,8 @@ static int plantronics_input_mapping(struct hid_device *hdev, (plt_type & HID_USAGE) != PLT_BASIC_EXCEPTION) { if (PLT_ALLOW_CONSUMER) goto defaulted; + if ((usage->hid & HID_USAGE_PAGE) == HID_UP_TELEPHONY) + goto defaulted; } /* not 'basic telephony' - apply legacy mapping */ /* only map if the field is in the device's primary vendor page */ From patchwork Sat Jul 3 22:02:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Mikityanskiy X-Patchwork-Id: 12357133 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-14.8 required=3.0 tests=BANG_GUAR,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5A183C07E97 for ; Sat, 3 Jul 2021 22:02:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 41FB260FD8 for ; Sat, 3 Jul 2021 22:02:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229818AbhGCWFP (ORCPT ); Sat, 3 Jul 2021 18:05:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58458 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229881AbhGCWFG (ORCPT ); Sat, 3 Jul 2021 18:05:06 -0400 Received: from mail-ed1-x533.google.com (mail-ed1-x533.google.com [IPv6:2a00:1450:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1465CC061762; Sat, 3 Jul 2021 15:02:31 -0700 (PDT) Received: by mail-ed1-x533.google.com with SMTP id t3so18394683edc.7; Sat, 03 Jul 2021 15:02:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=JR2liRXOxmwJp1ZJ/wg7Rq+iYd/du1qufuFzoWCde2U=; b=DHknTo8ur7PtmMgDVSZZTeM/L6r9NsipDC3ZO54pRDYgkuxaP2bCEGxCn/u7/pcoAK rPLJ8AmxpUOe6FXiz5N8c11RPw9suc7n3ZqxCpr9t6dFy989g6PDIGtmxcn9wLCuSH+C JBGL+9OSZzhAMpI6w+EEN2/Vq77DG0iBav0FUzvyZR3WAGkjlL6RCkjX1z1hsSKUpnhB ZwVwG3QC6cmMyH3eOQn7ARidCUs+G2UpkKghnCJOMjHRA22Fd4XjflhDP64zN8vKL8iA B6882+QJNvS1goBijcRf+UiPpW+mQao4gNHEb7Jef1oWvy4SS3CvlkNu2ZtDcJ25Fmoe H6IQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=JR2liRXOxmwJp1ZJ/wg7Rq+iYd/du1qufuFzoWCde2U=; b=Rj8bjHSp7AlsKDGIjtIaH/UkT/4X6lt8yC+fws6zpHMHTzKP+FPkow9t6zlgbpewN1 /VfIcEldmGJro/Y6fypIrwZ0tpi7OykqFb2WCuDOSqn8whtYr5wDJnHPfqUopr6pE4N4 Lo64Vjo70R7P7+Q6JGDIScPNlVaA/DFh3DtT1Sat4ICaV/3a8+PEAXmPWaod8Q0YpHCT weTlYRUe3aRihUKfc93O1kZaJbcwDf7dvU80SChBvm//GcMZn6ugZqjMzlKoBgizqG6M bjRvpe1vmt0rxSqaxUvj9rcDB8PYA//9SIz+7W6i1wD7U27A6yE24mNGHSJ5Qr9Bn0aC iDZw== X-Gm-Message-State: AOAM530DfDYgc2N38W/98wXHqfmlaatOhl/X7zyMzTXbvCFnqhmkdf8Y rVwEV9Okgpi8DsrzLUohBB8= X-Google-Smtp-Source: ABdhPJyClyCALMa908kKtzm5KeLC3McFMvWnlClfErsChIKXT9DCjunHg7h7ARNv5EJp8oiAS36jaw== X-Received: by 2002:a05:6402:411:: with SMTP id q17mr7092227edv.313.1625349749700; Sat, 03 Jul 2021 15:02:29 -0700 (PDT) Received: from warrior.lan ([2a03:7380:2407:bc63:7e28:eb67:305b:8ba0]) by smtp.gmail.com with ESMTPSA id b25sm3186110edv.9.2021.07.03.15.02.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 03 Jul 2021 15:02:29 -0700 (PDT) From: Maxim Mikityanskiy To: Jiri Kosina , Benjamin Tissoires , Dmitry Torokhov , Daniel Kurtz , Oliver Neukum Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, Maxim Mikityanskiy Subject: [PATCH 5/6] HID: hid-input: Update LEDs in all HID reports Date: Sun, 4 Jul 2021 01:02:01 +0300 Message-Id: <20210703220202.5637-6-maxtram95@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210703220202.5637-1-maxtram95@gmail.com> References: <20210703220202.5637-1-maxtram95@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org hidinput_led_worker is scheduled on a work queue to update all LEDs in a batch. However, it uses hidinput_get_led_field which gets the first LED field found, and updates only the report this field belongs to. There are devices that expose multiple LEDs in multiple reports. The current implementation of the worker fails to update some LEDs on such devices. Plantronics Blackwire 3220 Series (047f:c056) is an example of such device. Only mute LED works, but offhook and ring LEDs don't work. This commit fixes hidinput_led_worker by making it go over all reports that contain at least one LED field. Fixes: 4371ea8202e9 ("HID: usbhid: defer LED setting to a workqueue") Signed-off-by: Maxim Mikityanskiy --- drivers/hid/hid-input.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 533a7f429a5f..29f59208b34c 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -1663,22 +1663,29 @@ unsigned int hidinput_count_leds(struct hid_device *hid) } EXPORT_SYMBOL_GPL(hidinput_count_leds); -static void hidinput_led_worker(struct work_struct *work) +static bool hidinput_is_led_report(struct hid_report *report) { - struct hid_device *hid = container_of(work, struct hid_device, - led_work); struct hid_field *field; - struct hid_report *report; + int i, j; + + for (i = 0; i < report->maxfield; i++) { + field = report->field[i]; + for (j = 0; j < field->maxusage; j++) + if (field->usage[j].type == EV_LED) + return true; + } + + return false; +} + +static void hidinput_led_update(struct hid_device *hid, struct hid_report *report) +{ int ret; u32 len; __u8 *buf; - field = hidinput_get_led_field(hid); - if (!field) - return; - /* - * field->report is accessed unlocked regarding HID core. So there might + * report is accessed unlocked regarding HID core. So there might * be another incoming SET-LED request from user-space, which changes * the LED state while we assemble our outgoing buffer. However, this * doesn't matter as hid_output_report() correctly converts it into a @@ -1690,8 +1697,6 @@ static void hidinput_led_worker(struct work_struct *work) * correct value, guaranteed! */ - report = field->report; - /* use custom SET_REPORT request if possible (asynchronous) */ if (hid->ll_driver->request) return hid->ll_driver->request(hid, report, HID_REQ_SET_REPORT); @@ -1711,6 +1716,20 @@ static void hidinput_led_worker(struct work_struct *work) kfree(buf); } +static void hidinput_led_worker(struct work_struct *work) +{ + struct hid_device *hid = container_of(work, struct hid_device, + led_work); + struct hid_report *report; + + list_for_each_entry(report, + &hid->report_enum[HID_OUTPUT_REPORT].report_list, + list) { + if (hidinput_is_led_report(report)) + hidinput_led_update(hid, report); + } +} + static int hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { From patchwork Sat Jul 3 22:02:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Mikityanskiy X-Patchwork-Id: 12357135 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 57288C07E98 for ; Sat, 3 Jul 2021 22:02:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 39DA661416 for ; Sat, 3 Jul 2021 22:02:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230003AbhGCWFQ (ORCPT ); Sat, 3 Jul 2021 18:05:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58464 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229865AbhGCWFG (ORCPT ); Sat, 3 Jul 2021 18:05:06 -0400 Received: from mail-ej1-x635.google.com (mail-ej1-x635.google.com [IPv6:2a00:1450:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 005E5C061764; Sat, 3 Jul 2021 15:02:31 -0700 (PDT) Received: by mail-ej1-x635.google.com with SMTP id c17so22538885ejk.13; Sat, 03 Jul 2021 15:02:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Suqpqo5vbYogXQd8G18V6nH4n6l93IDGiGtOPmsm1nA=; b=EhZXCxm73mp70T++U1t3VqvHUiVxVuRM3XByDA3bLXkDOtEObYdJ1/AVxPnv+abV7W uPYLGKOSBkqAdArUFHVPhR8xC5xAvEZYRiaTc9TSPjDAVHPXhks7FV5Sk0PFrDG5UUUD lYrwebTWwUlM8IzBaCxBjaMDCYPZyc0PRzzj5sNk36rziIviLmzPz1Svu1j2U8TDCak7 ydeUPdsPqXfBGtykEOlK/6fB6rD47QjLXAq0h45TzckaR6w0/EJnqLXpmo5oYg5gGECR ZnjlSBQIpTR/4RGX5ge1pYXl68/WvIoSw45gOnBQ7JWrrn8KSIgPMTns8VJYieN+hrcV fGKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Suqpqo5vbYogXQd8G18V6nH4n6l93IDGiGtOPmsm1nA=; b=a8JuBDcLWoi/NhM26DYO652rCqqQeF2VW3cZ2zbUtW1BhP24+Vpb4IHUOvYOi4mAw9 3kpmMVrqRqPdNYv74Pz/SprDjzKMGDBGTOdLLoBNYGqzepYcI8hA1YdmLPiNin/ChlXa /oYTYbgoMfzTrDYgS3A7y6qNT4Rx4zrRUYeAeThpZ3ej7+ZrbxYzaoYw/Eey0BMiTAhf SbKYU3iIbH56dHqxTAkX9UuyhtEH3b9KnsFsHldQFgMlJqEksa5mD7mprdEGcMC61qPq L7OtAIOQrHPTR4kXLv9LW1gOMf/Gy6LAcxUZMu4UoWMtH8gj5YWWduUuQVr5q66qBigc l+1w== X-Gm-Message-State: AOAM53075C73fP/TonWttopHI/xYQKWBpqfrT26IBriuclpbKxuHCBak OjgKRjGsoEv7O5hVvtu6p4A= X-Google-Smtp-Source: ABdhPJyBPuD8AbRKJW5TTubRnv3+Lgkn7ZtaMCfif6Im2I9efdqiQtQQV+XuaCPLP8ZAEvBY+VuZRw== X-Received: by 2002:a17:907:1c0a:: with SMTP id nc10mr6129835ejc.294.1625349750546; Sat, 03 Jul 2021 15:02:30 -0700 (PDT) Received: from warrior.lan ([2a03:7380:2407:bc63:7e28:eb67:305b:8ba0]) by smtp.gmail.com with ESMTPSA id b25sm3186110edv.9.2021.07.03.15.02.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 03 Jul 2021 15:02:30 -0700 (PDT) From: Maxim Mikityanskiy To: Jiri Kosina , Benjamin Tissoires , Dmitry Torokhov , Daniel Kurtz , Oliver Neukum Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, Maxim Mikityanskiy Subject: [PATCH 6/6] HID: jabra: Change mute LED state to avoid missing key press events Date: Sun, 4 Jul 2021 01:02:02 +0300 Message-Id: <20210703220202.5637-7-maxtram95@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210703220202.5637-1-maxtram95@gmail.com> References: <20210703220202.5637-1-maxtram95@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Jabra devices use their discretion regarding when to send the mute key press events. Although every press on the mute button changes the LED and actual mute state, key press events are only generated in the offhook state and only if the mute state set by the host matches the mute state of the headset. Without the host's help, every second mute key press will be missed. This patch addresses it by making the driver update the mute state every time the mute button is pressed. Tested with GN Netcom Jabra EVOLVE 20 MS (0b0e:0300). If some other Jabra device doesn't suffer from this behavior, this workaround shouldn't hurt. Signed-off-by: Maxim Mikityanskiy --- drivers/hid/hid-jabra.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/hid/hid-jabra.c b/drivers/hid/hid-jabra.c index 41dc30fe2d16..818c174cd544 100644 --- a/drivers/hid/hid-jabra.c +++ b/drivers/hid/hid-jabra.c @@ -37,16 +37,51 @@ static int jabra_input_mapping(struct hid_device *hdev, return is_vendor_defined ? -1 : 0; } +static int jabra_event(struct hid_device *hdev, struct hid_field *field, + struct hid_usage *usage, __s32 value) +{ + struct hid_field *mute_led_field; + int offset; + + /* Usages are filtered in jabra_usages. */ + + if (!value) /* Handle key presses only. */ + return 0; + + offset = hidinput_find_field(hdev, EV_LED, LED_MUTE, &mute_led_field); + if (offset == -1) + return 0; /* No mute LED, proceed. */ + + /* + * The device changes the LED state automatically on the mute key press, + * however, it still expects the host to change the LED state. If there + * is a mismatch (i.e. the host didn't change the LED state), the next + * mute key press won't generate an event. To avoid missing every second + * mute key press, change the LED state here. + */ + input_event(mute_led_field->hidinput->input, EV_LED, LED_MUTE, + !mute_led_field->value[offset]); + + return 0; +} + static const struct hid_device_id jabra_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_JABRA, HID_ANY_ID) }, { } }; MODULE_DEVICE_TABLE(hid, jabra_devices); +static const struct hid_usage_id jabra_usages[] = { + { 0x000b002f, EV_KEY, HID_ANY_ID }, /* Mic mute */ + { HID_TERMINATOR, HID_TERMINATOR, HID_TERMINATOR } +}; + static struct hid_driver jabra_driver = { .name = "jabra", .id_table = jabra_devices, + .usage_table = jabra_usages, .input_mapping = jabra_input_mapping, + .event = jabra_event, }; module_hid_driver(jabra_driver);