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