From: Robin van der Gracht <robin@protonic.nl> To: Dmitry Torokhov <dmitry.torokhov@gmail.com> Cc: "linux-input @ vger . kernel . org" <linux-input@vger.kernel.org>, "linux-kernel @ vger . kernel . org" <linux-kernel@vger.kernel.org>, RobinGong <yibin.gong@nxp.com>, Pengutronix Kernel Team <kernel@pengutronix.de>, Marco Felsch <m.felsch@pengutronix.de>, Shawn Guo <shawnguo@kernel.org>, Adam Ford <aford173@gmail.com>, "linux-arm-kernel @ lists . infradead . org" <linux-arm-kernel@lists.infradead.org>, Robin van der Gracht <robin@protonic.nl> Subject: [PATCH v4] input: keyboard: snvs_pwrkey: Send key events for i.MX6 S, DL and Q Date: Mon, 25 Nov 2019 17:12:10 +0100 [thread overview] Message-ID: <20191125161210.8275-1-robin@protonic.nl> (raw) The first generation i.MX6 processors does not send an interrupt when the power key is pressed. It sends a power down request interrupt if the key is released before a hard shutdown (5 second press). This should allow software to bring down the SoC safely. For this driver to work as a regular power key with the older SoCs, we need to send a keypress AND release when we get the power down request irq. Signed-off-by: Robin van der Gracht <robin@protonic.nl> --- Changes v3 -> v4: * The key release irq handler is now emitting the press and release events directly, instead of the debounce timer handler. drivers/input/keyboard/Kconfig | 2 +- drivers/input/keyboard/snvs_pwrkey.c | 28 +++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 7c4f19dab34f..937e58da5ce1 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -436,7 +436,7 @@ config KEYBOARD_SNVS_PWRKEY depends on OF help This is the snvs powerkey driver for the Freescale i.MX application - processors that are newer than i.MX6 SX. + processors. To compile this driver as a module, choose M here; the module will be called snvs_pwrkey. diff --git a/drivers/input/keyboard/snvs_pwrkey.c b/drivers/input/keyboard/snvs_pwrkey.c index 5342d8d45f81..4888e137cc5d 100644 --- a/drivers/input/keyboard/snvs_pwrkey.c +++ b/drivers/input/keyboard/snvs_pwrkey.c @@ -19,6 +19,7 @@ #include <linux/mfd/syscon.h> #include <linux/regmap.h> +#define SNVS_HPVIDR1_REG 0xF8 #define SNVS_LPSR_REG 0x4C /* LP Status Register */ #define SNVS_LPCR_REG 0x38 /* LP Control Register */ #define SNVS_HPSR_REG 0x14 @@ -37,6 +38,7 @@ struct pwrkey_drv_data { int wakeup; struct timer_list check_timer; struct input_dev *input; + u8 minor_rev; }; static void imx_imx_snvs_check_for_events(struct timer_list *t) @@ -67,13 +69,29 @@ static irqreturn_t imx_snvs_pwrkey_interrupt(int irq, void *dev_id) { struct platform_device *pdev = dev_id; struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev); + struct input_dev *input = pdata->input; u32 lp_status; - pm_wakeup_event(pdata->input->dev.parent, 0); + pm_wakeup_event(input->dev.parent, 0); regmap_read(pdata->snvs, SNVS_LPSR_REG, &lp_status); - if (lp_status & SNVS_LPSR_SPO) - mod_timer(&pdata->check_timer, jiffies + msecs_to_jiffies(DEBOUNCE_TIME)); + if (lp_status & SNVS_LPSR_SPO) { + if (pdata->minor_rev == 0) { + /* + * The first generation i.MX6 SoCs only sends an + * interrupt on button release. To mimic power-key + * usage, we'll prepend a press event. + */ + input_report_key(input, pdata->keycode, 1); + input_sync(input); + input_report_key(input, pdata->keycode, 0); + input_sync(input); + pm_relax(input->dev.parent); + } else { + mod_timer(&pdata->check_timer, + jiffies + msecs_to_jiffies(DEBOUNCE_TIME)); + } + } /* clear SPO status */ regmap_write(pdata->snvs, SNVS_LPSR_REG, SNVS_LPSR_SPO); @@ -94,6 +112,7 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev) struct input_dev *input = NULL; struct device_node *np; int error; + u32 vid; /* Get SNVS register Page */ np = pdev->dev.of_node; @@ -123,6 +142,9 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev) return -EINVAL; } + regmap_read(pdata->snvs, SNVS_HPVIDR1_REG, &vid); + pdata->minor_rev = vid & 0xff; + regmap_update_bits(pdata->snvs, SNVS_LPCR_REG, SNVS_LPCR_DEP_EN, SNVS_LPCR_DEP_EN); /* clear the unexpected interrupt before driver ready */ -- 2.20.1
WARNING: multiple messages have this Message-ID (diff)
From: Robin van der Gracht <robin@protonic.nl> To: Dmitry Torokhov <dmitry.torokhov@gmail.com> Cc: Robin van der Gracht <robin@protonic.nl>, Adam Ford <aford173@gmail.com>, Marco Felsch <m.felsch@pengutronix.de>, "linux-kernel @ vger . kernel . org" <linux-kernel@vger.kernel.org>, Pengutronix Kernel Team <kernel@pengutronix.de>, "linux-input @ vger . kernel . org" <linux-input@vger.kernel.org>, RobinGong <yibin.gong@nxp.com>, Shawn Guo <shawnguo@kernel.org>, "linux-arm-kernel @ lists . infradead . org" <linux-arm-kernel@lists.infradead.org> Subject: [PATCH v4] input: keyboard: snvs_pwrkey: Send key events for i.MX6 S, DL and Q Date: Mon, 25 Nov 2019 17:12:10 +0100 [thread overview] Message-ID: <20191125161210.8275-1-robin@protonic.nl> (raw) The first generation i.MX6 processors does not send an interrupt when the power key is pressed. It sends a power down request interrupt if the key is released before a hard shutdown (5 second press). This should allow software to bring down the SoC safely. For this driver to work as a regular power key with the older SoCs, we need to send a keypress AND release when we get the power down request irq. Signed-off-by: Robin van der Gracht <robin@protonic.nl> --- Changes v3 -> v4: * The key release irq handler is now emitting the press and release events directly, instead of the debounce timer handler. drivers/input/keyboard/Kconfig | 2 +- drivers/input/keyboard/snvs_pwrkey.c | 28 +++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 7c4f19dab34f..937e58da5ce1 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -436,7 +436,7 @@ config KEYBOARD_SNVS_PWRKEY depends on OF help This is the snvs powerkey driver for the Freescale i.MX application - processors that are newer than i.MX6 SX. + processors. To compile this driver as a module, choose M here; the module will be called snvs_pwrkey. diff --git a/drivers/input/keyboard/snvs_pwrkey.c b/drivers/input/keyboard/snvs_pwrkey.c index 5342d8d45f81..4888e137cc5d 100644 --- a/drivers/input/keyboard/snvs_pwrkey.c +++ b/drivers/input/keyboard/snvs_pwrkey.c @@ -19,6 +19,7 @@ #include <linux/mfd/syscon.h> #include <linux/regmap.h> +#define SNVS_HPVIDR1_REG 0xF8 #define SNVS_LPSR_REG 0x4C /* LP Status Register */ #define SNVS_LPCR_REG 0x38 /* LP Control Register */ #define SNVS_HPSR_REG 0x14 @@ -37,6 +38,7 @@ struct pwrkey_drv_data { int wakeup; struct timer_list check_timer; struct input_dev *input; + u8 minor_rev; }; static void imx_imx_snvs_check_for_events(struct timer_list *t) @@ -67,13 +69,29 @@ static irqreturn_t imx_snvs_pwrkey_interrupt(int irq, void *dev_id) { struct platform_device *pdev = dev_id; struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev); + struct input_dev *input = pdata->input; u32 lp_status; - pm_wakeup_event(pdata->input->dev.parent, 0); + pm_wakeup_event(input->dev.parent, 0); regmap_read(pdata->snvs, SNVS_LPSR_REG, &lp_status); - if (lp_status & SNVS_LPSR_SPO) - mod_timer(&pdata->check_timer, jiffies + msecs_to_jiffies(DEBOUNCE_TIME)); + if (lp_status & SNVS_LPSR_SPO) { + if (pdata->minor_rev == 0) { + /* + * The first generation i.MX6 SoCs only sends an + * interrupt on button release. To mimic power-key + * usage, we'll prepend a press event. + */ + input_report_key(input, pdata->keycode, 1); + input_sync(input); + input_report_key(input, pdata->keycode, 0); + input_sync(input); + pm_relax(input->dev.parent); + } else { + mod_timer(&pdata->check_timer, + jiffies + msecs_to_jiffies(DEBOUNCE_TIME)); + } + } /* clear SPO status */ regmap_write(pdata->snvs, SNVS_LPSR_REG, SNVS_LPSR_SPO); @@ -94,6 +112,7 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev) struct input_dev *input = NULL; struct device_node *np; int error; + u32 vid; /* Get SNVS register Page */ np = pdev->dev.of_node; @@ -123,6 +142,9 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev) return -EINVAL; } + regmap_read(pdata->snvs, SNVS_HPVIDR1_REG, &vid); + pdata->minor_rev = vid & 0xff; + regmap_update_bits(pdata->snvs, SNVS_LPCR_REG, SNVS_LPCR_DEP_EN, SNVS_LPCR_DEP_EN); /* clear the unexpected interrupt before driver ready */ -- 2.20.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next reply other threads:[~2019-11-25 16:19 UTC|newest] Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-11-25 16:12 Robin van der Gracht [this message] 2019-11-25 16:12 ` [PATCH v4] input: keyboard: snvs_pwrkey: Send key events for i.MX6 S, DL and Q Robin van der Gracht 2019-11-25 21:13 ` Dmitry Torokhov 2019-11-25 21:13 ` Dmitry Torokhov
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=20191125161210.8275-1-robin@protonic.nl \ --to=robin@protonic.nl \ --cc=aford173@gmail.com \ --cc=dmitry.torokhov@gmail.com \ --cc=kernel@pengutronix.de \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-input@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=m.felsch@pengutronix.de \ --cc=shawnguo@kernel.org \ --cc=yibin.gong@nxp.com \ /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: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.