1 | /* |
2 | * Retu power button driver. |
3 | * |
4 | * Copyright (C) 2004-2010 Nokia Corporation |
5 | * |
6 | * Original code written by Ari Saastamoinen, Juha Yrjölä and Felipe Balbi. |
7 | * Rewritten by Aaro Koskinen. |
8 | * |
9 | * This file is subject to the terms and conditions of the GNU General |
10 | * Public License. See the file "COPYING" in the main directory of this |
11 | * archive for more details. |
12 | * |
13 | * This program is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. |
17 | */ |
18 | |
19 | #include <linux/irq.h> |
20 | #include <linux/slab.h> |
21 | #include <linux/errno.h> |
22 | #include <linux/input.h> |
23 | #include <linux/kernel.h> |
24 | #include <linux/module.h> |
25 | #include <linux/mfd/retu.h> |
26 | #include <linux/interrupt.h> |
27 | #include <linux/platform_device.h> |
28 | |
29 | #define RETU_STATUS_PWRONX (1 << 5) |
30 | |
31 | static irqreturn_t retu_pwrbutton_irq(int irq, void *_pwr) |
32 | { |
33 | struct input_dev *idev = _pwr; |
34 | struct retu_dev *rdev = input_get_drvdata(dev: idev); |
35 | bool state; |
36 | |
37 | state = !(retu_read(rdev, RETU_REG_STATUS) & RETU_STATUS_PWRONX); |
38 | input_report_key(dev: idev, KEY_POWER, value: state); |
39 | input_sync(dev: idev); |
40 | |
41 | return IRQ_HANDLED; |
42 | } |
43 | |
44 | static int retu_pwrbutton_probe(struct platform_device *pdev) |
45 | { |
46 | struct retu_dev *rdev = dev_get_drvdata(dev: pdev->dev.parent); |
47 | struct input_dev *idev; |
48 | int irq; |
49 | int error; |
50 | |
51 | irq = platform_get_irq(pdev, 0); |
52 | if (irq < 0) |
53 | return irq; |
54 | |
55 | idev = devm_input_allocate_device(&pdev->dev); |
56 | if (!idev) |
57 | return -ENOMEM; |
58 | |
59 | idev->name = "retu-pwrbutton" ; |
60 | idev->dev.parent = &pdev->dev; |
61 | |
62 | input_set_capability(dev: idev, EV_KEY, KEY_POWER); |
63 | input_set_drvdata(dev: idev, data: rdev); |
64 | |
65 | error = devm_request_threaded_irq(dev: &pdev->dev, irq, |
66 | NULL, thread_fn: retu_pwrbutton_irq, |
67 | IRQF_ONESHOT, |
68 | devname: "retu-pwrbutton" , dev_id: idev); |
69 | if (error) |
70 | return error; |
71 | |
72 | error = input_register_device(idev); |
73 | if (error) |
74 | return error; |
75 | |
76 | return 0; |
77 | } |
78 | |
79 | static struct platform_driver retu_pwrbutton_driver = { |
80 | .probe = retu_pwrbutton_probe, |
81 | .driver = { |
82 | .name = "retu-pwrbutton" , |
83 | }, |
84 | }; |
85 | module_platform_driver(retu_pwrbutton_driver); |
86 | |
87 | MODULE_ALIAS("platform:retu-pwrbutton" ); |
88 | MODULE_DESCRIPTION("Retu Power Button" ); |
89 | MODULE_AUTHOR("Ari Saastamoinen" ); |
90 | MODULE_AUTHOR("Felipe Balbi" ); |
91 | MODULE_AUTHOR("Aaro Koskinen <aaro.koskinen@iki.fi>" ); |
92 | MODULE_LICENSE("GPL" ); |
93 | |