From: Anjelique Melendez <quic_amelende@quicinc.com>
To: <dmitry.torokhov@gmail.com>, <corbet@lwn.net>, <sre@kernel.org>,
<robh+dt@kernel.org>
Cc: <linux-input@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<linux-arm-msm@vger.kernel.org>, <collinsd@codeaurora.org>,
<bjorn.andersson@linaro.org>, <swboyd@chromium.org>,
<skakit@codeaurora.org>, <linux-doc@vger.kernel.org>,
<linux-pm@vger.kernel.org>, <devicetree@vger.kernel.org>,
Anjelique Melendez <quic_amelende@quicinc.com>
Subject: [PATCH v5 4/5] input: misc: pm8941-pwrkey: add software key press debouncing support
Date: Mon, 11 Apr 2022 13:05:09 -0700 [thread overview]
Message-ID: <20220411200506.22891-5-quic_amelende@quicinc.com> (raw)
In-Reply-To: <20220411200506.22891-1-quic_amelende@quicinc.com>
From: David Collins <collinsd@codeaurora.org>
On certain PMICs, an unexpected assertion of KPDPWR_DEB (the
positive logic hardware debounced power key signal) may be seen
during the falling edge of KPDPWR_N (i.e. a power key press) when
it occurs close to the rising edge of SLEEP_CLK. This then
triggers a spurious KPDPWR interrupt.
Handle this issue by adding software debouncing support to ignore
key events that occur within the hardware debounce delay after the
most recent key release event.
Signed-off-by: David Collins <collinsd@codeaurora.org>
Signed-off-by: Anjelique Melendez <quic_amelende@quicinc.com>
---
drivers/input/misc/pm8941-pwrkey.c | 80 +++++++++++++++++++++++++++---
1 file changed, 74 insertions(+), 6 deletions(-)
diff --git a/drivers/input/misc/pm8941-pwrkey.c b/drivers/input/misc/pm8941-pwrkey.c
index 43106e4cfd23..881943ab4d55 100644
--- a/drivers/input/misc/pm8941-pwrkey.c
+++ b/drivers/input/misc/pm8941-pwrkey.c
@@ -9,6 +9,7 @@
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
+#include <linux/ktime.h>
#include <linux/log2.h>
#include <linux/module.h>
#include <linux/of.h>
@@ -20,6 +21,16 @@
#define PON_REV2 0x01
+#define PON_SUBTYPE 0x05
+
+#define PON_SUBTYPE_PRIMARY 0x01
+#define PON_SUBTYPE_SECONDARY 0x02
+#define PON_SUBTYPE_1REG 0x03
+#define PON_SUBTYPE_GEN2_PRIMARY 0x04
+#define PON_SUBTYPE_GEN2_SECONDARY 0x05
+#define PON_SUBTYPE_GEN3_PBS 0x08
+#define PON_SUBTYPE_GEN3_HLOS 0x09
+
#define PON_RT_STS 0x10
#define PON_KPDPWR_N_SET BIT(0)
#define PON_RESIN_N_SET BIT(1)
@@ -59,9 +70,12 @@ struct pm8941_pwrkey {
struct input_dev *input;
unsigned int revision;
+ unsigned int subtype;
struct notifier_block reboot_notifier;
u32 code;
+ u32 sw_debounce_time_us;
+ ktime_t sw_debounce_end_time;
const struct pm8941_data *data;
};
@@ -128,20 +142,63 @@ static irqreturn_t pm8941_pwrkey_irq(int irq, void *_data)
{
struct pm8941_pwrkey *pwrkey = _data;
unsigned int sts;
- int error;
+ int err;
- error = regmap_read(pwrkey->regmap,
- pwrkey->baseaddr + PON_RT_STS, &sts);
- if (error)
+ if (pwrkey->sw_debounce_time_us) {
+ if (ktime_before(ktime_get(), pwrkey->sw_debounce_end_time)) {
+ dev_dbg(pwrkey->dev, "ignoring key event received before debounce end %llu us\n",
+ pwrkey->sw_debounce_end_time);
+ return IRQ_HANDLED;
+ }
+ }
+
+ err = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_RT_STS, &sts);
+ if (err)
return IRQ_HANDLED;
- input_report_key(pwrkey->input, pwrkey->code,
- sts & pwrkey->data->status_bit);
+ sts &= pwrkey->data->status_bit;
+
+ if (pwrkey->sw_debounce_time_us && !sts)
+ pwrkey->sw_debounce_end_time = ktime_add_us(ktime_get(),
+ pwrkey->sw_debounce_time_us);
+
+ input_report_key(pwrkey->input, pwrkey->code, sts);
input_sync(pwrkey->input);
return IRQ_HANDLED;
}
+static int pm8941_pwrkey_sw_debounce_init(struct pm8941_pwrkey *pwrkey)
+{
+ unsigned int val, addr, mask;
+ int error;
+
+ if (pwrkey->data->has_pon_pbs && !pwrkey->pon_pbs_baseaddr) {
+ dev_err(pwrkey->dev, "PON_PBS address missing, can't read HW debounce time\n");
+ return 0;
+ }
+
+ if (pwrkey->pon_pbs_baseaddr)
+ addr = pwrkey->pon_pbs_baseaddr + PON_DBC_CTL;
+ else
+ addr = pwrkey->baseaddr + PON_DBC_CTL;
+ error = regmap_read(pwrkey->regmap, addr, &val);
+ if (error)
+ return error;
+
+ if (pwrkey->subtype >= PON_SUBTYPE_GEN2_PRIMARY)
+ mask = 0xf;
+ else
+ mask = 0x7;
+
+ pwrkey->sw_debounce_time_us = 2 * USEC_PER_SEC / (1 << (mask - (val & mask)));
+
+ dev_dbg(pwrkey->dev, "SW debounce time = %u us\n",
+ pwrkey->sw_debounce_time_us);
+
+ return 0;
+}
+
static int __maybe_unused pm8941_pwrkey_suspend(struct device *dev)
{
struct pm8941_pwrkey *pwrkey = dev_get_drvdata(dev);
@@ -234,6 +291,13 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
return error;
}
+ error = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_SUBTYPE,
+ &pwrkey->subtype);
+ if (error) {
+ dev_err(&pdev->dev, "failed to read subtype: %d\n", error);
+ return error;
+ }
+
error = of_property_read_u32(pdev->dev.of_node, "linux,code",
&pwrkey->code);
if (error) {
@@ -268,6 +332,10 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
}
}
+ error = pm8941_pwrkey_sw_debounce_init(pwrkey);
+ if (error)
+ return error;
+
if (pwrkey->data->pull_up_bit) {
error = regmap_update_bits(pwrkey->regmap,
pwrkey->baseaddr + PON_PULL_CTL,
--
2.35.1
next prev parent reply other threads:[~2022-04-11 20:06 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-11 20:05 [PATCH v5 0/5] Extend pm8941-pwrkey driver Anjelique Melendez
2022-04-11 20:05 ` [PATCH v5 1/5] dt-bindings: power: reset: qcom-pon: update "reg" property details Anjelique Melendez
2022-04-14 15:34 ` Rob Herring
2022-04-15 18:44 ` Anjelique Melendez
2022-04-11 20:05 ` [PATCH v5 2/5] input: misc: pm8941-pwrkey: fix error message Anjelique Melendez
2022-04-11 20:05 ` [PATCH v5 3/5] input: misc: pm8941-pwrkey: add support for PON GEN3 base addresses Anjelique Melendez
2022-04-14 21:18 ` Dmitry Baryshkov
2022-04-15 18:46 ` Anjelique Melendez
2022-04-11 20:05 ` Anjelique Melendez [this message]
2022-04-11 20:05 ` [PATCH v5 5/5] input: misc: pm8941-pwrkey: simulate missed key press events Anjelique Melendez
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220411200506.22891-5-quic_amelende@quicinc.com \
--to=quic_amelende@quicinc.com \
--cc=bjorn.andersson@linaro.org \
--cc=collinsd@codeaurora.org \
--cc=corbet@lwn.net \
--cc=devicetree@vger.kernel.org \
--cc=dmitry.torokhov@gmail.com \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=robh+dt@kernel.org \
--cc=skakit@codeaurora.org \
--cc=sre@kernel.org \
--cc=swboyd@chromium.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).