• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * axp20x power button driver.
3  *
4  * Copyright (C) 2013 Carlo Caione <carlo@caione.org>
5  *
6  * This file is subject to the terms and conditions of the GNU General
7  * Public License. See the file "COPYING" in the main directory of this
8  * archive for more details.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  */
15 #define pr_fmt(x) KBUILD_MODNAME ": " x
16 
17 #include <linux/errno.h>
18 #include <linux/irq.h>
19 #include <linux/init.h>
20 #include <linux/input.h>
21 #include <linux/interrupt.h>
22 #include <linux/kernel.h>
23 #include <power/axp2101.h>
24 #include <linux/module.h>
25 #include <linux/platform_device.h>
26 #include <linux/regmap.h>
27 #include <linux/slab.h>
28 #include <linux/of.h>
29 
30 #define AXP20X_PEK_STARTUP_MASK		(0x03)
31 #define AXP20X_PEK_SHUTDOWN_MASK	(0x0c)
32 
33 #define axp2101_PONLEVEL        (0x27)
34 #define axp2101_PWROFF_EN       (0x22)
35 #define axp2101_PWR_TIME_CTRL   (0x25)
36 #define axp2101_VBAT_H          (0x34)
37 #define axp2101_INTSTS2         (0x49)
38 
39 #define IRQ_DBR_BIT             BIT(0)
40 #define IRQ_DBF_BIT             BIT(1)
41 
42 struct pk_dts {
43 	uint32_t pmu_powkey_off_time;
44 	uint32_t pmu_powkey_off_func;
45 	uint32_t pmu_powkey_off_en;
46 	uint32_t pmu_powkey_off_delay_time;
47 	uint32_t pmu_powkey_long_time;
48 	uint32_t pmu_powkey_on_time;
49 	uint32_t pmu_pwrok_time;
50 	uint32_t pmu_pwrnoe_time;
51 	uint32_t pmu_powkey_wakeup_rising;
52 	uint32_t pmu_powkey_wakeup_falling;
53 };
54 
55 struct axp20x_pek {
56 	struct axp20x_dev *axp20x;
57 	struct input_dev *input;
58 	struct pk_dts pk_dts;
59 	int irq_dbr;
60 	int irq_dbf;
61 };
62 
63 struct axp20x_time {
64 	unsigned int time;
65 	unsigned int idx;
66 };
67 
68 static const struct axp20x_time startup_time[] = {
69 	{ .time = 128,  .idx = 0 },
70 	{ .time = 512,  .idx = 1 },
71 	{ .time = 1000, .idx = 2 },
72 	{ .time = 2000, .idx = 3 },
73 };
74 
75 static const struct axp20x_time shutdown_time[] = {
76 	{ .time = 4000,  .idx = 0 },
77 	{ .time = 6000,  .idx = 1 },
78 	{ .time = 8000,  .idx = 2 },
79 	{ .time = 10000, .idx = 3 },
80 };
81 
82 #define AXP_OF_PROP_READ(name, def_value)                             \
83 	do {                                                          \
84 		if (of_property_read_u32(node, #name, &pk_dts->name)) \
85 			pk_dts->name = def_value;                     \
86 	} while (0)
87 
axp_powerkey_dt_parse(struct device_node * node,struct pk_dts * pk_dts)88 static int axp_powerkey_dt_parse(struct device_node *node,
89 				 struct pk_dts *pk_dts)
90 {
91 	if (!of_device_is_available(node)) {
92 		pr_err("%s: failed\n", __func__);
93 		return -1;
94 	}
95 
96 	AXP_OF_PROP_READ(pmu_powkey_off_time,       6000);
97 	AXP_OF_PROP_READ(pmu_powkey_off_func,       0);
98 	AXP_OF_PROP_READ(pmu_powkey_off_en,         1);
99 	AXP_OF_PROP_READ(pmu_powkey_off_delay_time, 0);
100 	AXP_OF_PROP_READ(pmu_powkey_long_time,      1500);
101 	AXP_OF_PROP_READ(pmu_powkey_on_time,        1000);
102 	AXP_OF_PROP_READ(pmu_pwrok_time,            64);
103 	AXP_OF_PROP_READ(pmu_pwrnoe_time,           2000);
104 
105 	pk_dts->pmu_powkey_wakeup_rising =
106 		of_property_read_bool(node, "wakeup_rising");
107 	pk_dts->pmu_powkey_wakeup_falling =
108 		of_property_read_bool(node, "wakeup_falling");
109 
110 	return 0;
111 }
112 
113 struct axp20x_pek_ext_attr {
114 	const struct axp20x_time *p_time;
115 	unsigned int mask;
116 };
117 
118 static struct axp20x_pek_ext_attr axp20x_pek_startup_ext_attr = {
119 	.p_time	= startup_time,
120 	.mask	= AXP20X_PEK_STARTUP_MASK,
121 };
122 
123 static struct axp20x_pek_ext_attr axp20x_pek_shutdown_ext_attr = {
124 	.p_time	= shutdown_time,
125 	.mask	= AXP20X_PEK_SHUTDOWN_MASK,
126 };
127 
get_axp_ext_attr(struct device_attribute * attr)128 static struct axp20x_pek_ext_attr *get_axp_ext_attr(struct device_attribute *attr)
129 {
130 	return container_of(attr, struct dev_ext_attribute, attr)->var;
131 }
132 
axp20x_show_ext_attr(struct device * dev,struct device_attribute * attr,char * buf)133 static ssize_t axp20x_show_ext_attr(struct device *dev,
134 				    struct device_attribute *attr, char *buf)
135 {
136 	struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
137 	struct axp20x_pek_ext_attr *axp20x_ea = get_axp_ext_attr(attr);
138 	unsigned int val;
139 	int ret, i;
140 
141 	ret = regmap_read(axp20x_pek->axp20x->regmap, axp2101_PONLEVEL, &val);
142 	if (ret != 0)
143 		return ret;
144 
145 	val &= axp20x_ea->mask;
146 	val >>= ffs(axp20x_ea->mask) - 1;
147 
148 	for (i = 0; i < 4; i++)
149 		if (val == axp20x_ea->p_time[i].idx)
150 			val = axp20x_ea->p_time[i].time;
151 
152 	return sprintf(buf, "%u\n", val);
153 }
154 
axp20x_store_ext_attr(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)155 static ssize_t axp20x_store_ext_attr(struct device *dev,
156 				     struct device_attribute *attr,
157 				     const char *buf, size_t count)
158 {
159 	struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
160 	struct axp20x_pek_ext_attr *axp20x_ea = get_axp_ext_attr(attr);
161 	char val_str[20];
162 	size_t len;
163 	int ret, i;
164 	unsigned int val, idx = 0;
165 	unsigned int best_err = UINT_MAX;
166 
167 	val_str[sizeof(val_str) - 1] = '\0';
168 	strncpy(val_str, buf, sizeof(val_str) - 1);
169 	len = strlen(val_str);
170 
171 	if (len && val_str[len - 1] == '\n')
172 		val_str[len - 1] = '\0';
173 
174 	ret = kstrtouint(val_str, 10, &val);
175 	if (ret)
176 		return ret;
177 
178 	for (i = 3; i >= 0; i--) {
179 		unsigned int err;
180 
181 		err = abs(axp20x_ea->p_time[i].time - val);
182 		if (err < best_err) {
183 			best_err = err;
184 			idx = axp20x_ea->p_time[i].idx;
185 		}
186 
187 		if (!err)
188 			break;
189 	}
190 
191 	idx <<= ffs(axp20x_ea->mask) - 1;
192 	ret = regmap_update_bits(axp20x_pek->axp20x->regmap,
193 				 axp2101_PONLEVEL,
194 				 axp20x_ea->mask, idx);
195 	if (ret != 0)
196 		return -EINVAL;
197 
198 	return count;
199 }
200 
201 static struct dev_ext_attribute axp20x_dev_attr_startup = {
202 	.attr	= __ATTR(startup, 0644, axp20x_show_ext_attr, axp20x_store_ext_attr),
203 	.var	= &axp20x_pek_startup_ext_attr,
204 };
205 
206 static struct dev_ext_attribute axp20x_dev_attr_shutdown = {
207 	.attr	= __ATTR(shutdown, 0644, axp20x_show_ext_attr, axp20x_store_ext_attr),
208 	.var	= &axp20x_pek_shutdown_ext_attr,
209 };
210 
211 static struct attribute *axp20x_attributes[] = {
212 	&axp20x_dev_attr_startup.attr.attr,
213 	&axp20x_dev_attr_shutdown.attr.attr,
214 	NULL,
215 };
216 
217 static const struct attribute_group axp20x_attribute_group = {
218 	.attrs = axp20x_attributes,
219 };
220 
axp20x_pek_irq(int irq,void * pwr)221 static irqreturn_t axp20x_pek_irq(int irq, void *pwr)
222 {
223 	struct input_dev *idev = pwr;
224 	struct axp20x_pek *axp20x_pek = input_get_drvdata(idev);
225 
226 	/*
227 	 * The power-button is connected to ground so a falling edge (dbf)
228 	 * means it is pressed.
229 	 */
230 	if (irq == axp20x_pek->irq_dbf)
231 		input_report_key(idev, KEY_POWER, true);
232 	else if (irq == axp20x_pek->irq_dbr)
233 		input_report_key(idev, KEY_POWER, false);
234 
235 	input_sync(idev);
236 
237 	return IRQ_HANDLED;
238 }
239 
axp20x_remove_sysfs_group(void * _data)240 static void axp20x_remove_sysfs_group(void *_data)
241 {
242 	struct device *dev = _data;
243 
244 	sysfs_remove_group(&dev->kobj, &axp20x_attribute_group);
245 }
246 #if 0
247 static int axp2202_config_set(struct axp20x_pek *axp20x_pek)
248 {
249 	struct axp20x_dev *axp20x_dev = axp20x_pek->axp20x;
250 	struct regmap *regmap = axp20x_dev->regmap;
251 	struct pk_dts *pk_dts = &axp20x_pek->pk_dts;
252 	unsigned int val;
253 
254 	regmap_read(regmap, AXP2202_PONLEVEL, &val);
255 	if (pk_dts->pmu_powkey_on_time < 128)
256 		val &= 0x3C;
257 	else if (pk_dts->pmu_powkey_on_time < 512) {
258 		val &= 0x3C;
259 		val |= 0x01;
260 	} else if (pk_dts->pmu_powkey_on_time < 1000) {
261 		val &= 0x3C;
262 		val |= 0x10;
263 	} else {
264 		val &= 0x3C;
265 		val |= 0x11;
266 	}
267 	regmap_write(regmap, AXP2202_PONLEVEL, val);
268 
269 	/* pok long time set*/
270 	if (pk_dts->pmu_powkey_long_time < 1000)
271 		pk_dts->pmu_powkey_long_time = 1000;
272 
273 	if (pk_dts->pmu_powkey_long_time > 2500)
274 		pk_dts->pmu_powkey_long_time = 2500;
275 
276 	regmap_read(regmap, AXP2202_PONLEVEL, &val);
277 	val &= 0xcf;
278 	val |= (((pk_dts->pmu_powkey_long_time - 1000) / 500)
279 		<< 4);
280 	regmap_write(regmap, AXP2202_PONLEVEL, val);
281 
282 	/* pek offlevel poweroff en set*/
283 	if (pk_dts->pmu_powkey_off_en)
284 		pk_dts->pmu_powkey_off_en = 1;
285 	else
286 		pk_dts->pmu_powkey_off_en = 0;
287 
288 	regmap_read(regmap, AXP2202_PWROFF_EN, &val);
289 	val &= 0xfD;
290 	val |= (pk_dts->pmu_powkey_off_en << 1);
291 	regmap_write(regmap, AXP2202_PWROFF_EN, val);
292 
293 	/*Init offlevel restart or not */
294 	if (pk_dts->pmu_powkey_off_func)
295 		regmap_update_bits(regmap, AXP2202_PWROFF_EN, 0x01,
296 				   0x01); /* restart */
297 	else
298 		regmap_update_bits(regmap, AXP2202_PWROFF_EN, 0x01,
299 				   0x00); /* power off */
300 
301 	/* pek delay set */
302 	/* regmap_read(regmap, AXP2202_PWR_TIME_CTRL, &val); */
303 	/* val &= 0xfc; */
304 	/* if (pk_dts->pmu_pwrok_time < 32) */
305 		/* val |= ((pk_dts->pmu_pwrok_time / 8) - 1); */
306 	/* else */
307 		/* val |= ((pk_dts->pmu_pwrok_time / 32) + 1); */
308 	/* regmap_write(regmap, AXP2202_PWR_TIME_CTRL, val); */
309 
310 	/* pek offlevel time set */
311 	if (pk_dts->pmu_powkey_off_time < 4000)
312 		pk_dts->pmu_powkey_off_time = 4000;
313 
314 	if (pk_dts->pmu_powkey_off_time > 10000)
315 		pk_dts->pmu_powkey_off_time = 10000;
316 
317 	regmap_read(regmap, AXP2202_PONLEVEL, &val);
318 	val &= 0xf3;
319 	val |= ((pk_dts->pmu_powkey_off_time - 4000) / 2000
320 		<< 2);
321 	regmap_write(regmap, AXP2202_PONLEVEL, val);
322 
323 	/* vbat use all channels */
324 	/* regmap_write(regmap, AXP2202_VBAT_H, 0x40); */
325 
326 	return 0;
327 }
328 #endif
axp152_config_set(struct axp20x_pek * axp20x_pek)329 static int axp152_config_set(struct axp20x_pek *axp20x_pek)
330 {
331 	struct axp20x_dev *axp20x_dev = axp20x_pek->axp20x;
332 	struct regmap *regmap = axp20x_dev->regmap;
333 	struct pk_dts *pk_dts = &axp20x_pek->pk_dts;
334 	unsigned int val;
335 
336 	regmap_read(regmap, AXP152_PEK_KEY, &val);
337 	if (pk_dts->pmu_powkey_on_time <= 128)
338 		val &= 0x3f;
339 	else if (pk_dts->pmu_powkey_on_time <= 1000) {
340 		val &= 0x3f;
341 		val |= 0x10;
342 	} else if (pk_dts->pmu_powkey_on_time <= 2000) {
343 		val &= 0x3f;
344 		val |= 0x11;
345 	} else {
346 		val &= 0x3f;
347 		val |= 0x01;
348 	}
349 	regmap_write(regmap, AXP152_PEK_KEY, val);
350 
351 	/* pok long time set*/
352 	if (pk_dts->pmu_powkey_long_time < 1000)
353 		pk_dts->pmu_powkey_long_time = 1000;
354 
355 	if (pk_dts->pmu_powkey_long_time > 2500)
356 		pk_dts->pmu_powkey_long_time = 2500;
357 
358 	regmap_read(regmap, AXP152_PEK_KEY, &val);
359 	val &= 0xcf;
360 	val |= (((pk_dts->pmu_powkey_long_time - 1000) / 500)
361 		<< 4);
362 	regmap_write(regmap, AXP152_PEK_KEY, val);
363 
364 	/* pek offlevel poweroff en set*/
365 	if (pk_dts->pmu_powkey_off_en)
366 		pk_dts->pmu_powkey_off_en = 1;
367 	else
368 		pk_dts->pmu_powkey_off_en = 0;
369 
370 	regmap_read(regmap, AXP152_PEK_KEY, &val);
371 	val &= 0xf7;
372 	val |= (pk_dts->pmu_powkey_off_en << 3);
373 	regmap_write(regmap, AXP152_PEK_KEY, val);
374 
375 	/* pwrok time */
376 	if (pk_dts->pmu_pwrok_time == 64)
377 		regmap_update_bits(regmap, AXP152_PEK_KEY, 0x04,
378 				   0x04); /* 64ms */
379 	else
380 		regmap_update_bits(regmap, AXP152_PEK_KEY, 0x04,
381 				   0x00); /* 8ms */
382 
383 	/* pek offlevel time set */
384 	if (pk_dts->pmu_powkey_off_time < 4000)
385 		pk_dts->pmu_powkey_off_time = 4000;
386 
387 	if (pk_dts->pmu_powkey_off_time > 10000)
388 		pk_dts->pmu_powkey_off_time = 10000;
389 
390 	regmap_read(regmap, AXP152_PEK_KEY, &val);
391 	val &= 0xfc;
392 	val |= ((pk_dts->pmu_powkey_off_time - 4000) / 2000);
393 	regmap_write(regmap, AXP152_PEK_KEY, val);
394 
395 	return 0;
396 }
397 
axp803_config_set(struct axp20x_pek * axp20x_pek)398 static int axp803_config_set(struct axp20x_pek *axp20x_pek)
399 {
400 	struct axp20x_dev *axp20x_dev = axp20x_pek->axp20x;
401 	struct regmap *regmap = axp20x_dev->regmap;
402 	struct pk_dts *pk_dts = &axp20x_pek->pk_dts;
403 	unsigned int val;
404 
405 	/* onlevel setting */
406 	regmap_read(regmap, AXP803_POK_SET, &val);
407 	if (pk_dts->pmu_powkey_on_time <= 128)
408 		val &= 0x3f;
409 	else if (pk_dts->pmu_powkey_on_time <= 1000) {
410 		val &= 0x3f;
411 		val |= 0x40;
412 	} else if (pk_dts->pmu_powkey_on_time <= 2000) {
413 		val &= 0x3f;
414 		val |= 0x80;
415 	} else {
416 		val &= 0x3f;
417 		val |= 0xc0;
418 	}
419 	regmap_write(regmap, AXP803_POK_SET, val);
420 
421 	/* pok long time set*/
422 	if (pk_dts->pmu_powkey_long_time < 1000)
423 		pk_dts->pmu_powkey_long_time = 1000;
424 
425 	if (pk_dts->pmu_powkey_long_time > 2500)
426 		pk_dts->pmu_powkey_long_time = 2500;
427 
428 	regmap_read(regmap, AXP803_POK_SET, &val);
429 	val &= 0xcf;
430 	val |= (((pk_dts->pmu_powkey_long_time - 1000) / 500)
431 		<< 4);
432 	regmap_write(regmap, AXP803_POK_SET, val);
433 
434 	/* pek offlevel poweroff en set*/
435 	if (pk_dts->pmu_powkey_off_en)
436 		pk_dts->pmu_powkey_off_en = 1;
437 	else
438 		pk_dts->pmu_powkey_off_en = 0;
439 
440 	regmap_read(regmap, AXP803_POK_SET, &val);
441 	val &= 0xf7;
442 	val |= (pk_dts->pmu_powkey_off_en << 3);
443 	regmap_write(regmap, AXP803_POK_SET, val);
444 
445 	/*Init offlevel restart or not */
446 	if (pk_dts->pmu_powkey_off_func)
447 		regmap_update_bits(regmap, AXP803_POK_SET, 0x04,
448 				   0x01); /* restart */
449 	else
450 		regmap_update_bits(regmap, AXP803_POK_SET, 0x04,
451 				   0x00); /* not restart*/
452 
453 	/* pek offlevel poweroff time set */
454 	if (pk_dts->pmu_powkey_off_time < 4000)
455 		pk_dts->pmu_powkey_off_time = 4000;
456 
457 	if (pk_dts->pmu_powkey_off_time > 10000)
458 		pk_dts->pmu_powkey_off_time = 10000;
459 
460 	regmap_read(regmap, AXP803_POK_SET, &val);
461 	val &= 0xfc;
462 	val |= ((pk_dts->pmu_powkey_off_time - 4000) / 2000);
463 	regmap_write(regmap, AXP803_POK_SET, val);
464 
465 
466 	return 0;
467 }
468 
469 
axp2585_config_set(struct axp20x_pek * axp20x_pek)470 static int axp2585_config_set(struct axp20x_pek *axp20x_pek)
471 {
472 	struct axp20x_dev *axp20x_dev = axp20x_pek->axp20x;
473 	struct regmap *regmap = axp20x_dev->regmap;
474 	struct pk_dts *pk_dts = &axp20x_pek->pk_dts;
475 	unsigned int val;
476 
477 	/* onlevel setting */
478 	regmap_read(regmap, AXP2585_POK_SET, &val);
479 	if (pk_dts->pmu_powkey_on_time <= 628)
480 		val &= 0xf3;
481 	else if (pk_dts->pmu_powkey_on_time <= 1500) {
482 		val &= 0xf3;
483 		val |= 0x04;
484 	} else if (pk_dts->pmu_powkey_on_time <= 2500) {
485 		val &= 0xf3;
486 		val |= 0x08;
487 	} else {
488 		val &= 0xf3;
489 		val |= 0x0c;
490 	}
491 	regmap_write(regmap, AXP2585_POK_SET, val);
492 
493 	/* pok long time set*/
494 	if (pk_dts->pmu_powkey_long_time < 1000)
495 		pk_dts->pmu_powkey_long_time = 1000;
496 
497 	if (pk_dts->pmu_powkey_long_time > 2500)
498 		pk_dts->pmu_powkey_long_time = 2500;
499 
500 	regmap_read(regmap, AXP2585_POK_SET, &val);
501 	val &= 0x3f;
502 	val |= (((pk_dts->pmu_powkey_long_time - 1000) / 500)
503 		<< 6);
504 	regmap_write(regmap, AXP2585_POK_SET, val);
505 
506 	/* pek offlevel poweroff time set */
507 	if (pk_dts->pmu_powkey_off_time < 4500)
508 		pk_dts->pmu_powkey_off_time = 4500;
509 
510 	if (pk_dts->pmu_powkey_off_time > 10500)
511 		pk_dts->pmu_powkey_off_time = 10500;
512 
513 	regmap_read(regmap, AXP2585_POK_SET, &val);
514 	val &= 0xfc;
515 	val |= ((pk_dts->pmu_powkey_off_time - 4500) / 2000);
516 	regmap_write(regmap, AXP2585_POK_SET, val);
517 
518 	return 0;
519 }
520 
axp2202_config_set(struct axp20x_pek * axp20x_pek)521 static int axp2202_config_set(struct axp20x_pek *axp20x_pek)
522 {
523 	struct axp20x_dev *axp20x_dev = axp20x_pek->axp20x;
524 	struct regmap *regmap = axp20x_dev->regmap;
525 	struct pk_dts *pk_dts = &axp20x_pek->pk_dts;
526 	unsigned int val;
527 
528 	regmap_read(regmap, AXP2202_PONLEVEL, &val);
529 	if (pk_dts->pmu_powkey_on_time < 128)
530 		val &= 0x3C;
531 	else if (pk_dts->pmu_powkey_on_time < 512) {
532 		val &= 0x3C;
533 		val |= 0x01;
534 	} else if (pk_dts->pmu_powkey_on_time < 1000) {
535 		val &= 0x3C;
536 		val |= 0x02;
537 	} else {
538 		val &= 0x3C;
539 		val |= 0x03;
540 	}
541 	regmap_write(regmap, AXP2202_PONLEVEL, val);
542 
543 	/* pok long time set*/
544 	if (pk_dts->pmu_powkey_long_time < 1000)
545 		pk_dts->pmu_powkey_long_time = 1000;
546 
547 	if (pk_dts->pmu_powkey_long_time > 2500)
548 		pk_dts->pmu_powkey_long_time = 2500;
549 
550 	regmap_read(regmap, AXP2202_PONLEVEL, &val);
551 	val &= 0xcf;
552 	val |= (((pk_dts->pmu_powkey_long_time - 1000) / 500)
553 		<< 4);
554 	regmap_write(regmap, AXP2202_PONLEVEL, val);
555 
556 	/* pek offlevel poweroff en set*/
557 	if (pk_dts->pmu_powkey_off_en)
558 		pk_dts->pmu_powkey_off_en = 1;
559 	else
560 		pk_dts->pmu_powkey_off_en = 0;
561 
562 	regmap_read(regmap, AXP2202_PWROFF_EN, &val);
563 	val &= 0xfD;
564 	val |= (pk_dts->pmu_powkey_off_en << 1);
565 	regmap_write(regmap, AXP2202_PWROFF_EN, val);
566 
567 	/*Init offlevel restart or not */
568 	if (pk_dts->pmu_powkey_off_func)
569 		regmap_update_bits(regmap, AXP2202_PWROFF_EN, 0x01,
570 				   0x01); /* restart */
571 	else
572 		regmap_update_bits(regmap, AXP2202_PWROFF_EN, 0x01,
573 				   0x00); /* power off */
574 
575 	/* pek delay set */
576 	/* regmap_read(regmap, AXP2202_PWR_TIME_CTRL, &val); */
577 	/* val &= 0xfc; */
578 	/* if (pk_dts->pmu_pwrok_time < 32) */
579 		/* val |= ((pk_dts->pmu_pwrok_time / 8) - 1); */
580 	/* else */
581 		/* val |= ((pk_dts->pmu_pwrok_time / 32) + 1); */
582 	/* regmap_write(regmap, AXP2202_PWR_TIME_CTRL, val); */
583 
584 	/* pek offlevel time set */
585 	if (pk_dts->pmu_powkey_off_time < 4000)
586 		pk_dts->pmu_powkey_off_time = 4000;
587 
588 	if (pk_dts->pmu_powkey_off_time > 10000)
589 		pk_dts->pmu_powkey_off_time = 10000;
590 
591 	regmap_read(regmap, AXP2202_PONLEVEL, &val);
592 	val &= 0xf3;
593 	val |= ((pk_dts->pmu_powkey_off_time - 4000) / 2000
594 		<< 2);
595 	regmap_write(regmap, AXP2202_PONLEVEL, val);
596 
597 	/* vbat use all channels */
598 	/* regmap_write(regmap, AXP2202_VBAT_H, 0x40); */
599 
600 	return 0;
601 }
602 
axp2201_config_set(struct axp20x_pek * axp20x_pek)603 static int axp2201_config_set(struct axp20x_pek *axp20x_pek)
604 {
605 	struct axp20x_dev *axp20x_dev = axp20x_pek->axp20x;
606 	struct regmap *regmap = axp20x_dev->regmap;
607 	struct pk_dts *pk_dts = &axp20x_pek->pk_dts;
608 	unsigned int val;
609 
610 	regmap_read(regmap, axp2101_PONLEVEL, &val);
611 	if (pk_dts->pmu_powkey_on_time < 128)
612 		val &= 0x3C;
613 	else if (pk_dts->pmu_powkey_on_time < 512) {
614 		val &= 0x3C;
615 		val |= 0x01;
616 	} else if (pk_dts->pmu_powkey_on_time < 1000) {
617 		val &= 0x3C;
618 		val |= 0x02;
619 	} else {
620 		val &= 0x3C;
621 		val |= 0x03;
622 	}
623 	regmap_write(regmap, axp2101_PONLEVEL, val);
624 
625 	/* pok long time set*/
626 	if (pk_dts->pmu_powkey_long_time < 1000)
627 		pk_dts->pmu_powkey_long_time = 1000;
628 
629 	if (pk_dts->pmu_powkey_long_time > 2500)
630 		pk_dts->pmu_powkey_long_time = 2500;
631 
632 	regmap_read(regmap, axp2101_PONLEVEL, &val);
633 	val &= 0xcf;
634 	val |= (((pk_dts->pmu_powkey_long_time - 1000) / 500)
635 		<< 4);
636 	regmap_write(regmap, axp2101_PONLEVEL, val);
637 
638 	/* pek offlevel poweroff en set*/
639 	if (pk_dts->pmu_powkey_off_en)
640 		pk_dts->pmu_powkey_off_en = 1;
641 	else
642 		pk_dts->pmu_powkey_off_en = 0;
643 
644 	regmap_read(regmap, axp2101_PWROFF_EN, &val);
645 	val &= 0x0D;
646 	val |= (pk_dts->pmu_powkey_off_en << 1);
647 	regmap_write(regmap, axp2101_PWROFF_EN, val);
648 
649 	/*Init offlevel restart or not */
650 	if (pk_dts->pmu_powkey_off_func)
651 		regmap_update_bits(regmap, axp2101_PWROFF_EN, 0x01,
652 				   0x01); /* restart */
653 	else
654 		regmap_update_bits(regmap, axp2101_PWROFF_EN, 0x01,
655 				   0x00); /* not restart*/
656 
657 	/* pek delay set */
658 	regmap_read(regmap, axp2101_PWR_TIME_CTRL, &val);
659 	val &= 0xfc;
660 	if (pk_dts->pmu_pwrok_time < 32)
661 		val |= ((pk_dts->pmu_pwrok_time / 8) - 1);
662 	else
663 		val |= ((pk_dts->pmu_pwrok_time / 32) + 1);
664 	regmap_write(regmap, axp2101_PWR_TIME_CTRL, val);
665 
666 	/* pek offlevel time set */
667 	if (pk_dts->pmu_powkey_off_time < 4000)
668 		pk_dts->pmu_powkey_off_time = 4000;
669 
670 	if (pk_dts->pmu_powkey_off_time > 10000)
671 		pk_dts->pmu_powkey_off_time = 10000;
672 
673 	regmap_read(regmap, axp2101_PONLEVEL, &val);
674 	val &= 0x33;
675 	val |= ((pk_dts->pmu_powkey_off_time - 4000) / 2000
676 		<< 2);
677 	regmap_write(regmap, axp2101_PONLEVEL, val);
678 
679 	/* vbat use all channels */
680 	regmap_write(regmap, axp2101_VBAT_H, 0x40);
681 
682 	return 0;
683 }
684 
axp806_config_set(struct axp20x_pek * axp20x_pek)685 static int axp806_config_set(struct axp20x_pek *axp20x_pek)
686 {
687 	struct axp20x_dev *axp20x_dev = axp20x_pek->axp20x;
688 	struct regmap *regmap = axp20x_dev->regmap;
689 	struct pk_dts *pk_dts = &axp20x_pek->pk_dts;
690 	unsigned int val;
691 
692 	regmap_read(regmap, AXP806_POK_SET, &val);
693 	if (pk_dts->pmu_powkey_on_time < 128)
694 		val &= 0x3f;
695 	else if (pk_dts->pmu_powkey_on_time < 1000) {
696 		val &= 0x3f;
697 		val |= 0x40;
698 	} else if (pk_dts->pmu_powkey_on_time < 2000) {
699 		val &= 0x3f;
700 		val |= 0x80;
701 	} else {
702 		val &= 0x3f;
703 		val |= 0xc0;
704 	}
705 	regmap_write(regmap, AXP806_POK_SET, val);
706 
707 	/* pok long time set*/
708 	if (pk_dts->pmu_powkey_long_time < 1000)
709 		pk_dts->pmu_powkey_long_time = 1000;
710 
711 	if (pk_dts->pmu_powkey_long_time > 2500)
712 		pk_dts->pmu_powkey_long_time = 2500;
713 
714 	regmap_read(regmap, AXP806_POK_SET, &val);
715 	val &= 0xcf;
716 	val |= (((pk_dts->pmu_powkey_long_time - 1000) / 500) << 4);
717 	regmap_write(regmap, AXP806_POK_SET, val);
718 
719 	/*Init offlevel restart or not */
720 	if (pk_dts->pmu_powkey_off_func)
721 		regmap_update_bits(regmap, AXP806_POK_SET, 0x04, 0x04); /* restart */
722 	else
723 		regmap_update_bits(regmap, AXP806_POK_SET, 0x04, 0x00); /* not restart*/
724 
725 	/* pek offlevel poweroff en set*/
726 	if (pk_dts->pmu_powkey_off_en)
727 		pk_dts->pmu_powkey_off_en = 1;
728 	else
729 		pk_dts->pmu_powkey_off_en = 0;
730 
731 	regmap_read(regmap, AXP806_POK_SET, &val);
732 	val &= 0xf7;
733 	val |= (pk_dts->pmu_powkey_off_en << 3);
734 	regmap_write(regmap, AXP806_POK_SET, val);
735 
736 	/* pek offlevel time set */
737 	if (pk_dts->pmu_powkey_off_time < 4000)
738 		pk_dts->pmu_powkey_off_time = 4000;
739 
740 	if (pk_dts->pmu_powkey_off_time > 10000)
741 		pk_dts->pmu_powkey_off_time = 10000;
742 
743 	regmap_read(regmap, AXP806_POK_SET, &val);
744 	val &= 0xfc;
745 	val |= (pk_dts->pmu_powkey_off_time - 4000) / 2000;
746 	regmap_write(regmap, AXP806_POK_SET, val);
747 
748 	return 0;
749 }
750 
axp20x_dts_param_set(struct axp20x_pek * axp20x_pek)751 static void axp20x_dts_param_set(struct axp20x_pek *axp20x_pek)
752 {
753 	struct axp20x_dev *axp20x_dev = axp20x_pek->axp20x;
754 
755 	if (!axp_powerkey_dt_parse(axp20x_pek->input->dev.parent->of_node,
756 				   &axp20x_pek->pk_dts)) {
757 		switch (axp20x_dev->variant) {
758 		case AXP152_ID:
759 			axp152_config_set(axp20x_pek);
760 			break;
761 		case AXP2202_ID:
762 			axp2202_config_set(axp20x_pek);
763 			break;
764 		case AXP2585_ID:
765 			axp2585_config_set(axp20x_pek);
766 			break;
767 		case AXP803_ID:
768 			axp803_config_set(axp20x_pek);
769 			break;
770 		case AXP2101_ID:
771 			axp2201_config_set(axp20x_pek);
772 			break;
773 		case AXP806_ID:
774 			axp806_config_set(axp20x_pek);
775 			break;
776 		default:
777 			pr_warn("Setting power key for unsupported AXP variant\n");
778 		}
779 	}
780 }
781 
axp20x_pek_probe(struct platform_device * pdev)782 static int axp20x_pek_probe(struct platform_device *pdev)
783 {
784 	struct axp20x_pek *axp20x_pek;
785 	struct axp20x_dev *axp20x;
786 	struct input_dev *idev;
787 	int error;
788 
789 	axp20x_pek = devm_kzalloc(&pdev->dev, sizeof(struct axp20x_pek),
790 				  GFP_KERNEL);
791 	if (!axp20x_pek)
792 		return -ENOMEM;
793 
794 	axp20x_pek->axp20x = dev_get_drvdata(pdev->dev.parent);
795 	axp20x = axp20x_pek->axp20x;
796 
797 	if (!axp20x->irq) {
798 		pr_err("axp2101-pek can not register without irq\n");
799 		return -EINVAL;
800 	}
801 
802 	axp20x_pek->irq_dbr = platform_get_irq_byname(pdev, "PEK_DBR");
803 	if (axp20x_pek->irq_dbr < 0) {
804 		dev_err(&pdev->dev, "No IRQ for PEK_DBR, error=%d\n",
805 				axp20x_pek->irq_dbr);
806 		return axp20x_pek->irq_dbr;
807 	}
808 	axp20x_pek->irq_dbr = regmap_irq_get_virq(axp20x->regmap_irqc,
809 						  axp20x_pek->irq_dbr);
810 
811 	axp20x_pek->irq_dbf = platform_get_irq_byname(pdev, "PEK_DBF");
812 	if (axp20x_pek->irq_dbf < 0) {
813 		dev_err(&pdev->dev, "No IRQ for PEK_DBF, error=%d\n",
814 				axp20x_pek->irq_dbf);
815 		return axp20x_pek->irq_dbf;
816 	}
817 	axp20x_pek->irq_dbf = regmap_irq_get_virq(axp20x->regmap_irqc,
818 						  axp20x_pek->irq_dbf);
819 
820 	axp20x_pek->input = devm_input_allocate_device(&pdev->dev);
821 	if (!axp20x_pek->input)
822 		return -ENOMEM;
823 
824 	idev = axp20x_pek->input;
825 
826 	switch (axp20x->variant) {
827 	case AXP2585_ID:
828 		idev->name = "axp2585-pek";
829 		break;
830 	case AXP2202_ID:
831 		idev->name = "axp2202-pek";
832 		break;
833 	case AXP152_ID:
834 		idev->name = "axp152-pek";
835 		break;
836 	case AXP803_ID:
837 		idev->name = "axp803-pek";
838 		break;
839 	case AXP806_ID:
840 		idev->name = "axp806-pek";
841 		break;
842 	default:
843 		idev->name = "axp2101-pek";
844 		break;
845 }
846 
847 	idev->phys = "m1kbd/input2";
848 	idev->dev.parent = &pdev->dev;
849 
850 	input_set_capability(idev, EV_KEY, KEY_POWER);
851 	set_bit(EV_REP, idev->evbit);
852 
853 	input_set_drvdata(idev, axp20x_pek);
854 
855 	axp20x_dts_param_set(axp20x_pek);
856 	error = devm_request_any_context_irq(&pdev->dev, axp20x_pek->irq_dbr,
857 					     axp20x_pek_irq, 0,
858 					     "axp20x-pek-dbr", idev);
859 	if (error < 0) {
860 		dev_err(axp20x->dev, "Failed to request dbr IRQ#%d: %d\n",
861 			axp20x_pek->irq_dbr, error);
862 		return error;
863 	}
864 
865 	error = devm_request_any_context_irq(&pdev->dev, axp20x_pek->irq_dbf,
866 					  axp20x_pek_irq, 0,
867 					  "axp20x-pek-dbf", idev);
868 	if (error < 0) {
869 		dev_err(axp20x->dev, "Failed to request dbf IRQ#%d: %d\n",
870 			axp20x_pek->irq_dbf, error);
871 		return error;
872 	}
873 
874 	if (axp20x->variant == AXP2101_ID) {
875 		error = sysfs_create_group(&pdev->dev.kobj,
876 					   &axp20x_attribute_group);
877 		if (error) {
878 			dev_err(axp20x->dev,
879 				"Failed to create sysfs attributes: %d\n",
880 				error);
881 			return error;
882 		}
883 
884 		error = devm_add_action(&pdev->dev, axp20x_remove_sysfs_group,
885 					&pdev->dev);
886 		if (error) {
887 			axp20x_remove_sysfs_group(&pdev->dev);
888 			dev_err(&pdev->dev,
889 				"Failed to add sysfs cleanup action: %d\n",
890 				error);
891 			return error;
892 		}
893 	}
894 
895 	error = input_register_device(idev);
896 	if (error) {
897 		dev_err(axp20x->dev, "Can't register input device: %d\n",
898 			error);
899 		return error;
900 	}
901 
902 	platform_set_drvdata(pdev, axp20x_pek);
903 
904 	return 0;
905 }
906 
axp20x_pek_remove(struct platform_device * pdev)907 static int axp20x_pek_remove(struct platform_device *pdev)
908 {
909 	struct axp20x_pek *axp20x_pek = platform_get_drvdata(pdev);
910 	struct axp20x_dev *axp20x = axp20x_pek->axp20x;
911 
912 	if (axp20x->variant == AXP2101_ID) {
913 		axp20x_remove_sysfs_group(&pdev->dev);
914 	}
915 
916 	input_unregister_device(axp20x_pek->input);
917 
918 	return 0;
919 }
920 
axp2101_powerkey_suspend(struct device * dev)921 static int axp2101_powerkey_suspend(struct device *dev)
922 {
923 	struct platform_device *pdev = to_platform_device(dev);
924 	struct axp20x_pek *axp20x_pek = platform_get_drvdata(pdev);
925 
926 	if (!axp20x_pek->pk_dts.pmu_powkey_wakeup_rising) {
927 		disable_irq(axp20x_pek->irq_dbr);
928 	}
929 
930 	if (!axp20x_pek->pk_dts.pmu_powkey_wakeup_falling) {
931 		disable_irq(axp20x_pek->irq_dbf);
932 	}
933 
934 	return 0;
935 }
936 
axp2101_powerkey_resume(struct device * dev)937 static int axp2101_powerkey_resume(struct device *dev)
938 {
939 	struct platform_device *pdev = to_platform_device(dev);
940 	struct axp20x_pek *axp20x_pek = platform_get_drvdata(pdev);
941 
942 	if (!axp20x_pek->pk_dts.pmu_powkey_wakeup_rising) {
943 		enable_irq(axp20x_pek->irq_dbr);
944 	}
945 
946 	if (!axp20x_pek->pk_dts.pmu_powkey_wakeup_falling) {
947 		enable_irq(axp20x_pek->irq_dbf);
948 	}
949 
950 	return 0;
951 }
952 
953 static const struct dev_pm_ops axp2101_powerkey_pm_ops = {
954 	.suspend      = axp2101_powerkey_suspend,
955 	.resume       = axp2101_powerkey_resume,
956 };
957 
958 struct of_device_id axp_match_table[] = {
959 	{ .compatible = "x-powers,axp2585-pek" },
960 	{ .compatible = "x-powers,axp2202-pek" },
961 	{ .compatible = "x-powers,axp803-pek" },
962 	{ .compatible = "x-powers,axp806-pek" },
963 	{ .compatible = "x-powers,axp152-pek" },
964 { /* sentinel */ },
965 };
966 
967 static struct platform_driver axp20x_pek_driver = {
968 	.probe		= axp20x_pek_probe,
969 	.remove		= axp20x_pek_remove,
970 	.driver		= {
971 		.of_match_table = axp_match_table,
972 		.name = "axp2101-pek",
973 		.pm = &axp2101_powerkey_pm_ops,
974 	},
975 };
976 module_platform_driver(axp20x_pek_driver);
977 
978 MODULE_DESCRIPTION("axp2101 Power Button");
979 MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
980 MODULE_LICENSE("GPL");
981 MODULE_ALIAS("platform:axp2101-pek");
982