Received: by 10.213.65.68 with SMTP id h4csp3802895imn; Tue, 3 Apr 2018 10:53:48 -0700 (PDT) X-Google-Smtp-Source: AIpwx4/yPRf9p5l+Rlrl1+gYsUHL0loZOE8EFLslRz7yM0e4o6xJIBWtdbWRtepiyicPoFEEPB2R X-Received: by 10.98.137.218 with SMTP id n87mr11446041pfk.48.1522778028369; Tue, 03 Apr 2018 10:53:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1522778028; cv=none; d=google.com; s=arc-20160816; b=NwVT/CzTQE3HQ+lge8H43qvp5fIxYKq+YKSOoEamZyYMN0Q1s4PVJFa3x8RJz7YHvb DilUeY8VKUGxYbp1hERKzju7NS2Jl7XV723XMlfUzBStIt9ZUZ/RwITl1ovjP7ZHk+Lw H4YT/b7ecDaNDYbPXgcVFkOWcYKIJnA0XApFi3NBrMo1zTBvW/87bn2swcW5fWXn26V1 ibMdFIDtMPqWFyCxcFr869FCsK9Fp7R+mfRo2CCqj5frAR4HdBgMmwNIbCyshkGYPYud AKNlHtqE9fzZnWcihrAZi4ZyBjNQa0XeW8eUT6NelXgvNJWz7IQyphDrCeRlavLGrV/I tU+Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:content-disposition :mime-version:message-id:subject:cc:to:from:date:dkim-signature :arc-authentication-results; bh=XVryurwpM9Jp4bxtRDYwc/HkXwdrq1+ydmKTFXRv5sg=; b=TamISBS5c/5QNud4gavzducOAKgG1vMG7yXxjLqfXI9TpV9T7b2f2vGwvF9wqwxP2E 0jVft9/nNy4MFKvWZQgLDjrx2jFqAzyHeRzCs2IV3R91NaxrRo5QMNlH+NpRoX1Gc/+d hIWkrFxqtq53mQhbO2zWbmew8jKTS/QOp8pbD8ZFYTX7koJ/qw8l7POzXFt+Yu1XqgZl vaNZa3+iaYl+BsefNJMHCoe0r3sED9hjHWYNXdQYw4PxCBKmZgpqaiXAiU2/izimx/+w TBIKHuARqShHyePlxU42kHPt8/zLgMZP9SOehGjKoK8Y93AdomPEcR6z1M/oz+Sy5Jtv UrWA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=HjQNUJGK; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y62si2265726pgb.728.2018.04.03.10.53.33; Tue, 03 Apr 2018 10:53:48 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=HjQNUJGK; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752367AbeDCRwZ (ORCPT + 99 others); Tue, 3 Apr 2018 13:52:25 -0400 Received: from mail-pl0-f67.google.com ([209.85.160.67]:45851 "EHLO mail-pl0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751561AbeDCRwX (ORCPT ); Tue, 3 Apr 2018 13:52:23 -0400 Received: by mail-pl0-f67.google.com with SMTP id v18-v6so7901361ply.12; Tue, 03 Apr 2018 10:52:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:mime-version:content-disposition :user-agent; bh=XVryurwpM9Jp4bxtRDYwc/HkXwdrq1+ydmKTFXRv5sg=; b=HjQNUJGKTOBCmuZUlpvXOi40TSYpFdJ067QF0r3SsBDZtp1FMyKM3aosBtzgmmaoCa oeVLZ+sNHHmf4HC+gUpOdxlPzEu0dHIA7GZxk9w6u+1LkTACVFjOF1OT46ove+l4Yi+M p2hna4X2ZiCnEc+U6F/qnDBVKkJsbPodTWbi7qnjP5mCxd+zNIzAw72pEwswTWM35R+x Z5W0zSwXsJYwgM8cFCT7xgzMOTUs5xR6OAmycKQqQWFqHbrvlswJ9Uid2LhOLpbw9tdN FA4TlvWfdk2b6ZbeZv6WTyF4P6vBamyk0s3csvQgOAqajoxH5vh7QNG7DKCkjxOqAwX7 iPyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition:user-agent; bh=XVryurwpM9Jp4bxtRDYwc/HkXwdrq1+ydmKTFXRv5sg=; b=IcQqrq0aX5CsWun/792nEL7XT8sWhdqiP4YYjX8p4F+inIzOtvogaXlcfWeMqOtbgu WpRTdUeZr8EomFWSyPctuddVRSO0GYIbscvscAH+2MCmUP5t24irBT13sTs4D43+WbyQ FdhYBNMlUyTPl4hFsmEgdlu/yjv3hXGrFdNpXxizZDlHLfMDg9B45Ud/AEywHygfQGJ0 dLPwIH2HIuZWKyIiiQNddFReTMJOI9GdK6ZNXh2erSx+90IRV0N1kTDF6k3SY3cFQBsf 3XaG0/PVUWZ77EaV7T6ctP6fbHC0ij2UcmULbgjH+mLN4YGs3NJ1lySfZbUyM4+N0aDA 8C7Q== X-Gm-Message-State: AElRT7FjYKQAjdsEOhH5e1rEifYK3lHWWMpYC3RW6SsJDiqp6cAVpjFz WYINao5PsF0mhizo54L3rPAtT3D1 X-Received: by 10.99.155.2 with SMTP id r2mr9925414pgd.450.1522777942572; Tue, 03 Apr 2018 10:52:22 -0700 (PDT) Received: from dtor-ws ([2620:0:1000:1511:8de6:27a8:ed13:2ef5]) by smtp.gmail.com with ESMTPSA id c15sm6944591pfm.114.2018.04.03.10.52.21 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 03 Apr 2018 10:52:22 -0700 (PDT) Date: Tue, 3 Apr 2018 10:52:20 -0700 From: Dmitry Torokhov To: Jiri Kosina , Martin Cc: Benjamin Tissoires , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] HID: input: fix battery level reporting on BT mice Message-ID: <20180403175220.GA148162@dtor-ws> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.9.2 (2017-12-15) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The commit 581c4484769e ("HID: input: map digitizer battery usage") assumed that devices having input (qas opposed to feature) report for battery strength would report the data on their own, without the need to be polled by the kernel; unfortunately it is not so. Many wireless mice do not send unsolicited reports with battery strength data and have to be polled explicitly. As a complication, stylus devices on digitizers are not normally connected to the base and thus can not be polled - the base can only determine battery strength in the stylus when it is in proximity. To solve this issue, we add a special flag that tells the kernel to avoid polling the device (and expect unsolicited reports) and set it when report field with physical usage of digitizer stylus (HID_DG_STYLUS). Unless this flag is set, and we have not seen the unsolicited reports, the kernel will attempt to poll the device when userspace attempts to read "capacity" and "state" attributes of power_supply object corresponding to the devices battery. Fixes: 581c4484769e ("HID: input: map digitizer battery usage") Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=198095 Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov --- Martin, give this patch a try and reply with your name/email if you want to be credited for reporting/testing. Thanks! drivers/hid/hid-input.c | 24 +++++++++++++++++------- include/linux/hid.h | 9 ++++++++- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 6836a856c243..930652c25120 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -387,7 +387,8 @@ static int hidinput_get_battery_property(struct power_supply *psy, break; case POWER_SUPPLY_PROP_CAPACITY: - if (dev->battery_report_type == HID_FEATURE_REPORT) { + if (dev->battery_status != HID_BATTERY_REPORTED && + !dev->battery_avoid_query) { value = hidinput_query_battery_capacity(dev); if (value < 0) return value; @@ -403,17 +404,17 @@ static int hidinput_get_battery_property(struct power_supply *psy, break; case POWER_SUPPLY_PROP_STATUS: - if (!dev->battery_reported && - dev->battery_report_type == HID_FEATURE_REPORT) { + if (dev->battery_status != HID_BATTERY_REPORTED && + !dev->battery_avoid_query) { value = hidinput_query_battery_capacity(dev); if (value < 0) return value; dev->battery_capacity = value; - dev->battery_reported = true; + dev->battery_status = HID_BATTERY_QUERIED; } - if (!dev->battery_reported) + if (dev->battery_status == HID_BATTERY_UNKNOWN) val->intval = POWER_SUPPLY_STATUS_UNKNOWN; else if (dev->battery_capacity == 100) val->intval = POWER_SUPPLY_STATUS_FULL; @@ -486,6 +487,14 @@ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, dev->battery_report_type = report_type; dev->battery_report_id = field->report->id; + /* + * Stylus is normally not connected to the device and thus we + * can't query the device and get meaningful battery strength. + * We have to wait for the device to report it on its own. + */ + dev->battery_avoid_query = report_type == HID_INPUT_REPORT && + field->physical == HID_DG_STYLUS; + dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg); if (IS_ERR(dev->battery)) { error = PTR_ERR(dev->battery); @@ -530,9 +539,10 @@ static void hidinput_update_battery(struct hid_device *dev, int value) capacity = hidinput_scale_battery_capacity(dev, value); - if (!dev->battery_reported || capacity != dev->battery_capacity) { + if (dev->battery_status != HID_BATTERY_REPORTED || + capacity != dev->battery_capacity) { dev->battery_capacity = capacity; - dev->battery_reported = true; + dev->battery_status = HID_BATTERY_REPORTED; power_supply_changed(dev->battery); } } diff --git a/include/linux/hid.h b/include/linux/hid.h index 8da3e1f48195..26240a22978a 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -516,6 +516,12 @@ enum hid_type { HID_TYPE_USBNONE }; +enum hid_battery_status { + HID_BATTERY_UNKNOWN = 0, + HID_BATTERY_QUERIED, /* Kernel explicitly queried battery strength */ + HID_BATTERY_REPORTED, /* Device sent unsolicited battery strength report */ +}; + struct hid_driver; struct hid_ll_driver; @@ -558,7 +564,8 @@ struct hid_device { /* device report descriptor */ __s32 battery_max; __s32 battery_report_type; __s32 battery_report_id; - bool battery_reported; + enum hid_battery_status battery_status; + bool battery_avoid_query; #endif unsigned int status; /* see STAT flags above */ -- 2.17.0.rc1.321.gba9d0f2565-goog -- Dmitry