input: keyboard: rk_keys: add rk_keys.h
[firefly-linux-kernel-4.4.55.git] / drivers / input / sensors / hall / mh248.c
1  /*
2  * drivers/input/sensors/hall/mh248.c
3  *
4  * Copyright (C) 2012-2016 Rockchip Co.,Ltd.
5  * Author: Bin Yang <yangbin@rock-chips.com>
6  *
7  * This software is licensed under the terms of the GNU General Public
8  * License version 2, as published by the Free Software Foundation, and
9  * may be copied, distributed, and modified under those terms.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17
18 #include <linux/platform_device.h>
19 #include <linux/interrupt.h>
20 #include <linux/i2c.h>
21 #include <linux/slab.h>
22 #include <linux/irq.h>
23 #include <linux/miscdevice.h>
24 #include <linux/gpio.h>
25 #include <linux/uaccess.h>
26 #include <linux/atomic.h>
27 #include <linux/delay.h>
28 #include <linux/input.h>
29 #include <linux/workqueue.h>
30 #include <linux/freezer.h>
31 #include <linux/of_gpio.h>
32 #include <linux/sensor-dev.h>
33 #include <linux/fb.h>
34 #include <linux/notifier.h>
35 #include <linux/rk_keys.h>
36
37 struct mh248_para {
38         struct device *dev;
39         struct notifier_block fb_notif;
40         struct mutex ops_lock;
41         int is_suspend;
42         int gpio_pin;
43         int irq;
44         int active_value;
45 };
46
47 static int hall_fb_notifier_callback(struct notifier_block *self,
48                                      unsigned long action, void *data)
49 {
50         struct mh248_para *mh248;
51         struct fb_event *event = data;
52
53         mh248 = container_of(self, struct mh248_para, fb_notif);
54
55         mutex_lock(&mh248->ops_lock);
56         if (action == FB_EARLY_EVENT_BLANK) {
57                 switch (*((int *)event->data)) {
58                 case FB_BLANK_UNBLANK:
59                         break;
60                 default:
61                         mh248->is_suspend = 1;
62                         break;
63                 }
64         } else if (action == FB_EVENT_BLANK) {
65                 switch (*((int *)event->data)) {
66                 case FB_BLANK_UNBLANK:
67                         mh248->is_suspend = 0;
68                         break;
69                 default:
70                         break;
71                 }
72         }
73         mutex_unlock(&mh248->ops_lock);
74
75         return NOTIFY_OK;
76 }
77
78 static irqreturn_t hall_mh248_interrupt(int irq, void *dev_id)
79 {
80         struct mh248_para *mh248 = (struct mh248_para *)dev_id;
81         int gpio_value = 0;
82
83         gpio_value = gpio_get_value(mh248->gpio_pin);
84
85         if ((gpio_value != mh248->active_value) &&
86             (mh248->is_suspend == 0)) {
87                 rk_send_power_key(1);
88                 rk_send_power_key(0);
89         } else if ((gpio_value == mh248->active_value) &&
90                    (mh248->is_suspend == 1)) {
91                 rk_send_wakeup_key();
92         }
93
94         return IRQ_HANDLED;
95 }
96
97 static int hall_mh248_probe(struct platform_device *pdev)
98 {
99         struct device_node *np = pdev->dev.of_node;
100         struct mh248_para *mh248;
101         enum of_gpio_flags irq_flags;
102         int hallactive = 0;
103         int gpio_value = 0;
104         int ret = 0;
105
106         mh248 = devm_kzalloc(&pdev->dev, sizeof(*mh248), GFP_KERNEL);
107         if (!mh248)
108                 return -ENOMEM;
109
110         mh248->dev = &pdev->dev;
111
112         mh248->gpio_pin = of_get_named_gpio_flags(np, "irq-gpio",
113                                         0, &irq_flags);
114         if (!gpio_is_valid(mh248->gpio_pin)) {
115                 dev_err(mh248->dev, "Can not read property irq-gpio\n");
116                 return mh248->gpio_pin;
117         }
118         mh248->irq = gpio_to_irq(mh248->gpio_pin);
119
120         of_property_read_u32(np, "hall-active", &hallactive);
121         mh248->active_value = hallactive;
122         mh248->is_suspend = 0;
123         mutex_init(&mh248->ops_lock);
124
125         ret = devm_gpio_request_one(mh248->dev, mh248->gpio_pin,
126                                     GPIOF_DIR_IN, "hall_mh248");
127         if (ret < 0) {
128                 dev_err(mh248->dev, "fail to request gpio:%d\n",
129                         mh248->gpio_pin);
130                 return ret;
131         }
132         gpio_value = gpio_get_value(mh248->gpio_pin);
133
134         ret = devm_request_threaded_irq(mh248->dev, mh248->irq,
135                                         NULL, hall_mh248_interrupt,
136                                         irq_flags | IRQF_NO_SUSPEND | IRQF_ONESHOT,
137                                         "hall_mh248", mh248);
138         if (ret < 0) {
139                 dev_err(mh248->dev, "request irq(%d) failed, ret=%d\n",
140                         mh248->irq, ret);
141                 return ret;
142         }
143
144         enable_irq_wake(mh248->irq);
145         mh248->fb_notif.notifier_call = hall_fb_notifier_callback;
146         fb_register_client(&mh248->fb_notif);
147         dev_info(mh248->dev, "hall_mh248_probe success.\n");
148
149         return 0;
150 }
151
152 static const struct of_device_id hall_mh248_match[] = {
153         { .compatible = "hall-mh248" },
154         { /* Sentinel */ }
155 };
156
157 static struct platform_driver hall_mh248_driver = {
158         .probe = hall_mh248_probe,
159         .driver = {
160                 .name = "mh248",
161                 .owner = THIS_MODULE,
162                 .of_match_table = hall_mh248_match,
163         },
164 };
165
166 module_platform_driver(hall_mh248_driver);
167
168 MODULE_ALIAS("platform:mh248");
169 MODULE_AUTHOR("Bin Yang <yangbin@rock-chips.com>");
170 MODULE_LICENSE("GPL v2");
171 MODULE_DESCRIPTION("Hall Sensor MH248 driver");