Skip to content

Commit

Permalink
input: misc: add driver for max16150
Browse files Browse the repository at this point in the history
MAX16150/MAX16169 nanoPower Pushbutton On/Off Controller

Signed-off-by: Marc Paolo Sosa <[email protected]>
  • Loading branch information
mrcsosa committed Jan 13, 2025
1 parent 3a603d9 commit 2dc6f75
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 0 deletions.
9 changes: 9 additions & 0 deletions drivers/input/misc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions drivers/input/misc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
93 changes: 93 additions & 0 deletions drivers/input/misc/max16150.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Analog Devices MAX16150/MAX16169 Pushbutton Driver
*
* Copyright 2024 Analog Devices Inc.
*/

#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/platform_device.h>

#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 <[email protected]>");
MODULE_DESCRIPTION("MAX16150/MAX16169 Pushbutton Driver");
MODULE_LICENSE("GPL");

0 comments on commit 2dc6f75

Please sign in to comment.