1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2010-2011, 2020-2021, The Linux Foundation. All rights reserved.
4 * Copyright (c) 2014, Sony Mobile Communications Inc.
7 #include <linux/delay.h>
8 #include <linux/errno.h>
9 #include <linux/input.h>
10 #include <linux/interrupt.h>
11 #include <linux/kernel.h>
12 #include <linux/log2.h>
13 #include <linux/module.h>
15 #include <linux/of_device.h>
16 #include <linux/platform_device.h>
17 #include <linux/reboot.h>
18 #include <linux/regmap.h>
22 #define PON_RT_STS 0x10
23 #define PON_KPDPWR_N_SET BIT(0)
24 #define PON_RESIN_N_SET BIT(1)
25 #define PON_GEN3_RESIN_N_SET BIT(6)
26 #define PON_GEN3_KPDPWR_N_SET BIT(7)
28 #define PON_PS_HOLD_RST_CTL 0x5a
29 #define PON_PS_HOLD_RST_CTL2 0x5b
30 #define PON_PS_HOLD_ENABLE BIT(7)
31 #define PON_PS_HOLD_TYPE_MASK 0x0f
32 #define PON_PS_HOLD_TYPE_SHUTDOWN 4
33 #define PON_PS_HOLD_TYPE_HARD_RESET 7
35 #define PON_PULL_CTL 0x70
36 #define PON_KPDPWR_PULL_UP BIT(1)
37 #define PON_RESIN_PULL_UP BIT(0)
39 #define PON_DBC_CTL 0x71
40 #define PON_DBC_DELAY_MASK 0x7
43 unsigned int pull_up_bit;
44 unsigned int status_bit;
45 bool supports_ps_hold_poff_config;
46 bool supports_debounce_config;
51 struct pm8941_pwrkey {
55 struct regmap *regmap;
56 struct input_dev *input;
58 unsigned int revision;
59 struct notifier_block reboot_notifier;
62 const struct pm8941_data *data;
65 static int pm8941_reboot_notify(struct notifier_block *nb,
66 unsigned long code, void *unused)
68 struct pm8941_pwrkey *pwrkey = container_of(nb, struct pm8941_pwrkey,
70 unsigned int enable_reg;
71 unsigned int reset_type;
74 /* PMICs with revision 0 have the enable bit in same register as ctrl */
75 if (pwrkey->revision == 0)
76 enable_reg = PON_PS_HOLD_RST_CTL;
78 enable_reg = PON_PS_HOLD_RST_CTL2;
80 error = regmap_update_bits(pwrkey->regmap,
81 pwrkey->baseaddr + enable_reg,
86 "unable to clear ps hold reset enable: %d\n",
90 * Updates of PON_PS_HOLD_ENABLE requires 3 sleep cycles between
93 usleep_range(100, 1000);
98 reset_type = PON_PS_HOLD_TYPE_SHUTDOWN;
102 reset_type = PON_PS_HOLD_TYPE_HARD_RESET;
106 error = regmap_update_bits(pwrkey->regmap,
107 pwrkey->baseaddr + PON_PS_HOLD_RST_CTL,
108 PON_PS_HOLD_TYPE_MASK,
111 dev_err(pwrkey->dev, "unable to set ps hold reset type: %d\n",
114 error = regmap_update_bits(pwrkey->regmap,
115 pwrkey->baseaddr + enable_reg,
119 dev_err(pwrkey->dev, "unable to re-set enable: %d\n", error);
124 static irqreturn_t pm8941_pwrkey_irq(int irq, void *_data)
126 struct pm8941_pwrkey *pwrkey = _data;
130 error = regmap_read(pwrkey->regmap,
131 pwrkey->baseaddr + PON_RT_STS, &sts);
135 input_report_key(pwrkey->input, pwrkey->code,
136 sts & pwrkey->data->status_bit);
137 input_sync(pwrkey->input);
142 static int __maybe_unused pm8941_pwrkey_suspend(struct device *dev)
144 struct pm8941_pwrkey *pwrkey = dev_get_drvdata(dev);
146 if (device_may_wakeup(dev))
147 enable_irq_wake(pwrkey->irq);
152 static int __maybe_unused pm8941_pwrkey_resume(struct device *dev)
154 struct pm8941_pwrkey *pwrkey = dev_get_drvdata(dev);
156 if (device_may_wakeup(dev))
157 disable_irq_wake(pwrkey->irq);
162 static SIMPLE_DEV_PM_OPS(pm8941_pwr_key_pm_ops,
163 pm8941_pwrkey_suspend, pm8941_pwrkey_resume);
165 static int pm8941_pwrkey_probe(struct platform_device *pdev)
167 struct pm8941_pwrkey *pwrkey;
169 struct device *parent;
173 if (of_property_read_u32(pdev->dev.of_node, "debounce", &req_delay))
176 if (req_delay > 2000000 || req_delay == 0) {
177 dev_err(&pdev->dev, "invalid debounce time: %u\n", req_delay);
181 pull_up = of_property_read_bool(pdev->dev.of_node, "bias-pull-up");
183 pwrkey = devm_kzalloc(&pdev->dev, sizeof(*pwrkey), GFP_KERNEL);
187 pwrkey->dev = &pdev->dev;
188 pwrkey->data = of_device_get_match_data(&pdev->dev);
190 parent = pdev->dev.parent;
191 pwrkey->regmap = dev_get_regmap(parent, NULL);
192 if (!pwrkey->regmap) {
194 * We failed to get regmap for parent. Let's see if we are
195 * a child of pon node and read regmap and reg from its
198 pwrkey->regmap = dev_get_regmap(parent->parent, NULL);
199 if (!pwrkey->regmap) {
200 dev_err(&pdev->dev, "failed to locate regmap\n");
204 error = of_property_read_u32(parent->of_node,
205 "reg", &pwrkey->baseaddr);
207 error = of_property_read_u32(pdev->dev.of_node, "reg",
213 pwrkey->irq = platform_get_irq(pdev, 0);
217 error = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_REV2,
220 dev_err(&pdev->dev, "failed to set debounce: %d\n", error);
224 error = of_property_read_u32(pdev->dev.of_node, "linux,code",
228 "no linux,code assuming power (%d)\n", error);
229 pwrkey->code = KEY_POWER;
232 pwrkey->input = devm_input_allocate_device(&pdev->dev);
233 if (!pwrkey->input) {
234 dev_dbg(&pdev->dev, "unable to allocate input device\n");
238 input_set_capability(pwrkey->input, EV_KEY, pwrkey->code);
240 pwrkey->input->name = pwrkey->data->name;
241 pwrkey->input->phys = pwrkey->data->phys;
243 if (pwrkey->data->supports_debounce_config) {
244 req_delay = (req_delay << 6) / USEC_PER_SEC;
245 req_delay = ilog2(req_delay);
247 error = regmap_update_bits(pwrkey->regmap,
248 pwrkey->baseaddr + PON_DBC_CTL,
252 dev_err(&pdev->dev, "failed to set debounce: %d\n",
258 if (pwrkey->data->pull_up_bit) {
259 error = regmap_update_bits(pwrkey->regmap,
260 pwrkey->baseaddr + PON_PULL_CTL,
261 pwrkey->data->pull_up_bit,
262 pull_up ? pwrkey->data->pull_up_bit :
265 dev_err(&pdev->dev, "failed to set pull: %d\n", error);
270 error = devm_request_threaded_irq(&pdev->dev, pwrkey->irq,
271 NULL, pm8941_pwrkey_irq,
273 pwrkey->data->name, pwrkey);
275 dev_err(&pdev->dev, "failed requesting IRQ: %d\n", error);
279 error = input_register_device(pwrkey->input);
281 dev_err(&pdev->dev, "failed to register input device: %d\n",
286 if (pwrkey->data->supports_ps_hold_poff_config) {
287 pwrkey->reboot_notifier.notifier_call = pm8941_reboot_notify;
288 error = register_reboot_notifier(&pwrkey->reboot_notifier);
290 dev_err(&pdev->dev, "failed to register reboot notifier: %d\n",
296 platform_set_drvdata(pdev, pwrkey);
297 device_init_wakeup(&pdev->dev, 1);
302 static int pm8941_pwrkey_remove(struct platform_device *pdev)
304 struct pm8941_pwrkey *pwrkey = platform_get_drvdata(pdev);
306 if (pwrkey->data->supports_ps_hold_poff_config)
307 unregister_reboot_notifier(&pwrkey->reboot_notifier);
312 static const struct pm8941_data pwrkey_data = {
313 .pull_up_bit = PON_KPDPWR_PULL_UP,
314 .status_bit = PON_KPDPWR_N_SET,
315 .name = "pm8941_pwrkey",
316 .phys = "pm8941_pwrkey/input0",
317 .supports_ps_hold_poff_config = true,
318 .supports_debounce_config = true,
321 static const struct pm8941_data resin_data = {
322 .pull_up_bit = PON_RESIN_PULL_UP,
323 .status_bit = PON_RESIN_N_SET,
324 .name = "pm8941_resin",
325 .phys = "pm8941_resin/input0",
326 .supports_ps_hold_poff_config = true,
327 .supports_debounce_config = true,
330 static const struct pm8941_data pon_gen3_pwrkey_data = {
331 .status_bit = PON_GEN3_KPDPWR_N_SET,
332 .name = "pmic_pwrkey",
333 .phys = "pmic_pwrkey/input0",
334 .supports_ps_hold_poff_config = false,
335 .supports_debounce_config = false,
338 static const struct pm8941_data pon_gen3_resin_data = {
339 .status_bit = PON_GEN3_RESIN_N_SET,
340 .name = "pmic_resin",
341 .phys = "pmic_resin/input0",
342 .supports_ps_hold_poff_config = false,
343 .supports_debounce_config = false,
346 static const struct of_device_id pm8941_pwr_key_id_table[] = {
347 { .compatible = "qcom,pm8941-pwrkey", .data = &pwrkey_data },
348 { .compatible = "qcom,pm8941-resin", .data = &resin_data },
349 { .compatible = "qcom,pmk8350-pwrkey", .data = &pon_gen3_pwrkey_data },
350 { .compatible = "qcom,pmk8350-resin", .data = &pon_gen3_resin_data },
353 MODULE_DEVICE_TABLE(of, pm8941_pwr_key_id_table);
355 static struct platform_driver pm8941_pwrkey_driver = {
356 .probe = pm8941_pwrkey_probe,
357 .remove = pm8941_pwrkey_remove,
359 .name = "pm8941-pwrkey",
360 .pm = &pm8941_pwr_key_pm_ops,
361 .of_match_table = of_match_ptr(pm8941_pwr_key_id_table),
364 module_platform_driver(pm8941_pwrkey_driver);
366 MODULE_DESCRIPTION("PM8941 Power Key driver");
367 MODULE_LICENSE("GPL v2");