input: keyboard: rk_keys: add rk_keys.h
[firefly-linux-kernel-4.4.55.git] / drivers / input / misc / ricoh619-pwrkey.c
index 95018d288aafd7fe77b155282d882f3ba6d9dbf2..35b17f27f88f05ad4d40c9695713ebc0ea9ca0f1 100644 (file)
-/*\r
-* driver/input/misc/ricoh619-pwrkey.c\r
-*\r
-* Power Key driver for RICOH RC5T619 power management chip.\r
-*\r
-* Copyright (C) 2012-2013 RICOH COMPANY,LTD\r
-*\r
-*\r
-* This program is free software; you can redistribute it and/or modify\r
-* it under the terms of the GNU General Public License as published by\r
-* the Free Software Foundation; either version 2 of the License, or\r
-* (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful, but WITHOUT\r
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
-* more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program. If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-*/\r
-#include <linux/module.h>\r
-#include <linux/init.h>\r
-#include <linux/kernel.h>\r
-#include <linux/errno.h>\r
-#include <linux/input.h>\r
-#include <linux/interrupt.h>\r
-#include <linux/platform_device.h>\r
-#include <linux/mfd/ricoh619.h>\r
-#include <linux/spinlock.h>\r
-#include <linux/timer.h>\r
-#include <linux/pm.h>\r
-#include <linux/slab.h>\r
-#include <linux/pm_runtime.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/gpio.h>\r
-\r
-#include <linux/mfd/ricoh619.h>\r
-\r
-#define RICOH619_ONKEY_TRIGGER_LEVEL   0\r
-#define RICOH619_ONKEY_OFF_IRQ         0\r
-\r
-struct ricoh619_pwrkey {\r
-       struct device *dev;\r
-       struct input_dev *pwr;\r
-       #if RICOH619_ONKEY_TRIGGER_LEVEL\r
-               struct timer_list timer;\r
-       #endif\r
-       struct workqueue_struct *workqueue;\r
-       struct work_struct work;\r
-       unsigned long delay;\r
-       int key_irq;\r
-       bool pressed_first;\r
-       struct ricoh619_pwrkey_platform_data *pdata;\r
-       spinlock_t lock;\r
-};\r
-\r
-struct ricoh619_pwrkey *g_pwrkey;\r
-\r
-#if RICOH619_ONKEY_TRIGGER_LEVEL\r
-void ricoh619_pwrkey_timer(unsigned long t)\r
-{\r
-       queue_work(g_pwrkey->workqueue, &g_pwrkey->work);\r
-}\r
-#endif\r
-\r
-static void ricoh619_irq_work(struct work_struct *work)\r
-{\r
-       /* unsigned long flags; */\r
-       uint8_t val;\r
-\r
-//     printk("PMU: %s: \n",__func__);\r
-       //spin_lock_irqsave(&g_pwrkey->lock, flags);\r
-\r
-       if(pwrkey_wakeup){\r
-//             printk("PMU: %s: pwrkey_wakeup\n",__func__);\r
-               pwrkey_wakeup = 0;\r
-               input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 1);\r
-               input_event(g_pwrkey->pwr, EV_SYN, 0, 0);\r
-               input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 0);\r
-               input_event(g_pwrkey->pwr, EV_SYN, 0, 0);\r
-               \r
-               return;\r
-       }\r
-       ricoh619_read(g_pwrkey->dev->parent, RICOH619_INT_MON_SYS, &val);\r
-       dev_dbg(g_pwrkey->dev, "pwrkey is pressed?(0x%x): 0x%x\n",\r
-                                               RICOH619_INT_MON_SYS, val);\r
-//     printk(KERN_INFO "PMU: %s: val=0x%x\n", __func__, val);\r
-       val &= 0x1;\r
-       if(val){\r
-               #if (RICOH619_ONKEY_TRIGGER_LEVEL)\r
-               g_pwrkey->timer.expires = jiffies + g_pwrkey->delay;\r
-               dd_timer(&g_pwrkey->timer);\r
-               #endif\r
-               if (!g_pwrkey->pressed_first){\r
-                       g_pwrkey->pressed_first = true;\r
-//                     printk("PMU1: %s: Power Key!!!\n",__func__);\r
-                       //input_report_key(g_pwrkey->pwr, KEY_POWER, 1);\r
-                       //input_sync(g_pwrkey->pwr);\r
-                       input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 1);\r
-                       input_event(g_pwrkey->pwr, EV_SYN, 0, 0);\r
-               }\r
-       } else {\r
-               if (g_pwrkey->pressed_first) {\r
-//                     printk(KERN_INFO "PMU2: %s: Power Key!!!\n", __func__);\r
-                       /* input_report_key(g_pwrkey->pwr, KEY_POWER, 0); */\r
-                       /* input_sync(g_pwrkey->pwr); */\r
-                       input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 0);\r
-                       input_event(g_pwrkey->pwr, EV_SYN, 0, 0);\r
-               }\r
-               g_pwrkey->pressed_first = false;\r
-       }\r
-\r
-       /* spin_unlock_irqrestore(&g_pwrkey->lock, flags); */\r
-}\r
-\r
-static irqreturn_t pwrkey_irq(int irq, void *_pwrkey)\r
-{\r
-//     printk(KERN_INFO "PMU: %s:\n", __func__);\r
-\r
-       #if (RICOH619_ONKEY_TRIGGER_LEVEL)\r
-       g_pwrkey->timer.expires = jiffies + g_pwrkey->delay;\r
-       add_timer(&g_pwrkey->timer);\r
-       #else\r
-       queue_work(g_pwrkey->workqueue, &g_pwrkey->work);\r
-       #endif\r
-       return IRQ_HANDLED;\r
-}\r
-\r
-#if RICOH619_ONKEY_OFF_IRQ\r
-static irqreturn_t pwrkey_irq_off(int irq, void *_pwrkey)\r
-{\r
-       dev_warn(g_pwrkey->dev, "ONKEY is pressed long time!\n");\r
-       return IRQ_HANDLED;\r
-}\r
-#endif\r
-\r
-static int __devinit ricoh619_pwrkey_probe(struct platform_device *pdev)\r
-{\r
-       struct input_dev *pwr;\r
-       int key_irq;\r
-       int err;\r
-       struct ricoh619_pwrkey *pwrkey;\r
-       struct ricoh619_pwrkey_platform_data *pdata = pdev->dev.platform_data;\r
-       uint8_t val;\r
-\r
-//     printk("PMU: %s: \n",__func__);\r
-\r
-       if (!pdata) {\r
-               dev_err(&pdev->dev, "power key platform data not supplied\n");\r
-               return -EINVAL;\r
-       }\r
-       key_irq = (pdata->irq + RICOH619_IRQ_POWER_ON);\r
-       printk(KERN_INFO "PMU1: %s: key_irq=%d\n", __func__, key_irq);\r
-       pwrkey = kzalloc(sizeof(*pwrkey), GFP_KERNEL);\r
-       if (!pwrkey)\r
-               return -ENOMEM;\r
-\r
-       pwrkey->dev = &pdev->dev;\r
-       pwrkey->pdata = pdata;\r
-       pwrkey->pressed_first = false;\r
-       pwrkey->delay = HZ / 1000 * pdata->delay_ms;\r
-       g_pwrkey = pwrkey;\r
-       pwr = input_allocate_device();\r
-       if (!pwr) {\r
-               dev_dbg(&pdev->dev, "Can't allocate power button\n");\r
-               err = -ENOMEM;\r
-               goto free_pwrkey;\r
-       }\r
-       input_set_capability(pwr, EV_KEY, KEY_POWER);\r
-       pwr->name = "ricoh619_pwrkey";\r
-       pwr->phys = "ricoh619_pwrkey/input0";\r
-       pwr->dev.parent = &pdev->dev;\r
-\r
-       #if RICOH619_ONKEY_TRIGGER_LEVEL\r
-       init_timer(&pwrkey->timer);\r
-       pwrkey->timer.function = ricoh619_pwrkey_timer;\r
-       #endif\r
-\r
-       spin_lock_init(&pwrkey->lock);\r
-       err = input_register_device(pwr);\r
-       if (err) {\r
-               dev_dbg(&pdev->dev, "Can't register power key: %d\n", err);\r
-               goto free_input_dev;\r
-       }\r
-       pwrkey->key_irq = key_irq;\r
-       pwrkey->pwr = pwr;\r
-       platform_set_drvdata(pdev, pwrkey);\r
-\r
-       /* Check if power-key is pressed at boot up */\r
-       err = ricoh619_read(pwrkey->dev->parent, RICOH619_INT_MON_SYS, &val);\r
-       if (err < 0) {\r
-               dev_err(&pdev->dev, "Key-press status at boot failed rc=%d\n",\r
-                                                                        err);\r
-               goto unreg_input_dev;\r
-       }\r
-       val &= 0x1;\r
-       if (val) {\r
-               input_report_key(pwrkey->pwr, KEY_POWER, 1);\r
-//             printk(KERN_INFO "******KEY_POWER:1\n");\r
-               input_sync(pwrkey->pwr);\r
-               pwrkey->pressed_first = true;\r
-       }\r
-\r
-       #if !(RICOH619_ONKEY_TRIGGER_LEVEL)\r
-               /* trigger both edge */\r
-               ricoh619_set_bits(pwrkey->dev->parent, RICOH619_PWR_IRSEL, 0x1);\r
-       #endif\r
-\r
-       err = request_threaded_irq(key_irq, NULL, pwrkey_irq,\r
-               IRQF_ONESHOT, "ricoh619_pwrkey", pwrkey);\r
-       if (err < 0) {\r
-               dev_err(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n",\r
-                                                               key_irq, err);\r
-               goto unreg_input_dev;\r
-       }\r
-\r
-       #if RICOH619_ONKEY_OFF_IRQ\r
-       err = request_threaded_irq(key_irq + RICOH619_IRQ_ONKEY_OFF, NULL,\r
-                                               pwrkey_irq_off, IRQF_ONESHOT,\r
-                                               "ricoh619_pwrkey_off", pwrkey);\r
-       if (err < 0) {\r
-               dev_err(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n",\r
-                       key_irq + RICOH619_IRQ_ONKEY_OFF, err);\r
-               free_irq(key_irq, pwrkey);\r
-               goto unreg_input_dev;\r
-       }\r
-       #endif\r
-\r
-       pwrkey->workqueue = create_singlethread_workqueue("ricoh619_pwrkey");\r
-       INIT_WORK(&pwrkey->work, ricoh619_irq_work);\r
-\r
-       /* Enable power key IRQ */\r
-       /* trigger both edge */\r
-       ricoh619_set_bits(pwrkey->dev->parent, RICOH619_PWR_IRSEL, 0x1);\r
-       /* Enable system interrupt */\r
-       ricoh619_set_bits(pwrkey->dev->parent, RICOH619_INTC_INTEN, 0x1);\r
-       /* Enable power-on interrupt */\r
-       ricoh619_set_bits(pwrkey->dev->parent, RICOH619_INT_EN_SYS, 0x1);\r
-//     printk(KERN_INFO "PMU: %s is OK!\n", __func__);\r
-       return 0;\r
-\r
-unreg_input_dev:\r
-       input_unregister_device(pwr);\r
-       pwr = NULL;\r
-\r
-free_input_dev:\r
-       input_free_device(pwr);\r
-       free_pwrkey:\r
-       kfree(pwrkey);\r
-\r
-       return err;\r
-}\r
-\r
-static int __devexit ricoh619_pwrkey_remove(struct platform_device *pdev)\r
-{\r
-       struct ricoh619_pwrkey *pwrkey = platform_get_drvdata(pdev);\r
-\r
-       flush_workqueue(pwrkey->workqueue);\r
-       destroy_workqueue(pwrkey->workqueue);\r
-       free_irq(pwrkey->key_irq, pwrkey);\r
-       input_unregister_device(pwrkey->pwr);\r
-       kfree(pwrkey);\r
-\r
-       return 0;\r
-}\r
-\r
-#ifdef CONFIG_PM\r
-static int ricoh619_pwrkey_suspend(struct device *dev)\r
-{\r
-       struct ricoh619_pwrkey *info = dev_get_drvdata(dev);\r
-\r
-//     printk(KERN_INFO "PMU: %s\n", __func__);\r
-\r
-       if (info->key_irq)\r
-               disable_irq(info->key_irq);\r
-       cancel_work_sync(&info->work);\r
-       flush_workqueue(info->workqueue);\r
-\r
-       return 0;\r
-}\r
-\r
-static int ricoh619_pwrkey_resume(struct device *dev)\r
-{\r
-       struct ricoh619_pwrkey *info = dev_get_drvdata(dev);\r
-\r
-//     printk(KERN_INFO "PMU: %s\n", __func__);\r
-       queue_work(info->workqueue, &info->work);\r
-       if (info->key_irq)\r
-               enable_irq(info->key_irq);\r
-\r
-       return 0;\r
-}\r
-\r
-static const struct dev_pm_ops ricoh619_pwrkey_pm_ops = {\r
-       .suspend        = ricoh619_pwrkey_suspend,\r
-       .resume         = ricoh619_pwrkey_resume,\r
-};\r
-#endif\r
-\r
-static struct platform_driver ricoh619_pwrkey_driver = {\r
-       .probe = ricoh619_pwrkey_probe,\r
-       .remove = __devexit_p(ricoh619_pwrkey_remove),\r
-       .driver = {\r
-               .name = "ricoh619-pwrkey",\r
-               .owner = THIS_MODULE,\r
-#ifdef CONFIG_PM\r
-               .pm     = &ricoh619_pwrkey_pm_ops,\r
-#endif\r
-       },\r
-};\r
-\r
-static int __init ricoh619_pwrkey_init(void)\r
-{\r
-       return platform_driver_register(&ricoh619_pwrkey_driver);\r
-}\r
-subsys_initcall_sync(ricoh619_pwrkey_init);\r
-\r
-static void __exit ricoh619_pwrkey_exit(void)\r
-{\r
-       platform_driver_unregister(&ricoh619_pwrkey_driver);\r
-}\r
-module_exit(ricoh619_pwrkey_exit);\r
-\r
-\r
-MODULE_ALIAS("platform:ricoh619-pwrkey");\r
-MODULE_AUTHOR("zhangqing <zhangqing@rock-chips.com>");\r
-MODULE_DESCRIPTION("ricoh619 Power Key");\r
-MODULE_LICENSE("GPL v2");
\ No newline at end of file
+/*
+* driver/input/misc/ricoh619-pwrkey.c
+*
+* Power Key driver for RICOH RC5T619 power management chip.
+*
+* Copyright (C) 2012-2013 RICOH COMPANY,LTD
+*
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/ricoh619.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
+#include <linux/workqueue.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/delay.h>
+
+#include <linux/mfd/ricoh619.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+
+#define RICOH619_ONKEY_TRIGGER_LEVEL   0
+#define RICOH619_ONKEY_OFF_IRQ         0
+
+struct ricoh619_pwrkey {
+       struct device *dev;
+       struct input_dev *pwr;
+       #if RICOH619_ONKEY_TRIGGER_LEVEL
+               struct timer_list timer;
+       #endif
+       struct workqueue_struct *workqueue;
+       struct work_struct work;
+       unsigned long delay;
+       int key_irq;
+       bool pressed_first;
+       struct ricoh619_pwrkey_platform_data *pdata;
+       spinlock_t lock;
+};
+
+struct ricoh619_pwrkey *g_pwrkey;
+
+#if RICOH619_ONKEY_TRIGGER_LEVEL
+void ricoh619_pwrkey_timer(unsigned long t)
+{
+       queue_work(g_pwrkey->workqueue, &g_pwrkey->work);
+}
+#endif
+extern u8 ricoh619_pwr_key_reg;
+static void ricoh619_irq_work(struct work_struct *work)
+{
+       /* unsigned long flags; */
+       uint8_t val;
+       int i=0;
+
+//     printk("PMU: %s: \n",__func__);
+       //spin_lock_irqsave(&g_pwrkey->lock, flags);
+       if((ricoh619_pwr_key_reg & 0x01) && ricoh619_pwrkey_wakeup){
+               printk("PMU: %s: pwrkey_wakeup\n",__func__);
+               ricoh619_pwrkey_wakeup = 0;
+               input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 1);
+               input_event(g_pwrkey->pwr, EV_SYN, 0, 0);
+               input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 0);
+               input_event(g_pwrkey->pwr, EV_SYN, 0, 0);
+               do{
+                       ricoh619_read(g_pwrkey->dev->parent, RICOH619_INT_MON_SYS, &val);
+                       val &= 0x01;
+                       i += 1;
+                       msleep(100);
+               }while(val && (i < 15));
+               return;
+       }
+       ricoh619_read(g_pwrkey->dev->parent, RICOH619_INT_MON_SYS, &val);
+       dev_dbg(g_pwrkey->dev, "pwrkey is pressed?(0x%x): 0x%x\n",
+                                               RICOH619_INT_MON_SYS, val);
+//     printk(KERN_INFO "PMU: %s: val=0x%x\n", __func__, val);
+       val &= 0x1;
+       if(val){
+               #if (RICOH619_ONKEY_TRIGGER_LEVEL)
+               g_pwrkey->timer.expires = jiffies + g_pwrkey->delay;
+               add_timer(&g_pwrkey->timer);
+               #endif
+               if (!g_pwrkey->pressed_first){
+                       g_pwrkey->pressed_first = true;
+//                     printk("PMU1: %s: Power Key!!!\n",__func__);
+                       //input_report_key(g_pwrkey->pwr, KEY_POWER, 1);
+                       //input_sync(g_pwrkey->pwr);
+                       input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 1);
+                       input_event(g_pwrkey->pwr, EV_SYN, 0, 0);
+               }
+       } else {
+               if (g_pwrkey->pressed_first) {
+//                     printk(KERN_INFO "PMU2: %s: Power Key!!!\n", __func__);
+                       /* input_report_key(g_pwrkey->pwr, KEY_POWER, 0); */
+                       /* input_sync(g_pwrkey->pwr); */
+                       input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 0);
+                       input_event(g_pwrkey->pwr, EV_SYN, 0, 0);
+               }
+               g_pwrkey->pressed_first = false;
+       }
+
+       /* spin_unlock_irqrestore(&g_pwrkey->lock, flags); */
+}
+
+static irqreturn_t pwrkey_irq(int irq, void *_pwrkey)
+{
+//     printk(KERN_INFO "PMU: %s:\n", __func__);
+//     rk_send_wakeup_key();
+       #if (RICOH619_ONKEY_TRIGGER_LEVEL)
+       g_pwrkey->timer.expires = jiffies + g_pwrkey->delay;
+       add_timer(&g_pwrkey->timer);
+       #else
+       queue_work(g_pwrkey->workqueue, &g_pwrkey->work);
+       #endif
+       return IRQ_HANDLED;
+}
+
+#if RICOH619_ONKEY_OFF_IRQ
+static irqreturn_t pwrkey_irq_off(int irq, void *_pwrkey)
+{
+       dev_warn(g_pwrkey->dev, "ONKEY is pressed long time!\n");
+       return IRQ_HANDLED;
+}
+#endif
+
+#ifdef CONFIG_OF
+static struct ricoh619_pwrkey_platform_data *
+ricoh619_pwrkey_dt_init(struct platform_device *pdev)
+{
+       struct device_node *nproot = pdev->dev.parent->of_node;
+       struct device_node *np;
+       struct ricoh619_pwrkey_platform_data *pdata;
+
+       if (!nproot)
+               return pdev->dev.platform_data;
+
+       np = of_find_node_by_name(nproot, "pwrkey");
+       if (!np) {
+               dev_err(&pdev->dev, "failed to find pwrkey node\n");
+               return NULL;
+       }
+
+       pdata = devm_kzalloc(&pdev->dev,
+                       sizeof(struct ricoh619_pwrkey_platform_data),
+                       GFP_KERNEL);
+
+       of_property_read_u32(np, "ricoh,pwrkey-delay-ms", &pdata->delay_ms);
+       of_node_put(np);
+
+       return pdata;
+}
+#else
+static struct ricoh619_pwrkey_platform_data *
+ricoh619_pwrkey_dt_init(struct platform_device *pdev)
+{
+       return pdev->dev.platform_data;
+}
+#endif
+
+static int ricoh619_pwrkey_probe(struct platform_device *pdev)
+{
+       struct input_dev *pwr;
+       int key_irq;
+       int err;
+       struct ricoh619_pwrkey *pwrkey;
+       struct ricoh619_pwrkey_platform_data *pdata;
+       struct ricoh619 *ricoh619 = dev_get_drvdata(pdev->dev.parent);
+       uint8_t val;
+
+//     printk("PMU: %s: \n",__func__);
+
+       pdata = ricoh619_pwrkey_dt_init(pdev);
+       if (!pdata) {
+               dev_err(&pdev->dev, "platform data isn't assigned to "
+                       "power key\n");
+               return -EINVAL;
+       }
+       key_irq  = irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_POWER_ON);
+       printk(KERN_INFO "PMU1: %s: key_irq=%d\n", __func__, key_irq);
+       pwrkey = kzalloc(sizeof(*pwrkey), GFP_KERNEL);
+       if (!pwrkey)
+               return -ENOMEM;
+
+       pwrkey->dev = &pdev->dev;
+       pwrkey->pdata = pdata;
+       pwrkey->pressed_first = false;
+       pwrkey->delay = HZ / 1000 * pdata->delay_ms;
+       g_pwrkey = pwrkey;
+       pwr = input_allocate_device();
+       if (!pwr) {
+               dev_dbg(&pdev->dev, "Can't allocate power button\n");
+               err = -ENOMEM;
+               goto free_pwrkey;
+       }
+       input_set_capability(pwr, EV_KEY, KEY_POWER);
+       pwr->name = "ricoh619_pwrkey";
+       pwr->phys = "ricoh619_pwrkey/input0";
+       pwr->dev.parent = &pdev->dev;
+
+       #if RICOH619_ONKEY_TRIGGER_LEVEL
+       init_timer(&pwrkey->timer);
+       pwrkey->timer.function = ricoh619_pwrkey_timer;
+       #endif
+
+       spin_lock_init(&pwrkey->lock);
+       err = input_register_device(pwr);
+       if (err) {
+               dev_dbg(&pdev->dev, "Can't register power key: %d\n", err);
+               goto free_input_dev;
+       }
+       pwrkey->key_irq = key_irq;
+       pwrkey->pwr = pwr;
+       platform_set_drvdata(pdev, pwrkey);
+
+       /* Check if power-key is pressed at boot up */
+       err = ricoh619_read(pwrkey->dev->parent, RICOH619_INT_MON_SYS, &val);
+       if (err < 0) {
+               dev_err(&pdev->dev, "Key-press status at boot failed rc=%d\n",
+                                                                        err);
+               goto unreg_input_dev;
+       }
+       val &= 0x1;
+       if (val) {
+               input_report_key(pwrkey->pwr, KEY_POWER, 1);
+//             printk(KERN_INFO "******KEY_POWER:1\n");
+               input_sync(pwrkey->pwr);
+               pwrkey->pressed_first = true;
+       }
+
+       #if !(RICOH619_ONKEY_TRIGGER_LEVEL)
+               /* trigger both edge */
+               ricoh619_set_bits(pwrkey->dev->parent, RICOH619_PWR_IRSEL, 0x1);
+       #endif
+       err = request_threaded_irq(key_irq, NULL, pwrkey_irq,IRQF_ONESHOT, "ricoh619_pwrkey", pwrkey);
+       if (err < 0) {
+               dev_err(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n",
+                                                               key_irq, err);
+               goto unreg_input_dev;
+       }
+       /*
+       #if RICOH619_ONKEY_OFF_IRQ
+       err = request_threaded_irq( key_irq +RICOH619_ONKEY_OFF_IRQ, NULL,pwrkey_irq_off, IRQF_ONESHOT,
+                                               "ricoh619_pwrkey_off", pwrkey);
+       if (err < 0) {
+               dev_err(&pdev->dev, "Can't get %d IRQ for ricoh619_pwrkey_off: %d\n",
+                       key_irq + RICOH619_ONKEY_OFF_IRQ, err);
+               free_irq(key_irq, pwrkey);
+               goto unreg_input_dev;
+       }
+       #endif
+*/
+       pwrkey->workqueue = create_singlethread_workqueue("ricoh619_pwrkey");
+       INIT_WORK(&pwrkey->work, ricoh619_irq_work);
+
+       /* Enable power key IRQ */
+       /* trigger both edge */
+       ricoh619_set_bits(pwrkey->dev->parent, RICOH619_PWR_IRSEL, 0x1);
+       /* Enable system interrupt */
+       ricoh619_set_bits(pwrkey->dev->parent, RICOH619_INTC_INTEN, 0x1);
+       /* Enable power-on interrupt */
+       ricoh619_set_bits(pwrkey->dev->parent, RICOH619_INT_EN_SYS, 0x1);
+//     printk(KERN_INFO "PMU: %s is OK!\n", __func__);
+       return 0;
+
+unreg_input_dev:
+       input_unregister_device(pwr);
+       pwr = NULL;
+
+free_input_dev:
+       input_free_device(pwr);
+       free_pwrkey:
+       kfree(pwrkey);
+
+       return err;
+}
+
+static int ricoh619_pwrkey_remove(struct platform_device *pdev)
+{
+       struct ricoh619_pwrkey *pwrkey = platform_get_drvdata(pdev);
+
+       flush_workqueue(pwrkey->workqueue);
+       destroy_workqueue(pwrkey->workqueue);
+       free_irq(pwrkey->key_irq, pwrkey);
+       input_unregister_device(pwrkey->pwr);
+       kfree(pwrkey);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int ricoh619_pwrkey_suspend(struct device *dev)
+{
+       struct ricoh619_pwrkey *info = dev_get_drvdata(dev);
+
+//     printk(KERN_INFO "PMU: %s\n", __func__);
+
+//     if (info->key_irq)
+//             disable_irq(info->key_irq);
+       cancel_work_sync(&info->work);
+       flush_workqueue(info->workqueue);
+
+       return 0;
+}
+
+static int ricoh619_pwrkey_resume(struct device *dev)
+{
+       struct ricoh619_pwrkey *info = dev_get_drvdata(dev);
+
+//     printk(KERN_INFO "PMU: %s\n", __func__);
+       queue_work(info->workqueue, &info->work);
+//     if (info->key_irq)
+//             enable_irq(info->key_irq);
+
+       return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id ricoh619_pwrkey_dt_match[] = {
+       { .compatible = "ricoh,ricoh619-pwrkey", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, ricoh619_pwrkey_dt_match);
+#endif
+
+static const struct dev_pm_ops ricoh619_pwrkey_pm_ops = {
+       .suspend        = ricoh619_pwrkey_suspend,
+       .resume         = ricoh619_pwrkey_resume,
+};
+#endif
+
+static struct platform_driver ricoh619_pwrkey_driver = {
+       .probe = ricoh619_pwrkey_probe,
+       .remove = ricoh619_pwrkey_remove,
+       .driver = {
+               .name = "ricoh619-pwrkey",
+               .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(ricoh619_pwrkey_dt_match),
+#ifdef CONFIG_PM
+               .pm     = &ricoh619_pwrkey_pm_ops,
+#endif
+       },
+};
+
+static int __init ricoh619_pwrkey_init(void)
+{
+       return platform_driver_register(&ricoh619_pwrkey_driver);
+}
+subsys_initcall_sync(ricoh619_pwrkey_init);
+
+static void __exit ricoh619_pwrkey_exit(void)
+{
+       platform_driver_unregister(&ricoh619_pwrkey_driver);
+}
+module_exit(ricoh619_pwrkey_exit);
+
+
+MODULE_ALIAS("platform:ricoh619-pwrkey");
+MODULE_AUTHOR("zhangqing <zhangqing@rock-chips.com>");
+MODULE_DESCRIPTION("ricoh619 Power Key");
+MODULE_LICENSE("GPL v2");