-
Notifications
You must be signed in to change notification settings - Fork 855
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
input: misc: add driver for max16150
MAX16150/MAX16169 nanoPower Pushbutton On/Off Controller Signed-off-by: Marc Paolo Sosa <[email protected]>
- Loading branch information
Showing
3 changed files
with
103 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); |