xref: /linux/drivers/input/misc/pm8941-pwrkey.c (revision 0be3ff0c)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2010-2011, 2020-2021, The Linux Foundation. All rights reserved.
4  * Copyright (c) 2014, Sony Mobile Communications Inc.
5  */
6 
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>
14 #include <linux/of.h>
15 #include <linux/of_device.h>
16 #include <linux/platform_device.h>
17 #include <linux/reboot.h>
18 #include <linux/regmap.h>
19 
20 #define PON_REV2			0x01
21 
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)
27 
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_WARM_RESET	1
33 #define  PON_PS_HOLD_TYPE_SHUTDOWN	4
34 #define  PON_PS_HOLD_TYPE_HARD_RESET	7
35 
36 #define PON_PULL_CTL			0x70
37 #define  PON_KPDPWR_PULL_UP		BIT(1)
38 #define  PON_RESIN_PULL_UP		BIT(0)
39 
40 #define PON_DBC_CTL			0x71
41 #define  PON_DBC_DELAY_MASK		0x7
42 
43 struct pm8941_data {
44 	unsigned int	pull_up_bit;
45 	unsigned int	status_bit;
46 	bool		supports_ps_hold_poff_config;
47 	bool		supports_debounce_config;
48 	const char	*name;
49 	const char	*phys;
50 };
51 
52 struct pm8941_pwrkey {
53 	struct device *dev;
54 	int irq;
55 	u32 baseaddr;
56 	struct regmap *regmap;
57 	struct input_dev *input;
58 
59 	unsigned int revision;
60 	struct notifier_block reboot_notifier;
61 
62 	u32 code;
63 	const struct pm8941_data *data;
64 };
65 
66 static int pm8941_reboot_notify(struct notifier_block *nb,
67 				unsigned long code, void *unused)
68 {
69 	struct pm8941_pwrkey *pwrkey = container_of(nb, struct pm8941_pwrkey,
70 						    reboot_notifier);
71 	unsigned int enable_reg;
72 	unsigned int reset_type;
73 	int error;
74 
75 	/* PMICs with revision 0 have the enable bit in same register as ctrl */
76 	if (pwrkey->revision == 0)
77 		enable_reg = PON_PS_HOLD_RST_CTL;
78 	else
79 		enable_reg = PON_PS_HOLD_RST_CTL2;
80 
81 	error = regmap_update_bits(pwrkey->regmap,
82 				   pwrkey->baseaddr + enable_reg,
83 				   PON_PS_HOLD_ENABLE,
84 				   0);
85 	if (error)
86 		dev_err(pwrkey->dev,
87 			"unable to clear ps hold reset enable: %d\n",
88 			error);
89 
90 	/*
91 	 * Updates of PON_PS_HOLD_ENABLE requires 3 sleep cycles between
92 	 * writes.
93 	 */
94 	usleep_range(100, 1000);
95 
96 	switch (code) {
97 	case SYS_HALT:
98 	case SYS_POWER_OFF:
99 		reset_type = PON_PS_HOLD_TYPE_SHUTDOWN;
100 		break;
101 	case SYS_RESTART:
102 	default:
103 		if (reboot_mode == REBOOT_WARM)
104 			reset_type = PON_PS_HOLD_TYPE_WARM_RESET;
105 		else
106 			reset_type = PON_PS_HOLD_TYPE_HARD_RESET;
107 		break;
108 	}
109 
110 	error = regmap_update_bits(pwrkey->regmap,
111 				   pwrkey->baseaddr + PON_PS_HOLD_RST_CTL,
112 				   PON_PS_HOLD_TYPE_MASK,
113 				   reset_type);
114 	if (error)
115 		dev_err(pwrkey->dev, "unable to set ps hold reset type: %d\n",
116 			error);
117 
118 	error = regmap_update_bits(pwrkey->regmap,
119 				   pwrkey->baseaddr + enable_reg,
120 				   PON_PS_HOLD_ENABLE,
121 				   PON_PS_HOLD_ENABLE);
122 	if (error)
123 		dev_err(pwrkey->dev, "unable to re-set enable: %d\n", error);
124 
125 	return NOTIFY_DONE;
126 }
127 
128 static irqreturn_t pm8941_pwrkey_irq(int irq, void *_data)
129 {
130 	struct pm8941_pwrkey *pwrkey = _data;
131 	unsigned int sts;
132 	int error;
133 
134 	error = regmap_read(pwrkey->regmap,
135 			    pwrkey->baseaddr + PON_RT_STS, &sts);
136 	if (error)
137 		return IRQ_HANDLED;
138 
139 	input_report_key(pwrkey->input, pwrkey->code,
140 			 sts & pwrkey->data->status_bit);
141 	input_sync(pwrkey->input);
142 
143 	return IRQ_HANDLED;
144 }
145 
146 static int __maybe_unused pm8941_pwrkey_suspend(struct device *dev)
147 {
148 	struct pm8941_pwrkey *pwrkey = dev_get_drvdata(dev);
149 
150 	if (device_may_wakeup(dev))
151 		enable_irq_wake(pwrkey->irq);
152 
153 	return 0;
154 }
155 
156 static int __maybe_unused pm8941_pwrkey_resume(struct device *dev)
157 {
158 	struct pm8941_pwrkey *pwrkey = dev_get_drvdata(dev);
159 
160 	if (device_may_wakeup(dev))
161 		disable_irq_wake(pwrkey->irq);
162 
163 	return 0;
164 }
165 
166 static SIMPLE_DEV_PM_OPS(pm8941_pwr_key_pm_ops,
167 			 pm8941_pwrkey_suspend, pm8941_pwrkey_resume);
168 
169 static int pm8941_pwrkey_probe(struct platform_device *pdev)
170 {
171 	struct pm8941_pwrkey *pwrkey;
172 	bool pull_up;
173 	struct device *parent;
174 	u32 req_delay;
175 	int error;
176 
177 	if (of_property_read_u32(pdev->dev.of_node, "debounce", &req_delay))
178 		req_delay = 15625;
179 
180 	if (req_delay > 2000000 || req_delay == 0) {
181 		dev_err(&pdev->dev, "invalid debounce time: %u\n", req_delay);
182 		return -EINVAL;
183 	}
184 
185 	pull_up = of_property_read_bool(pdev->dev.of_node, "bias-pull-up");
186 
187 	pwrkey = devm_kzalloc(&pdev->dev, sizeof(*pwrkey), GFP_KERNEL);
188 	if (!pwrkey)
189 		return -ENOMEM;
190 
191 	pwrkey->dev = &pdev->dev;
192 	pwrkey->data = of_device_get_match_data(&pdev->dev);
193 
194 	parent = pdev->dev.parent;
195 	pwrkey->regmap = dev_get_regmap(parent, NULL);
196 	if (!pwrkey->regmap) {
197 		/*
198 		 * We failed to get regmap for parent. Let's see if we are
199 		 * a child of pon node and read regmap and reg from its
200 		 * parent.
201 		 */
202 		pwrkey->regmap = dev_get_regmap(parent->parent, NULL);
203 		if (!pwrkey->regmap) {
204 			dev_err(&pdev->dev, "failed to locate regmap\n");
205 			return -ENODEV;
206 		}
207 
208 		error = of_property_read_u32(parent->of_node,
209 					     "reg", &pwrkey->baseaddr);
210 	} else {
211 		error = of_property_read_u32(pdev->dev.of_node, "reg",
212 					     &pwrkey->baseaddr);
213 	}
214 	if (error)
215 		return error;
216 
217 	pwrkey->irq = platform_get_irq(pdev, 0);
218 	if (pwrkey->irq < 0)
219 		return pwrkey->irq;
220 
221 	error = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_REV2,
222 			    &pwrkey->revision);
223 	if (error) {
224 		dev_err(&pdev->dev, "failed to set debounce: %d\n", error);
225 		return error;
226 	}
227 
228 	error = of_property_read_u32(pdev->dev.of_node, "linux,code",
229 				     &pwrkey->code);
230 	if (error) {
231 		dev_dbg(&pdev->dev,
232 			"no linux,code assuming power (%d)\n", error);
233 		pwrkey->code = KEY_POWER;
234 	}
235 
236 	pwrkey->input = devm_input_allocate_device(&pdev->dev);
237 	if (!pwrkey->input) {
238 		dev_dbg(&pdev->dev, "unable to allocate input device\n");
239 		return -ENOMEM;
240 	}
241 
242 	input_set_capability(pwrkey->input, EV_KEY, pwrkey->code);
243 
244 	pwrkey->input->name = pwrkey->data->name;
245 	pwrkey->input->phys = pwrkey->data->phys;
246 
247 	if (pwrkey->data->supports_debounce_config) {
248 		req_delay = (req_delay << 6) / USEC_PER_SEC;
249 		req_delay = ilog2(req_delay);
250 
251 		error = regmap_update_bits(pwrkey->regmap,
252 					   pwrkey->baseaddr + PON_DBC_CTL,
253 					   PON_DBC_DELAY_MASK,
254 					   req_delay);
255 		if (error) {
256 			dev_err(&pdev->dev, "failed to set debounce: %d\n",
257 				error);
258 			return error;
259 		}
260 	}
261 
262 	if (pwrkey->data->pull_up_bit) {
263 		error = regmap_update_bits(pwrkey->regmap,
264 					   pwrkey->baseaddr + PON_PULL_CTL,
265 					   pwrkey->data->pull_up_bit,
266 					   pull_up ? pwrkey->data->pull_up_bit :
267 						     0);
268 		if (error) {
269 			dev_err(&pdev->dev, "failed to set pull: %d\n", error);
270 			return error;
271 		}
272 	}
273 
274 	error = devm_request_threaded_irq(&pdev->dev, pwrkey->irq,
275 					  NULL, pm8941_pwrkey_irq,
276 					  IRQF_ONESHOT,
277 					  pwrkey->data->name, pwrkey);
278 	if (error) {
279 		dev_err(&pdev->dev, "failed requesting IRQ: %d\n", error);
280 		return error;
281 	}
282 
283 	error = input_register_device(pwrkey->input);
284 	if (error) {
285 		dev_err(&pdev->dev, "failed to register input device: %d\n",
286 			error);
287 		return error;
288 	}
289 
290 	if (pwrkey->data->supports_ps_hold_poff_config) {
291 		pwrkey->reboot_notifier.notifier_call = pm8941_reboot_notify;
292 		error = register_reboot_notifier(&pwrkey->reboot_notifier);
293 		if (error) {
294 			dev_err(&pdev->dev, "failed to register reboot notifier: %d\n",
295 				error);
296 			return error;
297 		}
298 	}
299 
300 	platform_set_drvdata(pdev, pwrkey);
301 	device_init_wakeup(&pdev->dev, 1);
302 
303 	return 0;
304 }
305 
306 static int pm8941_pwrkey_remove(struct platform_device *pdev)
307 {
308 	struct pm8941_pwrkey *pwrkey = platform_get_drvdata(pdev);
309 
310 	if (pwrkey->data->supports_ps_hold_poff_config)
311 		unregister_reboot_notifier(&pwrkey->reboot_notifier);
312 
313 	return 0;
314 }
315 
316 static const struct pm8941_data pwrkey_data = {
317 	.pull_up_bit = PON_KPDPWR_PULL_UP,
318 	.status_bit = PON_KPDPWR_N_SET,
319 	.name = "pm8941_pwrkey",
320 	.phys = "pm8941_pwrkey/input0",
321 	.supports_ps_hold_poff_config = true,
322 	.supports_debounce_config = true,
323 };
324 
325 static const struct pm8941_data resin_data = {
326 	.pull_up_bit = PON_RESIN_PULL_UP,
327 	.status_bit = PON_RESIN_N_SET,
328 	.name = "pm8941_resin",
329 	.phys = "pm8941_resin/input0",
330 	.supports_ps_hold_poff_config = true,
331 	.supports_debounce_config = true,
332 };
333 
334 static const struct pm8941_data pon_gen3_pwrkey_data = {
335 	.status_bit = PON_GEN3_KPDPWR_N_SET,
336 	.name = "pmic_pwrkey",
337 	.phys = "pmic_pwrkey/input0",
338 	.supports_ps_hold_poff_config = false,
339 	.supports_debounce_config = false,
340 };
341 
342 static const struct pm8941_data pon_gen3_resin_data = {
343 	.status_bit = PON_GEN3_RESIN_N_SET,
344 	.name = "pmic_resin",
345 	.phys = "pmic_resin/input0",
346 	.supports_ps_hold_poff_config = false,
347 	.supports_debounce_config = false,
348 };
349 
350 static const struct of_device_id pm8941_pwr_key_id_table[] = {
351 	{ .compatible = "qcom,pm8941-pwrkey", .data = &pwrkey_data },
352 	{ .compatible = "qcom,pm8941-resin", .data = &resin_data },
353 	{ .compatible = "qcom,pmk8350-pwrkey", .data = &pon_gen3_pwrkey_data },
354 	{ .compatible = "qcom,pmk8350-resin", .data = &pon_gen3_resin_data },
355 	{ }
356 };
357 MODULE_DEVICE_TABLE(of, pm8941_pwr_key_id_table);
358 
359 static struct platform_driver pm8941_pwrkey_driver = {
360 	.probe = pm8941_pwrkey_probe,
361 	.remove = pm8941_pwrkey_remove,
362 	.driver = {
363 		.name = "pm8941-pwrkey",
364 		.pm = &pm8941_pwr_key_pm_ops,
365 		.of_match_table = of_match_ptr(pm8941_pwr_key_id_table),
366 	},
367 };
368 module_platform_driver(pm8941_pwrkey_driver);
369 
370 MODULE_DESCRIPTION("PM8941 Power Key driver");
371 MODULE_LICENSE("GPL v2");
372