2 * driver/input/misc/ricoh619-pwrkey.c
4 * Power Key driver for RICOH RC5T619 power management chip.
6 * Copyright (C) 2012-2013 RICOH COMPANY,LTD
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.
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
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/>.
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>
34 #include <linux/slab.h>
35 #include <linux/pm_runtime.h>
36 #include <linux/workqueue.h>
37 #include <linux/gpio.h>
39 #include <linux/delay.h>
41 #include <linux/mfd/ricoh619.h>
42 #include <linux/irq.h>
43 #include <linux/irqdomain.h>
45 #define RICOH619_ONKEY_TRIGGER_LEVEL 0
46 #define RICOH619_ONKEY_OFF_IRQ 0
48 struct ricoh619_pwrkey {
50 struct input_dev *pwr;
51 #if RICOH619_ONKEY_TRIGGER_LEVEL
52 struct timer_list timer;
54 struct workqueue_struct *workqueue;
55 struct work_struct work;
59 struct ricoh619_pwrkey_platform_data *pdata;
63 struct ricoh619_pwrkey *g_pwrkey;
65 #if RICOH619_ONKEY_TRIGGER_LEVEL
66 void ricoh619_pwrkey_timer(unsigned long t)
68 queue_work(g_pwrkey->workqueue, &g_pwrkey->work);
71 extern u8 ricoh619_pwr_key_reg;
72 static void ricoh619_irq_work(struct work_struct *work)
74 /* unsigned long flags; */
78 // printk("PMU: %s: \n",__func__);
79 //spin_lock_irqsave(&g_pwrkey->lock, flags);
80 if((ricoh619_pwr_key_reg & 0x01) && ricoh619_pwrkey_wakeup){
81 printk("PMU: %s: pwrkey_wakeup\n",__func__);
82 ricoh619_pwrkey_wakeup = 0;
83 input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 1);
84 input_event(g_pwrkey->pwr, EV_SYN, 0, 0);
85 input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 0);
86 input_event(g_pwrkey->pwr, EV_SYN, 0, 0);
88 ricoh619_read(g_pwrkey->dev->parent, RICOH619_INT_MON_SYS, &val);
92 }while(val && (i < 15));
95 ricoh619_read(g_pwrkey->dev->parent, RICOH619_INT_MON_SYS, &val);
96 dev_dbg(g_pwrkey->dev, "pwrkey is pressed?(0x%x): 0x%x\n",
97 RICOH619_INT_MON_SYS, val);
98 // printk(KERN_INFO "PMU: %s: val=0x%x\n", __func__, val);
101 #if (RICOH619_ONKEY_TRIGGER_LEVEL)
102 g_pwrkey->timer.expires = jiffies + g_pwrkey->delay;
103 add_timer(&g_pwrkey->timer);
105 if (!g_pwrkey->pressed_first){
106 g_pwrkey->pressed_first = true;
107 // printk("PMU1: %s: Power Key!!!\n",__func__);
108 //input_report_key(g_pwrkey->pwr, KEY_POWER, 1);
109 //input_sync(g_pwrkey->pwr);
110 input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 1);
111 input_event(g_pwrkey->pwr, EV_SYN, 0, 0);
114 if (g_pwrkey->pressed_first) {
115 // printk(KERN_INFO "PMU2: %s: Power Key!!!\n", __func__);
116 /* input_report_key(g_pwrkey->pwr, KEY_POWER, 0); */
117 /* input_sync(g_pwrkey->pwr); */
118 input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 0);
119 input_event(g_pwrkey->pwr, EV_SYN, 0, 0);
121 g_pwrkey->pressed_first = false;
124 /* spin_unlock_irqrestore(&g_pwrkey->lock, flags); */
127 static irqreturn_t pwrkey_irq(int irq, void *_pwrkey)
129 // printk(KERN_INFO "PMU: %s:\n", __func__);
130 // rk_send_wakeup_key();
131 #if (RICOH619_ONKEY_TRIGGER_LEVEL)
132 g_pwrkey->timer.expires = jiffies + g_pwrkey->delay;
133 add_timer(&g_pwrkey->timer);
135 queue_work(g_pwrkey->workqueue, &g_pwrkey->work);
140 #if RICOH619_ONKEY_OFF_IRQ
141 static irqreturn_t pwrkey_irq_off(int irq, void *_pwrkey)
143 dev_warn(g_pwrkey->dev, "ONKEY is pressed long time!\n");
149 static struct ricoh619_pwrkey_platform_data *
150 ricoh619_pwrkey_dt_init(struct platform_device *pdev)
152 struct device_node *nproot = pdev->dev.parent->of_node;
153 struct device_node *np;
154 struct ricoh619_pwrkey_platform_data *pdata;
157 return pdev->dev.platform_data;
159 np = of_find_node_by_name(nproot, "pwrkey");
161 dev_err(&pdev->dev, "failed to find pwrkey node\n");
165 pdata = devm_kzalloc(&pdev->dev,
166 sizeof(struct ricoh619_pwrkey_platform_data),
169 of_property_read_u32(np, "ricoh,pwrkey-delay-ms", &pdata->delay_ms);
175 static struct ricoh619_pwrkey_platform_data *
176 ricoh619_pwrkey_dt_init(struct platform_device *pdev)
178 return pdev->dev.platform_data;
182 static int ricoh619_pwrkey_probe(struct platform_device *pdev)
184 struct input_dev *pwr;
187 struct ricoh619_pwrkey *pwrkey;
188 struct ricoh619_pwrkey_platform_data *pdata;
189 struct ricoh619 *ricoh619 = dev_get_drvdata(pdev->dev.parent);
192 // printk("PMU: %s: \n",__func__);
194 pdata = ricoh619_pwrkey_dt_init(pdev);
196 dev_err(&pdev->dev, "platform data isn't assigned to "
200 key_irq = irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_POWER_ON);
201 printk(KERN_INFO "PMU1: %s: key_irq=%d\n", __func__, key_irq);
202 pwrkey = kzalloc(sizeof(*pwrkey), GFP_KERNEL);
206 pwrkey->dev = &pdev->dev;
207 pwrkey->pdata = pdata;
208 pwrkey->pressed_first = false;
209 pwrkey->delay = HZ / 1000 * pdata->delay_ms;
211 pwr = input_allocate_device();
213 dev_dbg(&pdev->dev, "Can't allocate power button\n");
217 input_set_capability(pwr, EV_KEY, KEY_POWER);
218 pwr->name = "ricoh619_pwrkey";
219 pwr->phys = "ricoh619_pwrkey/input0";
220 pwr->dev.parent = &pdev->dev;
222 #if RICOH619_ONKEY_TRIGGER_LEVEL
223 init_timer(&pwrkey->timer);
224 pwrkey->timer.function = ricoh619_pwrkey_timer;
227 spin_lock_init(&pwrkey->lock);
228 err = input_register_device(pwr);
230 dev_dbg(&pdev->dev, "Can't register power key: %d\n", err);
233 pwrkey->key_irq = key_irq;
235 platform_set_drvdata(pdev, pwrkey);
237 /* Check if power-key is pressed at boot up */
238 err = ricoh619_read(pwrkey->dev->parent, RICOH619_INT_MON_SYS, &val);
240 dev_err(&pdev->dev, "Key-press status at boot failed rc=%d\n",
242 goto unreg_input_dev;
246 input_report_key(pwrkey->pwr, KEY_POWER, 1);
247 // printk(KERN_INFO "******KEY_POWER:1\n");
248 input_sync(pwrkey->pwr);
249 pwrkey->pressed_first = true;
252 #if !(RICOH619_ONKEY_TRIGGER_LEVEL)
253 /* trigger both edge */
254 ricoh619_set_bits(pwrkey->dev->parent, RICOH619_PWR_IRSEL, 0x1);
256 err = request_threaded_irq(key_irq, NULL, pwrkey_irq,IRQF_ONESHOT, "ricoh619_pwrkey", pwrkey);
258 dev_err(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n",
260 goto unreg_input_dev;
263 #if RICOH619_ONKEY_OFF_IRQ
264 err = request_threaded_irq( key_irq +RICOH619_ONKEY_OFF_IRQ, NULL,pwrkey_irq_off, IRQF_ONESHOT,
265 "ricoh619_pwrkey_off", pwrkey);
267 dev_err(&pdev->dev, "Can't get %d IRQ for ricoh619_pwrkey_off: %d\n",
268 key_irq + RICOH619_ONKEY_OFF_IRQ, err);
269 free_irq(key_irq, pwrkey);
270 goto unreg_input_dev;
274 pwrkey->workqueue = create_singlethread_workqueue("ricoh619_pwrkey");
275 INIT_WORK(&pwrkey->work, ricoh619_irq_work);
277 /* Enable power key IRQ */
278 /* trigger both edge */
279 ricoh619_set_bits(pwrkey->dev->parent, RICOH619_PWR_IRSEL, 0x1);
280 /* Enable system interrupt */
281 ricoh619_set_bits(pwrkey->dev->parent, RICOH619_INTC_INTEN, 0x1);
282 /* Enable power-on interrupt */
283 ricoh619_set_bits(pwrkey->dev->parent, RICOH619_INT_EN_SYS, 0x1);
284 // printk(KERN_INFO "PMU: %s is OK!\n", __func__);
288 input_unregister_device(pwr);
292 input_free_device(pwr);
299 static int ricoh619_pwrkey_remove(struct platform_device *pdev)
301 struct ricoh619_pwrkey *pwrkey = platform_get_drvdata(pdev);
303 flush_workqueue(pwrkey->workqueue);
304 destroy_workqueue(pwrkey->workqueue);
305 free_irq(pwrkey->key_irq, pwrkey);
306 input_unregister_device(pwrkey->pwr);
313 static int ricoh619_pwrkey_suspend(struct device *dev)
315 struct ricoh619_pwrkey *info = dev_get_drvdata(dev);
317 // printk(KERN_INFO "PMU: %s\n", __func__);
319 // if (info->key_irq)
320 // disable_irq(info->key_irq);
321 cancel_work_sync(&info->work);
322 flush_workqueue(info->workqueue);
327 static int ricoh619_pwrkey_resume(struct device *dev)
329 struct ricoh619_pwrkey *info = dev_get_drvdata(dev);
331 // printk(KERN_INFO "PMU: %s\n", __func__);
332 queue_work(info->workqueue, &info->work);
333 // if (info->key_irq)
334 // enable_irq(info->key_irq);
340 static const struct of_device_id ricoh619_pwrkey_dt_match[] = {
341 { .compatible = "ricoh,ricoh619-pwrkey", },
344 MODULE_DEVICE_TABLE(of, ricoh619_pwrkey_dt_match);
347 static const struct dev_pm_ops ricoh619_pwrkey_pm_ops = {
348 .suspend = ricoh619_pwrkey_suspend,
349 .resume = ricoh619_pwrkey_resume,
353 static struct platform_driver ricoh619_pwrkey_driver = {
354 .probe = ricoh619_pwrkey_probe,
355 .remove = ricoh619_pwrkey_remove,
357 .name = "ricoh619-pwrkey",
358 .owner = THIS_MODULE,
359 .of_match_table = of_match_ptr(ricoh619_pwrkey_dt_match),
361 .pm = &ricoh619_pwrkey_pm_ops,
366 static int __init ricoh619_pwrkey_init(void)
368 return platform_driver_register(&ricoh619_pwrkey_driver);
370 subsys_initcall_sync(ricoh619_pwrkey_init);
372 static void __exit ricoh619_pwrkey_exit(void)
374 platform_driver_unregister(&ricoh619_pwrkey_driver);
376 module_exit(ricoh619_pwrkey_exit);
379 MODULE_ALIAS("platform:ricoh619-pwrkey");
380 MODULE_AUTHOR("zhangqing <zhangqing@rock-chips.com>");
381 MODULE_DESCRIPTION("ricoh619 Power Key");
382 MODULE_LICENSE("GPL v2");