mfd: rk808: add rk805 support
[firefly-linux-kernel-4.4.55.git] / drivers / input / misc / rk8xx-pwrkey.c
1 /*
2  * driver/input/misc/rk8xx-pwrkey.c
3  * Power Key driver for RK8xx PMIC Power Button.
4  *
5  * Copyright (C) 2017, Rockchip Technology Co., Ltd.
6  * Author: Chen Jianhong <chenjh@rock-chips.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  *
12  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
13  * kind, whether express or implied; without even the implied warranty
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  */
17
18 #include <linux/errno.h>
19 #include <linux/input.h>
20 #include <linux/init.h>
21 #include <linux/interrupt.h>
22 #include <linux/kernel.h>
23 #include <linux/mfd/rk808.h>
24 #include <linux/module.h>
25 #include <linux/of.h>
26 #include <linux/platform_device.h>
27 #include <linux/regmap.h>
28
29 struct rk8xx_pwrkey {
30         struct rk808 *rk8xx;
31         struct input_dev *input_dev;
32         int report_key;
33 };
34
35 static irqreturn_t rk8xx_pwrkey_irq_falling(int irq, void *data)
36 {
37         struct rk8xx_pwrkey *pwr = data;
38
39         input_report_key(pwr->input_dev, pwr->report_key, 1);
40         input_sync(pwr->input_dev);
41
42         return IRQ_HANDLED;
43 }
44
45 static irqreturn_t rk8xx_pwrkey_irq_rising(int irq, void *data)
46 {
47         struct rk8xx_pwrkey *pwr = data;
48
49         input_report_key(pwr->input_dev, pwr->report_key, 0);
50         input_sync(pwr->input_dev);
51
52         return IRQ_HANDLED;
53 }
54
55 static int rk8xx_pwrkey_probe(struct platform_device *pdev)
56 {
57         struct rk808 *rk8xx = dev_get_drvdata(pdev->dev.parent);
58         struct rk8xx_pwrkey *pwrkey;
59         int fall_irq, rise_irq, err;
60         struct device_node *np;
61
62         np = of_find_node_by_name(pdev->dev.parent->of_node, "pwrkey");
63         if (np) {
64                 if (!of_device_is_available(np)) {
65                         dev_info(&pdev->dev, "device is disabled\n");
66                         return -EINVAL;
67                 }
68         }
69
70         pwrkey = devm_kzalloc(&pdev->dev,
71                               sizeof(struct rk8xx_pwrkey), GFP_KERNEL);
72         if (!pwrkey)
73                 return -ENOMEM;
74
75         pwrkey->input_dev = devm_input_allocate_device(&pdev->dev);
76         if (!pwrkey->input_dev) {
77                 dev_err(&pdev->dev, "Can't allocate power button\n");
78                 return -ENOMEM;
79         }
80
81         /* init struct input_dev */
82         pwrkey->rk8xx = rk8xx;
83         pwrkey->report_key = KEY_POWER;
84         pwrkey->input_dev->name = "rk8xx_pwrkey";
85         pwrkey->input_dev->phys = "rk8xx_pwrkey/input0";
86         pwrkey->input_dev->dev.parent = pdev->dev.parent;
87         pwrkey->input_dev->evbit[0] = BIT_MASK(EV_KEY);
88         pwrkey->input_dev->keybit[BIT_WORD(pwrkey->report_key)] =
89                                         BIT_MASK(pwrkey->report_key);
90         platform_set_drvdata(pdev, pwrkey);
91
92         /* requeset rise and fall irqs */
93         rise_irq = platform_get_irq(pdev, 0);
94         if (rise_irq < 0) {
95                 dev_err(&pdev->dev, "no IRQ for rise: %d\n", rise_irq);
96                 return rise_irq;
97         }
98
99         fall_irq = platform_get_irq(pdev, 1);
100         if (fall_irq < 0) {
101                 dev_err(&pdev->dev, "no IRQ for fall: %d\n", fall_irq);
102                 return fall_irq;
103         }
104
105         err = devm_request_threaded_irq(&pdev->dev, fall_irq,
106                                         NULL, rk8xx_pwrkey_irq_falling,
107                                         IRQF_TRIGGER_FALLING,
108                                         "rk8xx_pwrkey_fall", pwrkey);
109         if (err) {
110                 dev_err(&pdev->dev, "Can't get fall irq for pwrkey: %d\n", err);
111                 return err;
112         }
113         err = devm_request_threaded_irq(&pdev->dev, rise_irq,
114                                         NULL, rk8xx_pwrkey_irq_rising,
115                                         IRQF_TRIGGER_RISING,
116                                         "rk8xx_pwrkey_rise", pwrkey);
117         if (err) {
118                 dev_err(&pdev->dev, "Can't get rise irq for pwrkey: %d\n", err);
119                 return err;
120         }
121
122         /* register input device */
123         err = input_register_device(pwrkey->input_dev);
124         if (err) {
125                 dev_err(&pdev->dev, "Can't register power button: %d\n", err);
126                 return err;
127         }
128
129         return 0;
130 }
131
132 static struct platform_driver rk8xx_pwrkey_driver = {
133         .probe = rk8xx_pwrkey_probe,
134         .driver         = {
135                 .name   = "rk8xx-pwrkey",
136                 .owner  = THIS_MODULE,
137         },
138 };
139
140 module_platform_driver(rk8xx_pwrkey_driver);
141
142 MODULE_LICENSE("GPL v2");
143 MODULE_DESCRIPTION("RK8xx Power Button");
144 MODULE_AUTHOR("Chen Jianhong <chenjh@rock-chips.com>");