xref: /linux/drivers/input/misc/pm8941-pwrkey.c (revision 3e51108c72e8adbcf3180ed40527a2a9d2d0123b)
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/ktime.h>
13 #include <linux/log2.h>
14 #include <linux/module.h>
15 #include <linux/of.h>
16 #include <linux/of_address.h>
17 #include <linux/platform_device.h>
18 #include <linux/reboot.h>
19 #include <linux/regmap.h>
20 
21 #define PON_REV2			0x01
22 
23 #define PON_SUBTYPE			0x05
24 
25 #define PON_SUBTYPE_PRIMARY		0x01
26 #define PON_SUBTYPE_SECONDARY		0x02
27 #define PON_SUBTYPE_1REG		0x03
28 #define PON_SUBTYPE_GEN2_PRIMARY	0x04
29 #define PON_SUBTYPE_GEN2_SECONDARY	0x05
30 #define PON_SUBTYPE_GEN3_PBS		0x08
31 #define PON_SUBTYPE_GEN3_HLOS		0x09
32 
33 #define PON_RT_STS			0x10
34 #define  PON_KPDPWR_N_SET		BIT(0)
35 #define  PON_RESIN_N_SET		BIT(1)
36 #define  PON_GEN3_RESIN_N_SET		BIT(6)
37 #define  PON_GEN3_KPDPWR_N_SET		BIT(7)
38 
39 #define PON_PS_HOLD_RST_CTL		0x5a
40 #define PON_PS_HOLD_RST_CTL2		0x5b
41 #define  PON_PS_HOLD_ENABLE		BIT(7)
42 #define  PON_PS_HOLD_TYPE_MASK		0x0f
43 #define  PON_PS_HOLD_TYPE_WARM_RESET	1
44 #define  PON_PS_HOLD_TYPE_SHUTDOWN	4
45 #define  PON_PS_HOLD_TYPE_HARD_RESET	7
46 
47 #define PON_PULL_CTL			0x70
48 #define  PON_KPDPWR_PULL_UP		BIT(1)
49 #define  PON_RESIN_PULL_UP		BIT(0)
50 
51 #define PON_DBC_CTL			0x71
52 #define  PON_DBC_DELAY_MASK_GEN1	0x7
53 #define  PON_DBC_DELAY_MASK_GEN2	0xf
54 #define  PON_DBC_SHIFT_GEN1		6
55 #define  PON_DBC_SHIFT_GEN2		14
56 
57 struct pm8941_data {
58 	unsigned int	pull_up_bit;
59 	unsigned int	status_bit;
60 	bool		supports_ps_hold_poff_config;
61 	bool		supports_debounce_config;
62 	bool		has_pon_pbs;
63 	const char	*name;
64 	const char	*phys;
65 };
66 
67 struct pm8941_pwrkey {
68 	struct device *dev;
69 	int irq;
70 	u32 baseaddr;
71 	u32 pon_pbs_baseaddr;
72 	struct regmap *regmap;
73 	struct input_dev *input;
74 
75 	unsigned int revision;
76 	unsigned int subtype;
77 	struct notifier_block reboot_notifier;
78 
79 	u32 code;
80 	u32 sw_debounce_time_us;
81 	ktime_t sw_debounce_end_time;
82 	bool last_status;
83 	const struct pm8941_data *data;
84 };
85 
pm8941_reboot_notify(struct notifier_block * nb,unsigned long code,void * unused)86 static int pm8941_reboot_notify(struct notifier_block *nb,
87 				unsigned long code, void *unused)
88 {
89 	struct pm8941_pwrkey *pwrkey = container_of(nb, struct pm8941_pwrkey,
90 						    reboot_notifier);
91 	unsigned int enable_reg;
92 	unsigned int reset_type;
93 	int error;
94 
95 	/* PMICs with revision 0 have the enable bit in same register as ctrl */
96 	if (pwrkey->revision == 0)
97 		enable_reg = PON_PS_HOLD_RST_CTL;
98 	else
99 		enable_reg = PON_PS_HOLD_RST_CTL2;
100 
101 	error = regmap_update_bits(pwrkey->regmap,
102 				   pwrkey->baseaddr + enable_reg,
103 				   PON_PS_HOLD_ENABLE,
104 				   0);
105 	if (error)
106 		dev_err(pwrkey->dev,
107 			"unable to clear ps hold reset enable: %d\n",
108 			error);
109 
110 	/*
111 	 * Updates of PON_PS_HOLD_ENABLE requires 3 sleep cycles between
112 	 * writes.
113 	 */
114 	usleep_range(100, 1000);
115 
116 	switch (code) {
117 	case SYS_HALT:
118 	case SYS_POWER_OFF:
119 		reset_type = PON_PS_HOLD_TYPE_SHUTDOWN;
120 		break;
121 	case SYS_RESTART:
122 	default:
123 		if (reboot_mode == REBOOT_WARM)
124 			reset_type = PON_PS_HOLD_TYPE_WARM_RESET;
125 		else
126 			reset_type = PON_PS_HOLD_TYPE_HARD_RESET;
127 		break;
128 	}
129 
130 	error = regmap_update_bits(pwrkey->regmap,
131 				   pwrkey->baseaddr + PON_PS_HOLD_RST_CTL,
132 				   PON_PS_HOLD_TYPE_MASK,
133 				   reset_type);
134 	if (error)
135 		dev_err(pwrkey->dev, "unable to set ps hold reset type: %d\n",
136 			error);
137 
138 	error = regmap_update_bits(pwrkey->regmap,
139 				   pwrkey->baseaddr + enable_reg,
140 				   PON_PS_HOLD_ENABLE,
141 				   PON_PS_HOLD_ENABLE);
142 	if (error)
143 		dev_err(pwrkey->dev, "unable to re-set enable: %d\n", error);
144 
145 	return NOTIFY_DONE;
146 }
147 
pm8941_pwrkey_irq(int irq,void * _data)148 static irqreturn_t pm8941_pwrkey_irq(int irq, void *_data)
149 {
150 	struct pm8941_pwrkey *pwrkey = _data;
151 	unsigned int sts;
152 	int err;
153 
154 	if (pwrkey->sw_debounce_time_us) {
155 		if (ktime_before(ktime_get(), pwrkey->sw_debounce_end_time)) {
156 			dev_dbg(pwrkey->dev,
157 				"ignoring key event received before debounce end %llu us\n",
158 				pwrkey->sw_debounce_end_time);
159 			return IRQ_HANDLED;
160 		}
161 	}
162 
163 	err = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_RT_STS, &sts);
164 	if (err)
165 		return IRQ_HANDLED;
166 
167 	sts &= pwrkey->data->status_bit;
168 
169 	if (pwrkey->sw_debounce_time_us && !sts)
170 		pwrkey->sw_debounce_end_time = ktime_add_us(ktime_get(),
171 						pwrkey->sw_debounce_time_us);
172 
173 	/*
174 	 * Simulate a press event in case a release event occurred without a
175 	 * corresponding press event.
176 	 */
177 	if (!pwrkey->last_status && !sts) {
178 		input_report_key(pwrkey->input, pwrkey->code, 1);
179 		input_sync(pwrkey->input);
180 	}
181 	pwrkey->last_status = sts;
182 
183 	input_report_key(pwrkey->input, pwrkey->code, sts);
184 	input_sync(pwrkey->input);
185 
186 	return IRQ_HANDLED;
187 }
188 
pm8941_pwrkey_sw_debounce_init(struct pm8941_pwrkey * pwrkey)189 static int pm8941_pwrkey_sw_debounce_init(struct pm8941_pwrkey *pwrkey)
190 {
191 	unsigned int val, addr, mask;
192 	int error;
193 
194 	if (pwrkey->data->has_pon_pbs && !pwrkey->pon_pbs_baseaddr) {
195 		dev_err(pwrkey->dev,
196 			"PON_PBS address missing, can't read HW debounce time\n");
197 		return 0;
198 	}
199 
200 	if (pwrkey->pon_pbs_baseaddr)
201 		addr = pwrkey->pon_pbs_baseaddr + PON_DBC_CTL;
202 	else
203 		addr = pwrkey->baseaddr + PON_DBC_CTL;
204 	error = regmap_read(pwrkey->regmap, addr, &val);
205 	if (error)
206 		return error;
207 
208 	if (pwrkey->subtype >= PON_SUBTYPE_GEN2_PRIMARY)
209 		mask = 0xf;
210 	else
211 		mask = 0x7;
212 
213 	pwrkey->sw_debounce_time_us =
214 		2 * USEC_PER_SEC / (1 << (mask - (val & mask)));
215 
216 	dev_dbg(pwrkey->dev, "SW debounce time = %u us\n",
217 		pwrkey->sw_debounce_time_us);
218 
219 	return 0;
220 }
221 
pm8941_pwrkey_suspend(struct device * dev)222 static int pm8941_pwrkey_suspend(struct device *dev)
223 {
224 	struct pm8941_pwrkey *pwrkey = dev_get_drvdata(dev);
225 
226 	if (device_may_wakeup(dev))
227 		enable_irq_wake(pwrkey->irq);
228 
229 	return 0;
230 }
231 
pm8941_pwrkey_resume(struct device * dev)232 static int pm8941_pwrkey_resume(struct device *dev)
233 {
234 	struct pm8941_pwrkey *pwrkey = dev_get_drvdata(dev);
235 
236 	if (device_may_wakeup(dev))
237 		disable_irq_wake(pwrkey->irq);
238 
239 	return 0;
240 }
241 
242 static DEFINE_SIMPLE_DEV_PM_OPS(pm8941_pwr_key_pm_ops,
243 				pm8941_pwrkey_suspend, pm8941_pwrkey_resume);
244 
pm8941_pwrkey_probe(struct platform_device * pdev)245 static int pm8941_pwrkey_probe(struct platform_device *pdev)
246 {
247 	struct pm8941_pwrkey *pwrkey;
248 	bool pull_up;
249 	struct device *parent;
250 	struct device_node *regmap_node;
251 	const __be32 *addr;
252 	u32 req_delay, mask, delay_shift;
253 	int error;
254 
255 	if (of_property_read_u32(pdev->dev.of_node, "debounce", &req_delay))
256 		req_delay = 15625;
257 
258 	if (req_delay > 2000000 || req_delay == 0) {
259 		dev_err(&pdev->dev, "invalid debounce time: %u\n", req_delay);
260 		return -EINVAL;
261 	}
262 
263 	pull_up = of_property_read_bool(pdev->dev.of_node, "bias-pull-up");
264 
265 	pwrkey = devm_kzalloc(&pdev->dev, sizeof(*pwrkey), GFP_KERNEL);
266 	if (!pwrkey)
267 		return -ENOMEM;
268 
269 	pwrkey->dev = &pdev->dev;
270 	pwrkey->data = of_device_get_match_data(&pdev->dev);
271 
272 	parent = pdev->dev.parent;
273 	regmap_node = pdev->dev.of_node;
274 	pwrkey->regmap = dev_get_regmap(parent, NULL);
275 	if (!pwrkey->regmap) {
276 		regmap_node = parent->of_node;
277 		/*
278 		 * We failed to get regmap for parent. Let's see if we are
279 		 * a child of pon node and read regmap and reg from its
280 		 * parent.
281 		 */
282 		pwrkey->regmap = dev_get_regmap(parent->parent, NULL);
283 		if (!pwrkey->regmap) {
284 			dev_err(&pdev->dev, "failed to locate regmap\n");
285 			return -ENODEV;
286 		}
287 	}
288 
289 	addr = of_get_address(regmap_node, 0, NULL, NULL);
290 	if (!addr) {
291 		dev_err(&pdev->dev, "reg property missing\n");
292 		return -EINVAL;
293 	}
294 	pwrkey->baseaddr = be32_to_cpup(addr);
295 
296 	if (pwrkey->data->has_pon_pbs) {
297 		/* PON_PBS base address is optional */
298 		addr = of_get_address(regmap_node, 1, NULL, NULL);
299 		if (addr)
300 			pwrkey->pon_pbs_baseaddr = be32_to_cpup(addr);
301 	}
302 
303 	pwrkey->irq = platform_get_irq(pdev, 0);
304 	if (pwrkey->irq < 0)
305 		return pwrkey->irq;
306 
307 	error = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_REV2,
308 			    &pwrkey->revision);
309 	if (error) {
310 		dev_err(&pdev->dev, "failed to read revision: %d\n", error);
311 		return error;
312 	}
313 
314 	error = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_SUBTYPE,
315 			    &pwrkey->subtype);
316 	if (error) {
317 		dev_err(&pdev->dev, "failed to read subtype: %d\n", error);
318 		return error;
319 	}
320 
321 	error = of_property_read_u32(pdev->dev.of_node, "linux,code",
322 				     &pwrkey->code);
323 	if (error) {
324 		dev_dbg(&pdev->dev,
325 			"no linux,code assuming power (%d)\n", error);
326 		pwrkey->code = KEY_POWER;
327 	}
328 
329 	pwrkey->input = devm_input_allocate_device(&pdev->dev);
330 	if (!pwrkey->input) {
331 		dev_dbg(&pdev->dev, "unable to allocate input device\n");
332 		return -ENOMEM;
333 	}
334 
335 	input_set_capability(pwrkey->input, EV_KEY, pwrkey->code);
336 
337 	pwrkey->input->name = pwrkey->data->name;
338 	pwrkey->input->phys = pwrkey->data->phys;
339 
340 	if (pwrkey->data->supports_debounce_config) {
341 		if (pwrkey->subtype >= PON_SUBTYPE_GEN2_PRIMARY) {
342 			mask = PON_DBC_DELAY_MASK_GEN2;
343 			delay_shift = PON_DBC_SHIFT_GEN2;
344 		} else {
345 			mask = PON_DBC_DELAY_MASK_GEN1;
346 			delay_shift = PON_DBC_SHIFT_GEN1;
347 		}
348 
349 		req_delay = (req_delay << delay_shift) / USEC_PER_SEC;
350 		req_delay = ilog2(req_delay);
351 
352 		error = regmap_update_bits(pwrkey->regmap,
353 					   pwrkey->baseaddr + PON_DBC_CTL,
354 					   mask,
355 					   req_delay);
356 		if (error) {
357 			dev_err(&pdev->dev, "failed to set debounce: %d\n",
358 				error);
359 			return error;
360 		}
361 	}
362 
363 	error = pm8941_pwrkey_sw_debounce_init(pwrkey);
364 	if (error)
365 		return error;
366 
367 	if (pwrkey->data->pull_up_bit) {
368 		error = regmap_update_bits(pwrkey->regmap,
369 					   pwrkey->baseaddr + PON_PULL_CTL,
370 					   pwrkey->data->pull_up_bit,
371 					   pull_up ? pwrkey->data->pull_up_bit :
372 						     0);
373 		if (error) {
374 			dev_err(&pdev->dev, "failed to set pull: %d\n", error);
375 			return error;
376 		}
377 	}
378 
379 	error = devm_request_threaded_irq(&pdev->dev, pwrkey->irq,
380 					  NULL, pm8941_pwrkey_irq,
381 					  IRQF_ONESHOT,
382 					  pwrkey->data->name, pwrkey);
383 	if (error) {
384 		dev_err(&pdev->dev, "failed requesting IRQ: %d\n", error);
385 		return error;
386 	}
387 
388 	error = input_register_device(pwrkey->input);
389 	if (error) {
390 		dev_err(&pdev->dev, "failed to register input device: %d\n",
391 			error);
392 		return error;
393 	}
394 
395 	if (pwrkey->data->supports_ps_hold_poff_config) {
396 		pwrkey->reboot_notifier.notifier_call = pm8941_reboot_notify;
397 		error = register_reboot_notifier(&pwrkey->reboot_notifier);
398 		if (error) {
399 			dev_err(&pdev->dev, "failed to register reboot notifier: %d\n",
400 				error);
401 			return error;
402 		}
403 	}
404 
405 	platform_set_drvdata(pdev, pwrkey);
406 	device_init_wakeup(&pdev->dev, 1);
407 
408 	return 0;
409 }
410 
pm8941_pwrkey_remove(struct platform_device * pdev)411 static void pm8941_pwrkey_remove(struct platform_device *pdev)
412 {
413 	struct pm8941_pwrkey *pwrkey = platform_get_drvdata(pdev);
414 
415 	if (pwrkey->data->supports_ps_hold_poff_config)
416 		unregister_reboot_notifier(&pwrkey->reboot_notifier);
417 }
418 
419 static const struct pm8941_data pwrkey_data = {
420 	.pull_up_bit = PON_KPDPWR_PULL_UP,
421 	.status_bit = PON_KPDPWR_N_SET,
422 	.name = "pm8941_pwrkey",
423 	.phys = "pm8941_pwrkey/input0",
424 	.supports_ps_hold_poff_config = true,
425 	.supports_debounce_config = true,
426 	.has_pon_pbs = false,
427 };
428 
429 static const struct pm8941_data resin_data = {
430 	.pull_up_bit = PON_RESIN_PULL_UP,
431 	.status_bit = PON_RESIN_N_SET,
432 	.name = "pm8941_resin",
433 	.phys = "pm8941_resin/input0",
434 	.supports_ps_hold_poff_config = true,
435 	.supports_debounce_config = true,
436 	.has_pon_pbs = false,
437 };
438 
439 static const struct pm8941_data pon_gen3_pwrkey_data = {
440 	.status_bit = PON_GEN3_KPDPWR_N_SET,
441 	.name = "pmic_pwrkey",
442 	.phys = "pmic_pwrkey/input0",
443 	.supports_ps_hold_poff_config = false,
444 	.supports_debounce_config = false,
445 	.has_pon_pbs = true,
446 };
447 
448 static const struct pm8941_data pon_gen3_resin_data = {
449 	.status_bit = PON_GEN3_RESIN_N_SET,
450 	.name = "pmic_resin",
451 	.phys = "pmic_resin/input0",
452 	.supports_ps_hold_poff_config = false,
453 	.supports_debounce_config = false,
454 	.has_pon_pbs = true,
455 };
456 
457 static const struct of_device_id pm8941_pwr_key_id_table[] = {
458 	{ .compatible = "qcom,pm8941-pwrkey", .data = &pwrkey_data },
459 	{ .compatible = "qcom,pm8941-resin", .data = &resin_data },
460 	{ .compatible = "qcom,pmk8350-pwrkey", .data = &pon_gen3_pwrkey_data },
461 	{ .compatible = "qcom,pmk8350-resin", .data = &pon_gen3_resin_data },
462 	{ }
463 };
464 MODULE_DEVICE_TABLE(of, pm8941_pwr_key_id_table);
465 
466 static struct platform_driver pm8941_pwrkey_driver = {
467 	.probe = pm8941_pwrkey_probe,
468 	.remove = pm8941_pwrkey_remove,
469 	.driver = {
470 		.name = "pm8941-pwrkey",
471 		.pm = pm_sleep_ptr(&pm8941_pwr_key_pm_ops),
472 		.of_match_table = of_match_ptr(pm8941_pwr_key_id_table),
473 	},
474 };
475 module_platform_driver(pm8941_pwrkey_driver);
476 
477 MODULE_DESCRIPTION("PM8941 Power Key driver");
478 MODULE_LICENSE("GPL v2");
479