From 2dc6f7518861ba5ec95a798149b8ea8ed12cd0f9 Mon Sep 17 00:00:00 2001 From: Marc Paolo Sosa Date: Thu, 5 Dec 2024 10:38:31 +0800 Subject: [PATCH] input: misc: add driver for max16150 MAX16150/MAX16169 nanoPower Pushbutton On/Off Controller Signed-off-by: Marc Paolo Sosa --- drivers/input/misc/Kconfig | 9 ++++ drivers/input/misc/Makefile | 1 + drivers/input/misc/max16150.c | 93 +++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 drivers/input/misc/max16150.c diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 6ba984d7f0b18..e4c3dd4cd2275 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -150,6 +150,15 @@ config INPUT_E3X0_BUTTON To compile this driver as a module, choose M here: the module will be called e3x0_button. +config INPUT_MAX16150_PWRBUTTON + bool "MAX16150/MAX16169 Pushbutton driver" + depends on OF_GPIO + help + This driver supports the MAX16150 and MAX16169 pushbutton + controllers, which are low-power devices with a switch + debouncer and built-in latch. Device bindings are specified + in the device tree. + config INPUT_PCSPKR tristate "PC Speaker support" depends on PCSPKR_PLATFORM diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 04296a4abe8e8..92b57e9522086 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -49,6 +49,7 @@ obj-$(CONFIG_INPUT_IQS7222) += iqs7222.o obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o obj-$(CONFIG_INPUT_KXTJ9) += kxtj9.o obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o +obj-$(CONFIG_INPUT_MAX16150_PWRBUTTON) += max16150.o obj-$(CONFIG_INPUT_MAX77650_ONKEY) += max77650-onkey.o obj-$(CONFIG_INPUT_MAX77693_HAPTIC) += max77693-haptic.o obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o diff --git a/drivers/input/misc/max16150.c b/drivers/input/misc/max16150.c new file mode 100644 index 0000000000000..1d6a47fa21814 --- /dev/null +++ b/drivers/input/misc/max16150.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Analog Devices MAX16150/MAX16169 Pushbutton Driver + * + * Copyright 2024 Analog Devices Inc. + */ + +#include +#include +#include +#include +#include + +#define GPIO_INT 17 +#define GPIO_CLR 27 + +static struct input_dev *max16150_input_dev; +static int irq_number; +static ktime_t last_time; +static const ktime_t short_pulse = 32 * NSEC_PER_MSEC; +static const ktime_t long_pulse = 128 * NSEC_PER_MSEC; + +static irqreturn_t max16150_isr(int irq, void *dev_id) +{ + ktime_t now = ktime_get(); + ktime_t duration = ktime_sub(now, last_time); + + if (duration >= long_pulse) + gpio_set_value(GPIO_CLR, 0); + + last_time = now; + return IRQ_HANDLED; +} + +static int max16150_probe(struct platform_device *pdev) +{ + struct input_dev *button; + int ret; + + button = devm_input_allocate_device(&pdev->dev); + if (!button) { + dev_err(&pdev->dev, "Can't allocate power button\n"); + return -ENOMEM; + } + + button->name = "max16150"; + button->phys = "max16150/input0"; + button->id.bustype = BUS_HOST; + input_set_capability(button, EV_KEY, KEY_POWER); + + ret = input_register_device(button); + if (ret) { + dev_err(&pdev->dev, "Can't register power button: %d\n", ret); + return ret; + } + + ret = devm_gpio_request_one(&pdev->dev, GPIO_CLR, GPIOF_OUT_INIT_HIGH, + "max16150_clr"); + if (ret) + return ret; + + irq_number = gpio_to_irq(GPIO_INT); + ret = devm_request_irq(&pdev->dev, irq_number, max16150_isr, + IRQF_TRIGGER_RISING, "max16150_irq", NULL); + if (ret) + return ret; + + last_time = ktime_get(); + platform_set_drvdata(pdev, button); + device_init_wakeup(&pdev->dev, true); + + return 0; +} + +static int max16150_remove(struct platform_device *pdev) +{ + input_unregister_device(max16150_input_dev); + return 0; +} + +static struct platform_driver max16150_driver = { + .probe = max16150_probe, + .remove = max16150_remove, + .driver = { + .name = "max16150", + }, +}; + +module_platform_driver(max16150_driver); + +MODULE_AUTHOR("Marc Paolo Sosa "); +MODULE_DESCRIPTION("MAX16150/MAX16169 Pushbutton Driver"); +MODULE_LICENSE("GPL");