1 // SPDX-License-Identifier: GPL-2.0-only
3 * CPCAP Power Button Input Driver
5 * Copyright (C) 2017 Sebastian Reichel <sre@kernel.org>
8 #include <linux/module.h>
9 #include <linux/init.h>
10 #include <linux/kernel.h>
11 #include <linux/errno.h>
12 #include <linux/input.h>
13 #include <linux/interrupt.h>
14 #include <linux/regmap.h>
16 #include <linux/platform_device.h>
17 #include <linux/mfd/motorola-cpcap.h>
19 #define CPCAP_IRQ_ON 23
20 #define CPCAP_IRQ_ON_BITMASK (1 << (CPCAP_IRQ_ON % 16))
22 struct cpcap_power_button
{
23 struct regmap
*regmap
;
24 struct input_dev
*idev
;
28 static irqreturn_t
powerbutton_irq(int irq
, void *_button
)
30 struct cpcap_power_button
*button
= _button
;
33 val
= cpcap_sense_virq(button
->regmap
, irq
);
35 dev_err(button
->dev
, "irq read failed: %d", val
);
39 pm_wakeup_event(button
->dev
, 0);
40 input_report_key(button
->idev
, KEY_POWER
, val
);
41 input_sync(button
->idev
);
46 static int cpcap_power_button_probe(struct platform_device
*pdev
)
48 struct cpcap_power_button
*button
;
52 irq
= platform_get_irq(pdev
, 0);
56 button
= devm_kmalloc(&pdev
->dev
, sizeof(*button
), GFP_KERNEL
);
60 button
->idev
= devm_input_allocate_device(&pdev
->dev
);
64 button
->regmap
= dev_get_regmap(pdev
->dev
.parent
, NULL
);
68 button
->dev
= &pdev
->dev
;
70 button
->idev
->name
= "cpcap-pwrbutton";
71 button
->idev
->phys
= "cpcap-pwrbutton/input0";
72 input_set_capability(button
->idev
, EV_KEY
, KEY_POWER
);
74 err
= devm_request_threaded_irq(&pdev
->dev
, irq
, NULL
,
75 powerbutton_irq
, IRQF_ONESHOT
, "cpcap_pwrbutton", button
);
77 dev_err(&pdev
->dev
, "IRQ request failed: %d\n", err
);
81 err
= input_register_device(button
->idev
);
83 dev_err(&pdev
->dev
, "Input register failed: %d\n", err
);
87 device_init_wakeup(&pdev
->dev
, true);
93 static const struct of_device_id cpcap_pwrbutton_dt_match_table
[] = {
94 { .compatible
= "motorola,cpcap-pwrbutton" },
97 MODULE_DEVICE_TABLE(of
, cpcap_pwrbutton_dt_match_table
);
100 static struct platform_driver cpcap_power_button_driver
= {
101 .probe
= cpcap_power_button_probe
,
103 .name
= "cpcap-pwrbutton",
104 .of_match_table
= of_match_ptr(cpcap_pwrbutton_dt_match_table
),
107 module_platform_driver(cpcap_power_button_driver
);
109 MODULE_ALIAS("platform:cpcap-pwrbutton");
110 MODULE_DESCRIPTION("CPCAP Power Button");
111 MODULE_LICENSE("GPL");
112 MODULE_AUTHOR("Sebastian Reichel <sre@kernel.org>");