ARM64: dts: rk3399: fixup android next backlight gpio
[firefly-linux-kernel-4.4.55.git] / drivers / mfd / rt5025-irq.c
1 /*
2  *  drivers/mfd/rt5025-irq.c
3  *  Driver for Richtek RT5025 PMIC IRQ driver
4  *
5  *  Copyright (C) 2014 Richtek Technology Corp.
6  *  cy_huang <cy_huang@richtek.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; either version 2
11  * of the License, or (at your option) any later version.
12  */
13
14 #include <linux/module.h>
15 #include <linux/kernel.h>
16 #include <linux/init.h>
17 #include <linux/err.h>
18 #include <linux/platform_device.h>
19 #include <linux/i2c.h>
20 #include <linux/of_gpio.h>
21 #include <linux/workqueue.h>
22 #include <linux/interrupt.h>
23
24 #include <linux/mfd/rt5025.h>
25 #include <linux/mfd/rt5025-irq.h>
26
27 struct rt5025_irq_info {
28         struct i2c_client *i2c;
29         struct rt5025_chip *chip;
30         struct device *dev;
31         int irq;
32         unsigned char suspend:1;
33         struct delayed_work irq_delayed_work;
34 };
35
36 static irqreturn_t rt5025_irq_handler(int irqno, void *param)
37 {
38         struct rt5025_irq_info *ii = param;
39         unsigned char regval[6];
40         unsigned int irq_event = 0;
41         int ret = 0;
42
43         if (ii->suspend) {
44                 schedule_delayed_work(&ii->irq_delayed_work,
45                         msecs_to_jiffies(10));
46                 goto irq_fin;
47         }
48
49         ret = rt5025_reg_read(ii->i2c, RT5025_REG_IRQFLG);
50         if (ret < 0) {
51                 dev_err(ii->dev, "read gauge irq event fail\n");
52         } else {
53                 irq_event = ret;
54                 RTINFO("gauge event %02x\n", irq_event);
55                 #ifdef CONFIG_BATTERY_RT5025
56                 if (irq_event)
57                         rt5025_gauge_irq_handler(ii->chip->battery_info,
58                                 irq_event&(~RT5025_TALRT_MASK));
59                 #endif /* #ifdef CONFIG_RTC_RT5025 */
60         }
61
62         ret = rt5025_reg_block_read(ii->i2c, RT5025_REG_IRQEN1, 6, regval);
63         if (ret < 0) {
64                 dev_err(ii->dev, "read charger irq event fail\n");
65         } else {
66                 #ifdef CONFIG_BATTERY_RT5025
67                 /*combine gauge talrt irq into charger event*/
68                 irq_event = irq_event&RT5025_TALRT_MASK;
69                 irq_event <<= 24;
70                 irq_event |= (regval[1] << 16 | regval[3] << 8 | regval[5]);
71                 #else
72                 irq_event = regval[1] << 16 | regval[3] << 8 | regval[5];
73                 #endif
74                 RTINFO("chg event %08x\n", irq_event);
75                 #ifdef CONFIG_CHARGER_RT5025
76                 if (irq_event)
77                         rt5025_charger_irq_handler(ii->chip->charger_info,
78                                 irq_event);
79                 #endif /* #ifdef CONFIG_CHARGER_RT5025 */
80         }
81
82         ret = rt5025_reg_block_read(ii->i2c, RT5025_REG_IRQEN4, 4, regval);
83         if (ret < 0) {
84                 dev_err(ii->dev, "read misc irq event fail\n");
85         } else {
86                 irq_event = regval[1] << 8 | regval[3];
87                 RTINFO("misc event %04x\n", irq_event);
88                 #ifdef CONFIG_MISC_RT5025
89                 if (irq_event)
90                         rt5025_misc_irq_handler(ii->chip->misc_info, irq_event);
91                 #endif /* #ifdef CONFIG_MISC_RT5025 */
92         }
93 irq_fin:
94         return IRQ_HANDLED;
95 }
96
97 static void rt5025_irq_delayed_work(struct work_struct *work)
98 {
99         struct rt5025_irq_info *ii = (struct rt5025_irq_info *)container_of(work,
100                 struct rt5025_irq_info, irq_delayed_work.work);
101
102         rt5025_irq_handler(ii->irq, ii);
103 }
104
105 static int rt_parse_dt(struct rt5025_irq_info *ii, struct device *dev)
106 {
107         #ifdef CONFIG_OF
108         struct device_node *np = dev->of_node;
109         int val;
110
111         val = of_get_named_gpio(np, "rt,irq-gpio", 0);
112         if (gpio_is_valid(val)) {
113                 if (gpio_request(val, "rt5025-irq") >= 0) {
114                         gpio_direction_input(val);
115                         ii->irq = gpio_to_irq(val);
116                 } else {
117                         ii->irq = -1;
118                 }
119         } else {
120                 ii->irq = -1;
121         }
122         #endif /* #ifdef CONFIG_OF */
123         RTINFO("\n");
124         return 0;
125 }
126
127 static int rt_parse_pdata(struct rt5025_irq_info *ii, struct device *dev)
128 {
129         struct rt5025_irq_data *pdata = dev->platform_data;
130
131         if (gpio_is_valid(pdata->irq_gpio)) {
132                 if (gpio_request(pdata->irq_gpio, "rt5025-irq") >= 0) {
133                         gpio_direction_input(pdata->irq_gpio);
134                         ii->irq = gpio_to_irq(pdata->irq_gpio);
135                 } else {
136                         ii->irq = -1;
137                 }
138         } else {
139                 ii->irq = -1;
140         }
141         RTINFO("\n");
142         return 0;
143 }
144
145 static int rt5025_irq_probe(struct platform_device *pdev)
146 {
147         struct rt5025_chip *chip = dev_get_drvdata(pdev->dev.parent);
148         struct rt5025_platform_data *pdata = (pdev->dev.parent)->platform_data;
149         struct rt5025_irq_info *ii;
150         bool use_dt = pdev->dev.of_node;
151         int ret;
152
153         ii = devm_kzalloc(&pdev->dev, sizeof(*ii), GFP_KERNEL);
154         if (!ii)
155                 return -ENOMEM;
156
157         ii->i2c = chip->i2c;
158         ii->chip = chip;
159         ii->dev = &pdev->dev;
160         if (use_dt) {
161                 rt_parse_dt(ii, &pdev->dev);
162         } else {
163                 if (!pdata)
164                         goto out_dev;
165                 pdev->dev.platform_data = pdata->irq_pdata;
166                 rt_parse_pdata(ii, &pdev->dev);
167                 dev_info(&pdev->dev, "ii->irq %d\n", ii->irq);
168         }
169
170         INIT_DELAYED_WORK(&ii->irq_delayed_work, rt5025_irq_delayed_work);
171
172         platform_set_drvdata(pdev, ii);
173         if (ii->irq >= 0) {
174                 ret = devm_request_irq(&pdev->dev, ii->irq, rt5025_irq_handler,
175                         IRQF_TRIGGER_FALLING|IRQF_NO_SUSPEND, "rt5025-irq", ii);
176                 if (ret != 0) {
177                         dev_err(&pdev->dev, "request threaded irq fail\n");
178                         goto out_dev;
179                 }
180                 enable_irq_wake(ii->irq);
181                 schedule_delayed_work(&ii->irq_delayed_work, 1*HZ);
182         }
183         dev_info(&pdev->dev, "driver successfully loaded\n");
184         return 0;
185 out_dev:
186         return -EINVAL;
187 }
188
189 static int rt5025_irq_remove(struct platform_device *pdev)
190 {
191         struct rt5025_irq_info *ii = platform_get_drvdata(pdev);
192
193         if (ii->irq >= 0)
194                 devm_free_irq(&pdev->dev, ii->irq, ii);
195         return 0;
196 }
197
198 static int rt5025_irq_suspend(struct platform_device *pdev, pm_message_t state)
199 {
200         struct rt5025_irq_info *ii = platform_get_drvdata(pdev);
201
202         ii->suspend = 1;
203         return 0;
204 }
205
206 static int rt5025_irq_resume(struct platform_device *pdev)
207 {
208         struct rt5025_irq_info *ii = platform_get_drvdata(pdev);
209
210         ii->suspend = 0;
211         return 0;
212 }
213
214 static const struct of_device_id rt_match_table[] = {
215         { .compatible = "rt,rt5025-irq",},
216         {},
217 };
218
219 static struct platform_driver rt5025_irq_driver = {
220         .driver = {
221                 .name = RT5025_DEV_NAME "-irq",
222                 .owner = THIS_MODULE,
223                 .of_match_table = rt_match_table,
224         },
225         .probe = rt5025_irq_probe,
226         .remove = rt5025_irq_remove,
227         .suspend = rt5025_irq_suspend,
228         .resume = rt5025_irq_resume,
229 };
230
231 static int rt5025_irq_init(void)
232 {
233         return platform_driver_register(&rt5025_irq_driver);
234 }
235 device_initcall(rt5025_irq_init);
236
237 static void rt5025_irq_exit(void)
238 {
239         platform_driver_unregister(&rt5025_irq_driver);
240 }
241
242 module_exit(rt5025_irq_exit);
243
244 MODULE_LICENSE("GPL");
245 MODULE_AUTHOR("CY Huang <cy_huang@richtek.com");
246 MODULE_DESCRIPTION("IRQ driver for RT5025");
247 MODULE_ALIAS("platform:"RT5025_DEV_NAME "-irq");
248 MODULE_VERSION(RT5025_DRV_VER);