Merge tag 'v4.4.2'
[firefly-linux-kernel-4.4.55.git] / drivers / input / misc / ricoh619-pwrkey.c
1 /*
2 * driver/input/misc/ricoh619-pwrkey.c
3 *
4 * Power Key driver for RICOH RC5T619 power management chip.
5 *
6 * Copyright (C) 2012-2013 RICOH COMPANY,LTD
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23 #include <linux/module.h>
24 #include <linux/init.h>
25 #include <linux/kernel.h>
26 #include <linux/errno.h>
27 #include <linux/input.h>
28 #include <linux/interrupt.h>
29 #include <linux/platform_device.h>
30 #include <linux/mfd/ricoh619.h>
31 #include <linux/spinlock.h>
32 #include <linux/timer.h>
33 #include <linux/pm.h>
34 #include <linux/slab.h>
35 #include <linux/pm_runtime.h>
36 #include <linux/workqueue.h>
37 #include <linux/gpio.h>
38 #include <linux/of.h>
39 #include <linux/delay.h>
40
41 #include <linux/mfd/ricoh619.h>
42 #include <linux/irq.h>
43 #include <linux/irqdomain.h>
44
45 #define RICOH619_ONKEY_TRIGGER_LEVEL    0
46 #define RICOH619_ONKEY_OFF_IRQ          0
47
48 struct ricoh619_pwrkey {
49         struct device *dev;
50         struct input_dev *pwr;
51         #if RICOH619_ONKEY_TRIGGER_LEVEL
52                 struct timer_list timer;
53         #endif
54         struct workqueue_struct *workqueue;
55         struct work_struct work;
56         unsigned long delay;
57         int key_irq;
58         bool pressed_first;
59         struct ricoh619_pwrkey_platform_data *pdata;
60         spinlock_t lock;
61 };
62
63 struct ricoh619_pwrkey *g_pwrkey;
64
65 #if RICOH619_ONKEY_TRIGGER_LEVEL
66 void ricoh619_pwrkey_timer(unsigned long t)
67 {
68         queue_work(g_pwrkey->workqueue, &g_pwrkey->work);
69 }
70 #endif
71 //extern void rk_send_wakeup_key(void);
72 extern u8 ricoh619_pwr_key_reg;
73 static void ricoh619_irq_work(struct work_struct *work)
74 {
75         /* unsigned long flags; */
76         uint8_t val;
77         int i=0;
78
79 //      printk("PMU: %s: \n",__func__);
80         //spin_lock_irqsave(&g_pwrkey->lock, flags);
81         if((ricoh619_pwr_key_reg & 0x01) && ricoh619_pwrkey_wakeup){
82                 printk("PMU: %s: pwrkey_wakeup\n",__func__);
83                 ricoh619_pwrkey_wakeup = 0;
84                 input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 1);
85                 input_event(g_pwrkey->pwr, EV_SYN, 0, 0);
86                 input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 0);
87                 input_event(g_pwrkey->pwr, EV_SYN, 0, 0);
88                 do{
89                         ricoh619_read(g_pwrkey->dev->parent, RICOH619_INT_MON_SYS, &val);
90                 val &= 0x01;
91                         i += 1;
92                         msleep(100);
93                 }while(val && (i < 15));
94                 return;
95         }
96         ricoh619_read(g_pwrkey->dev->parent, RICOH619_INT_MON_SYS, &val);
97         dev_dbg(g_pwrkey->dev, "pwrkey is pressed?(0x%x): 0x%x\n",
98                                                 RICOH619_INT_MON_SYS, val);
99 //      printk(KERN_INFO "PMU: %s: val=0x%x\n", __func__, val);
100         val &= 0x1;
101         if(val){
102                 #if (RICOH619_ONKEY_TRIGGER_LEVEL)
103                 g_pwrkey->timer.expires = jiffies + g_pwrkey->delay;
104                 add_timer(&g_pwrkey->timer);
105                 #endif
106                 if (!g_pwrkey->pressed_first){
107                         g_pwrkey->pressed_first = true;
108 //                      printk("PMU1: %s: Power Key!!!\n",__func__);
109                         //input_report_key(g_pwrkey->pwr, KEY_POWER, 1);
110                         //input_sync(g_pwrkey->pwr);
111                         input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 1);
112                         input_event(g_pwrkey->pwr, EV_SYN, 0, 0);
113                 }
114         } else {
115                 if (g_pwrkey->pressed_first) {
116 //                      printk(KERN_INFO "PMU2: %s: Power Key!!!\n", __func__);
117                         /* input_report_key(g_pwrkey->pwr, KEY_POWER, 0); */
118                         /* input_sync(g_pwrkey->pwr); */
119                         input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 0);
120                         input_event(g_pwrkey->pwr, EV_SYN, 0, 0);
121                 }
122                 g_pwrkey->pressed_first = false;
123         }
124
125         /* spin_unlock_irqrestore(&g_pwrkey->lock, flags); */
126 }
127
128 static irqreturn_t pwrkey_irq(int irq, void *_pwrkey)
129 {
130 //      printk(KERN_INFO "PMU: %s:\n", __func__);
131 //      rk_send_wakeup_key();
132         #if (RICOH619_ONKEY_TRIGGER_LEVEL)
133         g_pwrkey->timer.expires = jiffies + g_pwrkey->delay;
134         add_timer(&g_pwrkey->timer);
135         #else
136         queue_work(g_pwrkey->workqueue, &g_pwrkey->work);
137         #endif
138         return IRQ_HANDLED;
139 }
140
141 #if RICOH619_ONKEY_OFF_IRQ
142 static irqreturn_t pwrkey_irq_off(int irq, void *_pwrkey)
143 {
144         dev_warn(g_pwrkey->dev, "ONKEY is pressed long time!\n");
145         return IRQ_HANDLED;
146 }
147 #endif
148
149 #ifdef CONFIG_OF
150 static struct ricoh619_pwrkey_platform_data *
151 ricoh619_pwrkey_dt_init(struct platform_device *pdev)
152 {
153         struct device_node *nproot = pdev->dev.parent->of_node;
154         struct device_node *np;
155         struct ricoh619_pwrkey_platform_data *pdata;
156
157         if (!nproot)
158                 return pdev->dev.platform_data;
159
160         np = of_find_node_by_name(nproot, "pwrkey");
161         if (!np) {
162                 dev_err(&pdev->dev, "failed to find pwrkey node\n");
163                 return NULL;
164         }
165
166         pdata = devm_kzalloc(&pdev->dev,
167                         sizeof(struct ricoh619_pwrkey_platform_data),
168                         GFP_KERNEL);
169
170         of_property_read_u32(np, "ricoh,pwrkey-delay-ms", &pdata->delay_ms);
171         of_node_put(np);
172
173         return pdata;
174 }
175 #else
176 static struct ricoh619_pwrkey_platform_data *
177 ricoh619_pwrkey_dt_init(struct platform_device *pdev)
178 {
179         return pdev->dev.platform_data;
180 }
181 #endif
182
183 static int ricoh619_pwrkey_probe(struct platform_device *pdev)
184 {
185         struct input_dev *pwr;
186         int key_irq;
187         int err;
188         struct ricoh619_pwrkey *pwrkey;
189         struct ricoh619_pwrkey_platform_data *pdata;
190         struct ricoh619 *ricoh619 = dev_get_drvdata(pdev->dev.parent);
191         uint8_t val;
192
193 //      printk("PMU: %s: \n",__func__);
194
195         pdata = ricoh619_pwrkey_dt_init(pdev);
196         if (!pdata) {
197                 dev_err(&pdev->dev, "platform data isn't assigned to "
198                         "power key\n");
199                 return -EINVAL;
200         }
201         key_irq  = irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_POWER_ON);
202         printk(KERN_INFO "PMU1: %s: key_irq=%d\n", __func__, key_irq);
203         pwrkey = kzalloc(sizeof(*pwrkey), GFP_KERNEL);
204         if (!pwrkey)
205                 return -ENOMEM;
206
207         pwrkey->dev = &pdev->dev;
208         pwrkey->pdata = pdata;
209         pwrkey->pressed_first = false;
210         pwrkey->delay = HZ / 1000 * pdata->delay_ms;
211         g_pwrkey = pwrkey;
212         pwr = input_allocate_device();
213         if (!pwr) {
214                 dev_dbg(&pdev->dev, "Can't allocate power button\n");
215                 err = -ENOMEM;
216                 goto free_pwrkey;
217         }
218         input_set_capability(pwr, EV_KEY, KEY_POWER);
219         pwr->name = "ricoh619_pwrkey";
220         pwr->phys = "ricoh619_pwrkey/input0";
221         pwr->dev.parent = &pdev->dev;
222
223         #if RICOH619_ONKEY_TRIGGER_LEVEL
224         init_timer(&pwrkey->timer);
225         pwrkey->timer.function = ricoh619_pwrkey_timer;
226         #endif
227
228         spin_lock_init(&pwrkey->lock);
229         err = input_register_device(pwr);
230         if (err) {
231                 dev_dbg(&pdev->dev, "Can't register power key: %d\n", err);
232                 goto free_input_dev;
233         }
234         pwrkey->key_irq = key_irq;
235         pwrkey->pwr = pwr;
236         platform_set_drvdata(pdev, pwrkey);
237
238         /* Check if power-key is pressed at boot up */
239         err = ricoh619_read(pwrkey->dev->parent, RICOH619_INT_MON_SYS, &val);
240         if (err < 0) {
241                 dev_err(&pdev->dev, "Key-press status at boot failed rc=%d\n",
242                                                                          err);
243                 goto unreg_input_dev;
244         }
245         val &= 0x1;
246         if (val) {
247                 input_report_key(pwrkey->pwr, KEY_POWER, 1);
248 //              printk(KERN_INFO "******KEY_POWER:1\n");
249                 input_sync(pwrkey->pwr);
250                 pwrkey->pressed_first = true;
251         }
252
253         #if !(RICOH619_ONKEY_TRIGGER_LEVEL)
254                 /* trigger both edge */
255                 ricoh619_set_bits(pwrkey->dev->parent, RICOH619_PWR_IRSEL, 0x1);
256         #endif
257         err = request_threaded_irq(key_irq, NULL, pwrkey_irq,IRQF_ONESHOT, "ricoh619_pwrkey", pwrkey);
258         if (err < 0) {
259                 dev_err(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n",
260                                                                 key_irq, err);
261                 goto unreg_input_dev;
262         }
263         /*
264         #if RICOH619_ONKEY_OFF_IRQ
265         err = request_threaded_irq( key_irq +RICOH619_ONKEY_OFF_IRQ, NULL,pwrkey_irq_off, IRQF_ONESHOT,
266                                                 "ricoh619_pwrkey_off", pwrkey);
267         if (err < 0) {
268                 dev_err(&pdev->dev, "Can't get %d IRQ for ricoh619_pwrkey_off: %d\n",
269                         key_irq + RICOH619_ONKEY_OFF_IRQ, err);
270                 free_irq(key_irq, pwrkey);
271                 goto unreg_input_dev;
272         }
273         #endif
274 */
275         pwrkey->workqueue = create_singlethread_workqueue("ricoh619_pwrkey");
276         INIT_WORK(&pwrkey->work, ricoh619_irq_work);
277
278         /* Enable power key IRQ */
279         /* trigger both edge */
280         ricoh619_set_bits(pwrkey->dev->parent, RICOH619_PWR_IRSEL, 0x1);
281         /* Enable system interrupt */
282         ricoh619_set_bits(pwrkey->dev->parent, RICOH619_INTC_INTEN, 0x1);
283         /* Enable power-on interrupt */
284         ricoh619_set_bits(pwrkey->dev->parent, RICOH619_INT_EN_SYS, 0x1);
285 //      printk(KERN_INFO "PMU: %s is OK!\n", __func__);
286         return 0;
287
288 unreg_input_dev:
289         input_unregister_device(pwr);
290         pwr = NULL;
291
292 free_input_dev:
293         input_free_device(pwr);
294         free_pwrkey:
295         kfree(pwrkey);
296
297         return err;
298 }
299
300 static int ricoh619_pwrkey_remove(struct platform_device *pdev)
301 {
302         struct ricoh619_pwrkey *pwrkey = platform_get_drvdata(pdev);
303
304         flush_workqueue(pwrkey->workqueue);
305         destroy_workqueue(pwrkey->workqueue);
306         free_irq(pwrkey->key_irq, pwrkey);
307         input_unregister_device(pwrkey->pwr);
308         kfree(pwrkey);
309
310         return 0;
311 }
312
313 #ifdef CONFIG_PM
314 static int ricoh619_pwrkey_suspend(struct device *dev)
315 {
316         struct ricoh619_pwrkey *info = dev_get_drvdata(dev);
317
318 //      printk(KERN_INFO "PMU: %s\n", __func__);
319
320 //      if (info->key_irq)
321 //              disable_irq(info->key_irq);
322         cancel_work_sync(&info->work);
323         flush_workqueue(info->workqueue);
324
325         return 0;
326 }
327
328 static int ricoh619_pwrkey_resume(struct device *dev)
329 {
330         struct ricoh619_pwrkey *info = dev_get_drvdata(dev);
331
332 //      printk(KERN_INFO "PMU: %s\n", __func__);
333         queue_work(info->workqueue, &info->work);
334 //      if (info->key_irq)
335 //              enable_irq(info->key_irq);
336
337         return 0;
338 }
339
340 #ifdef CONFIG_OF
341 static const struct of_device_id ricoh619_pwrkey_dt_match[] = {
342         { .compatible = "ricoh,ricoh619-pwrkey", },
343         {},
344 };
345 MODULE_DEVICE_TABLE(of, ricoh619_pwrkey_dt_match);
346 #endif
347
348 static const struct dev_pm_ops ricoh619_pwrkey_pm_ops = {
349         .suspend        = ricoh619_pwrkey_suspend,
350         .resume         = ricoh619_pwrkey_resume,
351 };
352 #endif
353
354 static struct platform_driver ricoh619_pwrkey_driver = {
355         .probe = ricoh619_pwrkey_probe,
356         .remove = ricoh619_pwrkey_remove,
357         .driver = {
358                 .name = "ricoh619-pwrkey",
359                 .owner = THIS_MODULE,
360                 .of_match_table = of_match_ptr(ricoh619_pwrkey_dt_match),
361 #ifdef CONFIG_PM
362                 .pm     = &ricoh619_pwrkey_pm_ops,
363 #endif
364         },
365 };
366
367 static int __init ricoh619_pwrkey_init(void)
368 {
369         return platform_driver_register(&ricoh619_pwrkey_driver);
370 }
371 subsys_initcall_sync(ricoh619_pwrkey_init);
372
373 static void __exit ricoh619_pwrkey_exit(void)
374 {
375         platform_driver_unregister(&ricoh619_pwrkey_driver);
376 }
377 module_exit(ricoh619_pwrkey_exit);
378
379
380 MODULE_ALIAS("platform:ricoh619-pwrkey");
381 MODULE_AUTHOR("zhangqing <zhangqing@rock-chips.com>");
382 MODULE_DESCRIPTION("ricoh619 Power Key");
383 MODULE_LICENSE("GPL v2");