HID: i2c-hid: add support wakeup
authorZhou weixin <zwx@rock-chips.com>
Mon, 19 Dec 2016 03:04:36 +0000 (11:04 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Thu, 22 Dec 2016 08:24:27 +0000 (16:24 +0800)
Change-Id: I15890509ff5983e1a8adaa48b28391ec67de8bb5
Signed-off-by: Zhou weixin <zwx@rock-chips.com>
drivers/hid/i2c-hid/i2c-hid.c

index 0b80633bae91ecb180a7b0d4d245a8dec6313e0d..6c37c4a039f081a35948bdbf61d43453add16324 100644 (file)
@@ -38,6 +38,9 @@
 #include <linux/acpi.h>
 #include <linux/of.h>
 #include <linux/gpio/consumer.h>
+#include <linux/fb.h>
+#include <linux/notifier.h>
+#include <linux/rk_keys.h>
 
 #include <linux/i2c/i2c-hid.h>
 
@@ -151,8 +154,40 @@ struct i2c_hid {
        struct i2c_hid_platform_data pdata;
 
        bool                    irq_wake_enabled;
+
+       struct notifier_block fb_notif;
+       int is_suspend;
 };
 
+static int ihid_fb_notifier_callback(struct notifier_block *self,
+                                    unsigned long action, void *data)
+{
+       struct i2c_hid *ihid;
+       struct fb_event *event = data;
+
+       ihid = container_of(self, struct i2c_hid, fb_notif);
+
+       if (action == FB_EARLY_EVENT_BLANK) {
+               switch (*((int *)event->data)) {
+               case FB_BLANK_UNBLANK:
+                       break;
+               default:
+                       ihid->is_suspend = 1;
+                       break;
+               }
+       } else if (action == FB_EVENT_BLANK) {
+               switch (*((int *)event->data)) {
+               case FB_BLANK_UNBLANK:
+                       ihid->is_suspend = 0;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       return NOTIFY_OK;
+}
+
 static int __i2c_hid_command(struct i2c_client *client,
                const struct i2c_hid_cmd *command, u8 reportID,
                u8 reportType, u8 *args, int args_len,
@@ -427,6 +462,9 @@ static irqreturn_t i2c_hid_irq(int irq, void *dev_id)
 
        i2c_hid_get_input(ihid);
 
+       if (ihid->is_suspend == 1)
+               rk_send_wakeup_key();
+
        return IRQ_HANDLED;
 }
 
@@ -1014,6 +1052,16 @@ static int i2c_hid_probe(struct i2c_client *client,
        if (ret < 0)
                goto err_pm;
 
+       if (client->dev.of_node) {
+               ret = of_property_read_bool(client->dev.of_node, "hid-support-wakeup");
+               if (ret) {
+                       device_init_wakeup(&client->dev, true);
+                       ihid->is_suspend = 0;
+                       ihid->fb_notif.notifier_call = ihid_fb_notifier_callback;
+                       fb_register_client(&ihid->fb_notif);
+               }
+       }
+
        hid = hid_allocate_device();
        if (IS_ERR(hid)) {
                ret = PTR_ERR(hid);