diff mbox

[v7,4/4] input/power: Add driver for BD71837/BD71847 PMIC power button

Message ID af60857c6db5fcf14fbf0112f74719d898952459.1529404894.git.matti.vaittinen@fi.rohmeurope.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Vaittinen, Matti June 19, 2018, 10:57 a.m. UTC
ROHM BD71837 PMIC power button driver providing power-key press
information to user-space.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---
 drivers/input/misc/Kconfig          | 10 +++++
 drivers/input/misc/Makefile         |  1 +
 drivers/input/misc/bd718xx-pwrkey.c | 90 +++++++++++++++++++++++++++++++++++++
 3 files changed, 101 insertions(+)
 create mode 100644 drivers/input/misc/bd718xx-pwrkey.c

Comments

Dmitry Torokhov June 19, 2018, 5:50 p.m. UTC | #1
Hi Matti,

On Tue, Jun 19, 2018 at 01:57:09PM +0300, Matti Vaittinen wrote:
> ROHM BD71837 PMIC power button driver providing power-key press
> information to user-space.
> 
> Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> ---
>  drivers/input/misc/Kconfig          | 10 +++++
>  drivers/input/misc/Makefile         |  1 +
>  drivers/input/misc/bd718xx-pwrkey.c | 90 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 101 insertions(+)
>  create mode 100644 drivers/input/misc/bd718xx-pwrkey.c
> 
> diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
> index 572b15fa18c2..694c05d3f9fb 100644
> --- a/drivers/input/misc/Kconfig
> +++ b/drivers/input/misc/Kconfig
> @@ -96,6 +96,16 @@ config INPUT_ATMEL_CAPTOUCH
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called atmel_captouch.
>  
> +config INPUT_BD718XX_PWRKEY
> +	tristate "ROHM BD71837/BD71847 power key support"
> +	depends on MFD_BD71837
> +	help
> +	  Say Y here if you want support for the power key usually found
> +	  on boards using a ROHM BD71837/BD71847 compatible PMIC.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called bd718xx-pwrkey.
> +
>  config INPUT_BMA150
>  	tristate "BMA150/SMB380 acceleration sensor support"
>  	depends on I2C
> diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
> index 72cde28649e2..ea5b81cbf2bf 100644
> --- a/drivers/input/misc/Makefile
> +++ b/drivers/input/misc/Makefile
> @@ -20,6 +20,7 @@ obj-$(CONFIG_INPUT_ATI_REMOTE2)		+= ati_remote2.o
>  obj-$(CONFIG_INPUT_ATLAS_BTNS)		+= atlas_btns.o
>  obj-$(CONFIG_INPUT_ATMEL_CAPTOUCH)	+= atmel_captouch.o
>  obj-$(CONFIG_INPUT_BMA150)		+= bma150.o
> +obj-$(CONFIG_INPUT_BD718XX_PWRKEY)	+= bd718xx-pwrkey.o
>  obj-$(CONFIG_INPUT_CM109)		+= cm109.o
>  obj-$(CONFIG_INPUT_CMA3000)		+= cma3000_d0x.o
>  obj-$(CONFIG_INPUT_CMA3000_I2C)		+= cma3000_d0x_i2c.o
> diff --git a/drivers/input/misc/bd718xx-pwrkey.c b/drivers/input/misc/bd718xx-pwrkey.c
> new file mode 100644
> index 000000000000..e8ac9475c3cf
> --- /dev/null
> +++ b/drivers/input/misc/bd718xx-pwrkey.c
> @@ -0,0 +1,90 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (C) 2018 ROHM Semiconductors
> +// bd718xx-pwrkey.c -- ROHM BD71837MWV and BD71847 power button driver
> +
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/errno.h>
> +#include <linux/input.h>
> +#include <linux/interrupt.h>
> +#include <linux/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/mfd/bd71837.h>
> +
> +struct bd718xx_pwrkey {
> +	struct input_dev *idev;
> +	struct bd71837 *mfd;
> +	int irq;
> +};
> +
> +static irqreturn_t button_irq(int irq, void *_priv)
> +{
> +	struct input_dev *idev = (struct input_dev *)_priv;
> +
> +	input_report_key(idev, KEY_POWER, 1);
> +	input_sync(idev);
> +	input_report_key(idev, KEY_POWER, 0);
> +	input_sync(idev);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int bd718xx_pwr_btn_probe(struct platform_device *pdev)
> +{
> +	int err = -ENOMEM;
> +	struct bd718xx_pwrkey *pk;
> +
> +	pk = devm_kzalloc(&pdev->dev, sizeof(*pk), GFP_KERNEL);
> +	if (!pk)
> +		goto err_out;
> +
> +	pk->mfd = dev_get_drvdata(pdev->dev.parent);
> +
> +	pk->idev = devm_input_allocate_device(&pdev->dev);
> +	if (!pk->idev)
> +		goto err_out;
> +
> +	pk->idev->name = "bd718xx-pwrkey";
> +	pk->idev->phys = "bd718xx-pwrkey/input0";
> +	pk->idev->dev.parent = &pdev->dev;
> +
> +	input_set_capability(pk->idev, EV_KEY, KEY_POWER);
> +
> +	err = platform_get_irq_byname(pdev, "pwr-btn-s");
> +	if (err < 0) {
> +		dev_err(&pdev->dev, "could not get power key interrupt\n");
> +		goto err_out;
> +	}
> +
> +	pk->irq = err;
> +	err = devm_request_threaded_irq(&pdev->dev, pk->irq, NULL, &button_irq,
> +					0, "bd718xx-pwrkey", pk);
> +	if (err)
> +		goto err_out;
> +
> +	platform_set_drvdata(pdev, pk);
> +	err = regmap_update_bits(pk->mfd->regmap,
> +				 BD71837_REG_PWRONCONFIG0,
> +				 BD718XX_PWRBTN_SHORT_PRESS_MASK,
> +				 BD718XX_PWRBTN_SHORT_PRESS_10MS);

This seems to be the only custom bit of set up in the driver, the rest I
think can easily be handled by gpio-keys.c in interrupt-only mode. Maybe
we could move this into MFD piece and drop this driver?

> +	if (err)
> +		goto err_out;
> +
> +	err = input_register_device(pk->idev);
> +
> +err_out:
> +
> +	return err;
> +}
> +
> +static struct platform_driver bd718xx_pwr_btn_driver = {
> +	.probe	= bd718xx_pwr_btn_probe,
> +	.driver = {
> +		.name	= "bd718xx-pwrkey",
> +	},
> +};
> +module_platform_driver(bd718xx_pwr_btn_driver);
> +MODULE_DESCRIPTION("Power button driver for buttons connected to ROHM bd71837/bd71847 PMIC");
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
> +
> -- 
> 2.14.3
> 

Thanks.
Vaittinen, Matti June 20, 2018, 6:43 a.m. UTC | #2
Hello Dmitry,

First of all -  thanks for taking the time to review the patch =)

On Tue, Jun 19, 2018 at 10:50:28AM -0700, Dmitry Torokhov wrote:
> Hi Matti,
> 
> On Tue, Jun 19, 2018 at 01:57:09PM +0300, Matti Vaittinen wrote:
> > ROHM BD71837 PMIC power button driver providing power-key press
> > information to user-space.
> > 
> > Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> > ---
> >  drivers/input/misc/Kconfig          | 10 +++++
> >  drivers/input/misc/Makefile         |  1 +
> >  drivers/input/misc/bd718xx-pwrkey.c | 90 +++++++++++++++++++++++++++++++++++++
> >  3 files changed, 101 insertions(+)
> >  create mode 100644 drivers/input/misc/bd718xx-pwrkey.c
> > 
> > +	platform_set_drvdata(pdev, pk);
> > +	err = regmap_update_bits(pk->mfd->regmap,
> > +				 BD71837_REG_PWRONCONFIG0,
> > +				 BD718XX_PWRBTN_SHORT_PRESS_MASK,
> > +				 BD718XX_PWRBTN_SHORT_PRESS_10MS);
> 
> This seems to be the only custom bit of set up in the driver, the rest I
> think can easily be handled by gpio-keys.c in interrupt-only mode. Maybe
> we could move this into MFD piece and drop this driver?

I looked at the gpio_keys.c (for first time so please bear with me if I
ask something you consider as obvious). This is also the first time I am
dealing with input subsystem drivers. So this patch was kind of "RFC"
because I am unsure if this is the best way...

HW we are dealing with is a PMIC which can hace a power-button attached.
HW can generate 3 different types of interrupts for power button
presses:

1. interrupt when button is pressed or released. (Eg. if someone just
hits the button we get two interrupts of this type). We get no 'position
information' from PMIC - just the irqs. Hence it is difficult to know if
buttown was pressed or released. This is the reason why I decided not to
use this IRQ (at least not for now).

2. interrupt when button is pressed for 'short time'. Short time is
configurable and IRQ is generated when button is released based on the
duration it was held down. The limit for 'short time' can be configured.
By default if button is pressed longer than 3 seconds but less than 10
seconds the the PMIC detects 'short push'.

3. interrupt when button is pressed for 'long time'. Mechanism is same
as with short push. Default time is button held over 10 seconds. This
interrupt is not handled if PMIC provides power to processor as PMIC
will cut the power when long push is detected.

So the custom piece is setting the 'short push detection' time from
t > 3 sec to t > 10 msec. Driver is then using short push irq.

This means that we don't detect button press if it is shorter than 10ms.
But we don't need any button state information in driver either. This is
why I decided to use the short push irq - is it Ok?

After this explanation - the gpio_keys_irq_isr seems to be doing exactly
what is needed for short push handling (as far as I can tell). Now it
boils down to question how we should bundle the MFD and gpio_keys
together?

Should I just fill the gpio_keys_platform_data for gpio_keys in MFD
driver? After my short browsing of existing MFD drivers I did not see
any other drivers doing that. This is why I wonder if this is a correct
approach?

Still if MFD is configuring the button presses the gpio_keys for this chip
should only be used if MFD is used, right? Hence the gpio_keys driver
should be instantiaed from MFD, right?

Another option would be using DT and adding gpio_keys node to MFD node
or to simple-bus node. But I have an idea that this would make Rob
unhappy :) I had lenghty discussion with him about declaring the PMIC
as interrupt-controller in device-tree - and I was kindly educated that
it was not the way to go :) I'd rather not started this discussion
again.

Finally, there may be cases when power button is not attached to PMIC
or is needing different configuration for 'short push'. This is why I
would prefer having own Kconfig option for this power-key driver. I am
not sure if it is easily doable if we use gpio_keys?

Can you please give me some further pointer on how I could use the
gpio_keys from MFD?

Best Regards
    Matti Vaittinen

--
To unsubscribe from this list: send the line "unsubscribe linux-clk" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Vaittinen, Matti June 21, 2018, 10:25 a.m. UTC | #3
On Wed, Jun 20, 2018 at 09:43:16AM +0300, Matti Vaittinen wrote:
> On Tue, Jun 19, 2018 at 10:50:28AM -0700, Dmitry Torokhov wrote:
> > Hi Matti,
> > 
> > On Tue, Jun 19, 2018 at 01:57:09PM +0300, Matti Vaittinen wrote:
> > > ROHM BD71837 PMIC power button driver providing power-key press
> > > information to user-space.
> > > 
> > > Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> > > ---
> > >  drivers/input/misc/Kconfig          | 10 +++++
> > >  drivers/input/misc/Makefile         |  1 +
> > >  drivers/input/misc/bd718xx-pwrkey.c | 90 +++++++++++++++++++++++++++++++++++++
> > >  3 files changed, 101 insertions(+)
> > >  create mode 100644 drivers/input/misc/bd718xx-pwrkey.c
> > > 
> > > +	platform_set_drvdata(pdev, pk);
> > > +	err = regmap_update_bits(pk->mfd->regmap,
> > > +				 BD71837_REG_PWRONCONFIG0,
> > > +				 BD718XX_PWRBTN_SHORT_PRESS_MASK,
> > > +				 BD718XX_PWRBTN_SHORT_PRESS_10MS);
> > 
> > This seems to be the only custom bit of set up in the driver, the rest I
> > think can easily be handled by gpio-keys.c in interrupt-only mode. Maybe
> > we could move this into MFD piece and drop this driver?

I did following in MFD driver - is this what you suggested:
+static struct gpio_keys_button btns[] = {
+       {
+               .code = KEY_POWER,
+               .gpio = -1,
+               .type = EV_KEY,
+       },
+};
+
+static struct gpio_keys_platform_data bd718xx_powerkey_data = {
+       .buttons = &btns[0],
+       .nbuttons = ARRAY_SIZE(btns),
+       .name = "bd718xx-pwrkey",
+};
+
+/* bd71837 multi function cells */
+
+static struct mfd_cell bd71837_mfd_cells[] = {
+       {
+               .name = "bd71837-clk",
+       }, {
+               .name = "gpio-keys",
+               .platform_data = &bd718xx_powerkey_data,
+               .pdata_size = sizeof(bd718xx_powerkey_data),
+       }, {

//snip

+static int bd71837_i2c_probe(struct i2c_client *i2c,
+                           const struct i2c_device_id *id)
+{

// snip

+       ret = regmap_add_irq_chip(bd71837->regmap, bd71837->chip_irq,
+               IRQF_ONESHOT, 0,
+               &bd71837_irq_chip, &bd71837->irq_data);
+       if (ret < 0) {
+               dev_err(bd71837->dev, "Failed to add irq_chip %d\n", ret);
+               goto err_out;
+       }
+       /* I think this should be done conditionally and only when pwrkey is used
+        * What would be the correct way to decide if we want to touch rhw button
+        * press detection times?
+        */
+       ret = regmap_update_bits(bd71837->regmap,
+                                BD71837_REG_PWRONCONFIG0,
+                                BD718XX_PWRBTN_PRESS_DURATION_MASK,
+                                BD718XX_PWRBTN_SHORT_PRESS_10MS);
+       if (ret < 0) {
+               dev_err(bd71837->dev, "Failed to configure button short press timeout %d\n", ret);
+               goto err_out;
+       }
+       /* According to BD71847 datasheet the HW default for long press detection
+        * is 10ms. So letch change it to 10 sec so we can actually get the short
+        * push and allow gracefull shut down
+        */
+       ret = regmap_update_bits(bd71837->regmap,
+                                BD71837_REG_PWRONCONFIG1,
+                                BD718XX_PWRBTN_PRESS_DURATION_MASK,
+                                BD718XX_PWRBTN_LONG_PRESS_10S);
+       if (ret < 0) {
+               dev_err(bd71837->dev, "Failed to configure button long press timeout %d\n", ret);
+               goto err_out;
+       }
+       btns[0].irq = regmap_irq_get_virq(bd71837->irq_data,
+                                         BD71837_INT_PWRBTN_S);
+
+       if (btns[0].irq < 0) {
+               ret = btns[0].irq;
+               goto err_out;
+       }
+
+       ret = mfd_add_devices(bd71837->dev, PLATFORM_DEVID_AUTO,
+                             bd71837_mfd_cells, ARRAY_SIZE(bd71837_mfd_cells),
+                             NULL, 0,
+                             regmap_irq_get_domain(bd71837->irq_data));

If looks is Ok I will send new patch with this approach at next week -
unless I get lost during the traditional midsummer festival here in
Finland.

> Finally, there may be cases when power button is not attached to PMIC
> or is needing different configuration for 'short push'. This is why I
> would prefer having own Kconfig option for this power-key driver. I am
> not sure if it is easily doable if we use gpio_keys?

What would be the preferred mechanism for skipping the button push duration
configurations (time it takes for PMIC to detect short or long push)? Or
setting the durations to values user(s) would prefer? To me this sounds again
something we could configure from DT. Would adding propereties
rohm,short-press-ms and rohm,long-press-ms sound reasonable? I will send
the first version with no option to skip/specify the configuration
(fixed 10ms for short press, 10 sec for long press) but I would like to add
support for specifying the duration as next step.

Br,
	Matti Vaittinen
--
To unsubscribe from this list: send the line "unsubscribe linux-clk" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dmitry Torokhov June 27, 2018, 12:21 a.m. UTC | #4
Hi Matti,

On Thu, Jun 21, 2018 at 01:25:47PM +0300, Matti Vaittinen wrote:
> On Wed, Jun 20, 2018 at 09:43:16AM +0300, Matti Vaittinen wrote:
> > On Tue, Jun 19, 2018 at 10:50:28AM -0700, Dmitry Torokhov wrote:
> > > Hi Matti,
> > > 
> > > On Tue, Jun 19, 2018 at 01:57:09PM +0300, Matti Vaittinen wrote:
> > > > ROHM BD71837 PMIC power button driver providing power-key press
> > > > information to user-space.
> > > > 
> > > > Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> > > > ---
> > > >  drivers/input/misc/Kconfig          | 10 +++++
> > > >  drivers/input/misc/Makefile         |  1 +
> > > >  drivers/input/misc/bd718xx-pwrkey.c | 90 +++++++++++++++++++++++++++++++++++++
> > > >  3 files changed, 101 insertions(+)
> > > >  create mode 100644 drivers/input/misc/bd718xx-pwrkey.c
> > > > 
> > > > +	platform_set_drvdata(pdev, pk);
> > > > +	err = regmap_update_bits(pk->mfd->regmap,
> > > > +				 BD71837_REG_PWRONCONFIG0,
> > > > +				 BD718XX_PWRBTN_SHORT_PRESS_MASK,
> > > > +				 BD718XX_PWRBTN_SHORT_PRESS_10MS);
> > > 
> > > This seems to be the only custom bit of set up in the driver, the rest I
> > > think can easily be handled by gpio-keys.c in interrupt-only mode. Maybe
> > > we could move this into MFD piece and drop this driver?
> 
> I did following in MFD driver - is this what you suggested:
> +static struct gpio_keys_button btns[] = {
> +       {
> +               .code = KEY_POWER,
> +               .gpio = -1,
> +               .type = EV_KEY,
> +       },
> +};
> +
> +static struct gpio_keys_platform_data bd718xx_powerkey_data = {
> +       .buttons = &btns[0],
> +       .nbuttons = ARRAY_SIZE(btns),
> +       .name = "bd718xx-pwrkey",
> +};
> +
> +/* bd71837 multi function cells */
> +
> +static struct mfd_cell bd71837_mfd_cells[] = {
> +       {
> +               .name = "bd71837-clk",
> +       }, {
> +               .name = "gpio-keys",
> +               .platform_data = &bd718xx_powerkey_data,
> +               .pdata_size = sizeof(bd718xx_powerkey_data),
> +       }, {

Yes, something like this should work. It will not expose the internal
kernel structure (the fact that we are using gpio-keys dirver) to handle
power button of this PMIC, which Rob would appreciate. And we can change
it later if you want to create a fancier driver.

> 
> //snip
> 
> +static int bd71837_i2c_probe(struct i2c_client *i2c,
> +                           const struct i2c_device_id *id)
> +{
> 
> // snip
> 
> +       ret = regmap_add_irq_chip(bd71837->regmap, bd71837->chip_irq,
> +               IRQF_ONESHOT, 0,
> +               &bd71837_irq_chip, &bd71837->irq_data);
> +       if (ret < 0) {
> +               dev_err(bd71837->dev, "Failed to add irq_chip %d\n", ret);
> +               goto err_out;
> +       }
> +       /* I think this should be done conditionally and only when pwrkey is used
> +        * What would be the correct way to decide if we want to touch rhw button
> +        * press detection times?
> +        */
> +       ret = regmap_update_bits(bd71837->regmap,
> +                                BD71837_REG_PWRONCONFIG0,
> +                                BD718XX_PWRBTN_PRESS_DURATION_MASK,
> +                                BD718XX_PWRBTN_SHORT_PRESS_10MS);
> +       if (ret < 0) {
> +               dev_err(bd71837->dev, "Failed to configure button short press timeout %d\n", ret);
> +               goto err_out;
> +       }
> +       /* According to BD71847 datasheet the HW default for long press detection
> +        * is 10ms. So letch change it to 10 sec so we can actually get the short
> +        * push and allow gracefull shut down
> +        */
> +       ret = regmap_update_bits(bd71837->regmap,
> +                                BD71837_REG_PWRONCONFIG1,
> +                                BD718XX_PWRBTN_PRESS_DURATION_MASK,
> +                                BD718XX_PWRBTN_LONG_PRESS_10S);
> +       if (ret < 0) {
> +               dev_err(bd71837->dev, "Failed to configure button long press timeout %d\n", ret);
> +               goto err_out;
> +       }
> +       btns[0].irq = regmap_irq_get_virq(bd71837->irq_data,
> +                                         BD71837_INT_PWRBTN_S);
> +
> +       if (btns[0].irq < 0) {
> +               ret = btns[0].irq;
> +               goto err_out;
> +       }
> +
> +       ret = mfd_add_devices(bd71837->dev, PLATFORM_DEVID_AUTO,
> +                             bd71837_mfd_cells, ARRAY_SIZE(bd71837_mfd_cells),
> +                             NULL, 0,
> +                             regmap_irq_get_domain(bd71837->irq_data));
> 
> If looks is Ok I will send new patch with this approach at next week -
> unless I get lost during the traditional midsummer festival here in
> Finland.
> 
> > Finally, there may be cases when power button is not attached to PMIC
> > or is needing different configuration for 'short push'. This is why I
> > would prefer having own Kconfig option for this power-key driver. I am
> > not sure if it is easily doable if we use gpio_keys?
> 
> What would be the preferred mechanism for skipping the button push duration
> configurations (time it takes for PMIC to detect short or long push)? Or
> setting the durations to values user(s) would prefer? To me this sounds again
> something we could configure from DT. Would adding propereties
> rohm,short-press-ms and rohm,long-press-ms sound reasonable? I will send
> the first version with no option to skip/specify the configuration
> (fixed 10ms for short press, 10 sec for long press) but I would like to add
> support for specifying the duration as next step.

This sounds OK to be but you'd need to get Rob's buy in here. The
properties should probably be in a sub-node of the PMIC device node.

Thanks.
diff mbox

Patch

diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 572b15fa18c2..694c05d3f9fb 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -96,6 +96,16 @@  config INPUT_ATMEL_CAPTOUCH
 	  To compile this driver as a module, choose M here: the
 	  module will be called atmel_captouch.
 
+config INPUT_BD718XX_PWRKEY
+	tristate "ROHM BD71837/BD71847 power key support"
+	depends on MFD_BD71837
+	help
+	  Say Y here if you want support for the power key usually found
+	  on boards using a ROHM BD71837/BD71847 compatible PMIC.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called bd718xx-pwrkey.
+
 config INPUT_BMA150
 	tristate "BMA150/SMB380 acceleration sensor support"
 	depends on I2C
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 72cde28649e2..ea5b81cbf2bf 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -20,6 +20,7 @@  obj-$(CONFIG_INPUT_ATI_REMOTE2)		+= ati_remote2.o
 obj-$(CONFIG_INPUT_ATLAS_BTNS)		+= atlas_btns.o
 obj-$(CONFIG_INPUT_ATMEL_CAPTOUCH)	+= atmel_captouch.o
 obj-$(CONFIG_INPUT_BMA150)		+= bma150.o
+obj-$(CONFIG_INPUT_BD718XX_PWRKEY)	+= bd718xx-pwrkey.o
 obj-$(CONFIG_INPUT_CM109)		+= cm109.o
 obj-$(CONFIG_INPUT_CMA3000)		+= cma3000_d0x.o
 obj-$(CONFIG_INPUT_CMA3000_I2C)		+= cma3000_d0x_i2c.o
diff --git a/drivers/input/misc/bd718xx-pwrkey.c b/drivers/input/misc/bd718xx-pwrkey.c
new file mode 100644
index 000000000000..e8ac9475c3cf
--- /dev/null
+++ b/drivers/input/misc/bd718xx-pwrkey.c
@@ -0,0 +1,90 @@ 
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 ROHM Semiconductors
+// bd718xx-pwrkey.c -- ROHM BD71837MWV and BD71847 power button driver
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/mfd/bd71837.h>
+
+struct bd718xx_pwrkey {
+	struct input_dev *idev;
+	struct bd71837 *mfd;
+	int irq;
+};
+
+static irqreturn_t button_irq(int irq, void *_priv)
+{
+	struct input_dev *idev = (struct input_dev *)_priv;
+
+	input_report_key(idev, KEY_POWER, 1);
+	input_sync(idev);
+	input_report_key(idev, KEY_POWER, 0);
+	input_sync(idev);
+
+	return IRQ_HANDLED;
+}
+
+static int bd718xx_pwr_btn_probe(struct platform_device *pdev)
+{
+	int err = -ENOMEM;
+	struct bd718xx_pwrkey *pk;
+
+	pk = devm_kzalloc(&pdev->dev, sizeof(*pk), GFP_KERNEL);
+	if (!pk)
+		goto err_out;
+
+	pk->mfd = dev_get_drvdata(pdev->dev.parent);
+
+	pk->idev = devm_input_allocate_device(&pdev->dev);
+	if (!pk->idev)
+		goto err_out;
+
+	pk->idev->name = "bd718xx-pwrkey";
+	pk->idev->phys = "bd718xx-pwrkey/input0";
+	pk->idev->dev.parent = &pdev->dev;
+
+	input_set_capability(pk->idev, EV_KEY, KEY_POWER);
+
+	err = platform_get_irq_byname(pdev, "pwr-btn-s");
+	if (err < 0) {
+		dev_err(&pdev->dev, "could not get power key interrupt\n");
+		goto err_out;
+	}
+
+	pk->irq = err;
+	err = devm_request_threaded_irq(&pdev->dev, pk->irq, NULL, &button_irq,
+					0, "bd718xx-pwrkey", pk);
+	if (err)
+		goto err_out;
+
+	platform_set_drvdata(pdev, pk);
+	err = regmap_update_bits(pk->mfd->regmap,
+				 BD71837_REG_PWRONCONFIG0,
+				 BD718XX_PWRBTN_SHORT_PRESS_MASK,
+				 BD718XX_PWRBTN_SHORT_PRESS_10MS);
+	if (err)
+		goto err_out;
+
+	err = input_register_device(pk->idev);
+
+err_out:
+
+	return err;
+}
+
+static struct platform_driver bd718xx_pwr_btn_driver = {
+	.probe	= bd718xx_pwr_btn_probe,
+	.driver = {
+		.name	= "bd718xx-pwrkey",
+	},
+};
+module_platform_driver(bd718xx_pwr_btn_driver);
+MODULE_DESCRIPTION("Power button driver for buttons connected to ROHM bd71837/bd71847 PMIC");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
+