upload tizen1.0 source
[kernel/linux-2.6.36.git] / drivers / staging / dream / gpio_input.c
1 /* drivers/input/misc/gpio_input.c
2  *
3  * Copyright (C) 2007 Google, Inc.
4  *
5  * This software is licensed under the terms of the GNU General Public
6  * License version 2, as published by the Free Software Foundation, and
7  * may be copied, distributed, and modified under those terms.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  */
15
16 #include <linux/kernel.h>
17 #include <linux/gpio.h>
18 #include <linux/gpio_event.h>
19 #include <linux/hrtimer.h>
20 #include <linux/input.h>
21 #include <linux/interrupt.h>
22 #include <linux/slab.h>
23
24 enum {
25         DEBOUNCE_UNSTABLE     = BIT(0), /* Got irq, while debouncing */
26         DEBOUNCE_PRESSED      = BIT(1),
27         DEBOUNCE_NOTPRESSED   = BIT(2),
28         DEBOUNCE_WAIT_IRQ     = BIT(3), /* Stable irq state */
29         DEBOUNCE_POLL         = BIT(4), /* Stable polling state */
30
31         DEBOUNCE_UNKNOWN =
32                 DEBOUNCE_PRESSED | DEBOUNCE_NOTPRESSED,
33 };
34
35 struct gpio_key_state {
36         struct gpio_input_state *ds;
37         uint8_t debounce;
38 };
39
40 struct gpio_input_state {
41         struct input_dev *input_dev;
42         const struct gpio_event_input_info *info;
43         struct hrtimer timer;
44         int use_irq;
45         int debounce_count;
46         spinlock_t irq_lock;
47         struct gpio_key_state key_state[0];
48 };
49
50 static enum hrtimer_restart gpio_event_input_timer_func(struct hrtimer *timer)
51 {
52         int i;
53         int pressed;
54         struct gpio_input_state *ds =
55                 container_of(timer, struct gpio_input_state, timer);
56         unsigned gpio_flags = ds->info->flags;
57         unsigned npolarity;
58         int nkeys = ds->info->keymap_size;
59         const struct gpio_event_direct_entry *key_entry;
60         struct gpio_key_state *key_state;
61         unsigned long irqflags;
62         uint8_t debounce;
63
64 #if 0
65         key_entry = kp->keys_info->keymap;
66         key_state = kp->key_state;
67         for (i = 0; i < nkeys; i++, key_entry++, key_state++)
68                 pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
69                         gpio_read_detect_status(key_entry->gpio));
70 #endif
71         key_entry = ds->info->keymap;
72         key_state = ds->key_state;
73         spin_lock_irqsave(&ds->irq_lock, irqflags);
74         for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
75                 debounce = key_state->debounce;
76                 if (debounce & DEBOUNCE_WAIT_IRQ)
77                         continue;
78                 if (key_state->debounce & DEBOUNCE_UNSTABLE) {
79                         debounce = key_state->debounce = DEBOUNCE_UNKNOWN;
80                         enable_irq(gpio_to_irq(key_entry->gpio));
81                         pr_info("gpio_keys_scan_keys: key %x-%x, %d "
82                                 "(%d) continue debounce\n",
83                                 ds->info->type, key_entry->code,
84                                 i, key_entry->gpio);
85                 }
86                 npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH);
87                 pressed = gpio_get_value(key_entry->gpio) ^ npolarity;
88                 if (debounce & DEBOUNCE_POLL) {
89                         if (pressed == !(debounce & DEBOUNCE_PRESSED)) {
90                                 ds->debounce_count++;
91                                 key_state->debounce = DEBOUNCE_UNKNOWN;
92                                 if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
93                                         pr_info("gpio_keys_scan_keys: key %x-"
94                                                 "%x, %d (%d) start debounce\n",
95                                                 ds->info->type, key_entry->code,
96                                                 i, key_entry->gpio);
97                         }
98                         continue;
99                 }
100                 if (pressed && (debounce & DEBOUNCE_NOTPRESSED)) {
101                         if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
102                                 pr_info("gpio_keys_scan_keys: key %x-%x, %d "
103                                         "(%d) debounce pressed 1\n",
104                                         ds->info->type, key_entry->code,
105                                         i, key_entry->gpio);
106                         key_state->debounce = DEBOUNCE_PRESSED;
107                         continue;
108                 }
109                 if (!pressed && (debounce & DEBOUNCE_PRESSED)) {
110                         if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
111                                 pr_info("gpio_keys_scan_keys: key %x-%x, %d "
112                                         "(%d) debounce pressed 0\n",
113                                         ds->info->type, key_entry->code,
114                                         i, key_entry->gpio);
115                         key_state->debounce = DEBOUNCE_NOTPRESSED;
116                         continue;
117                 }
118                 /* key is stable */
119                 ds->debounce_count--;
120                 if (ds->use_irq)
121                         key_state->debounce |= DEBOUNCE_WAIT_IRQ;
122                 else
123                         key_state->debounce |= DEBOUNCE_POLL;
124                 if (gpio_flags & GPIOEDF_PRINT_KEYS)
125                         pr_info("gpio_keys_scan_keys: key %x-%x, %d (%d) "
126                                 "changed to %d\n", ds->info->type,
127                                 key_entry->code, i, key_entry->gpio, pressed);
128                 input_event(ds->input_dev, ds->info->type,
129                             key_entry->code, pressed);
130         }
131
132 #if 0
133         key_entry = kp->keys_info->keymap;
134         key_state = kp->key_state;
135         for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
136                 pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
137                         gpio_read_detect_status(key_entry->gpio));
138         }
139 #endif
140
141         if (ds->debounce_count)
142                 hrtimer_start(timer, ds->info->debounce_time, HRTIMER_MODE_REL);
143         else if (!ds->use_irq)
144                 hrtimer_start(timer, ds->info->poll_time, HRTIMER_MODE_REL);
145
146         spin_unlock_irqrestore(&ds->irq_lock, irqflags);
147
148         return HRTIMER_NORESTART;
149 }
150
151 static irqreturn_t gpio_event_input_irq_handler(int irq, void *dev_id)
152 {
153         struct gpio_key_state *ks = dev_id;
154         struct gpio_input_state *ds = ks->ds;
155         int keymap_index = ks - ds->key_state;
156         const struct gpio_event_direct_entry *key_entry;
157         unsigned long irqflags;
158         int pressed;
159
160         if (!ds->use_irq)
161                 return IRQ_HANDLED;
162
163         key_entry = &ds->info->keymap[keymap_index];
164
165         if (ds->info->debounce_time.tv64) {
166                 spin_lock_irqsave(&ds->irq_lock, irqflags);
167                 if (ks->debounce & DEBOUNCE_WAIT_IRQ) {
168                         ks->debounce = DEBOUNCE_UNKNOWN;
169                         if (ds->debounce_count++ == 0) {
170                                 hrtimer_start(
171                                         &ds->timer, ds->info->debounce_time,
172                                         HRTIMER_MODE_REL);
173                         }
174                         if (ds->info->flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
175                                 pr_info("gpio_event_input_irq_handler: "
176                                         "key %x-%x, %d (%d) start debounce\n",
177                                         ds->info->type, key_entry->code,
178                                         keymap_index, key_entry->gpio);
179                 } else {
180                         disable_irq(irq);
181                         ks->debounce = DEBOUNCE_UNSTABLE;
182                 }
183                 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
184         } else {
185                 pressed = gpio_get_value(key_entry->gpio) ^
186                         !(ds->info->flags & GPIOEDF_ACTIVE_HIGH);
187                 if (ds->info->flags & GPIOEDF_PRINT_KEYS)
188                         pr_info("gpio_event_input_irq_handler: key %x-%x, %d "
189                                 "(%d) changed to %d\n",
190                                 ds->info->type, key_entry->code, keymap_index,
191                                 key_entry->gpio, pressed);
192                 input_event(ds->input_dev, ds->info->type,
193                             key_entry->code, pressed);
194         }
195         return IRQ_HANDLED;
196 }
197
198 static int gpio_event_input_request_irqs(struct gpio_input_state *ds)
199 {
200         int i;
201         int err;
202         unsigned int irq;
203         unsigned long req_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
204
205         for (i = 0; i < ds->info->keymap_size; i++) {
206                 err = irq = gpio_to_irq(ds->info->keymap[i].gpio);
207                 if (err < 0)
208                         goto err_gpio_get_irq_num_failed;
209                 err = request_irq(irq, gpio_event_input_irq_handler,
210                                   req_flags, "gpio_keys", &ds->key_state[i]);
211                 if (err) {
212                         pr_err("gpio_event_input_request_irqs: request_irq "
213                                 "failed for input %d, irq %d\n",
214                                 ds->info->keymap[i].gpio, irq);
215                         goto err_request_irq_failed;
216                 }
217                 enable_irq_wake(irq);
218         }
219         return 0;
220
221         for (i = ds->info->keymap_size - 1; i >= 0; i--) {
222                 free_irq(gpio_to_irq(ds->info->keymap[i].gpio),
223                          &ds->key_state[i]);
224 err_request_irq_failed:
225 err_gpio_get_irq_num_failed:
226                 ;
227         }
228         return err;
229 }
230
231 int gpio_event_input_func(struct input_dev *input_dev,
232                         struct gpio_event_info *info, void **data, int func)
233 {
234         int ret;
235         int i;
236         unsigned long irqflags;
237         struct gpio_event_input_info *di;
238         struct gpio_input_state *ds = *data;
239
240         di = container_of(info, struct gpio_event_input_info, info);
241
242         if (func == GPIO_EVENT_FUNC_SUSPEND) {
243                 spin_lock_irqsave(&ds->irq_lock, irqflags);
244                 if (ds->use_irq)
245                         for (i = 0; i < di->keymap_size; i++)
246                                 disable_irq(gpio_to_irq(di->keymap[i].gpio));
247                 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
248                 hrtimer_cancel(&ds->timer);
249                 return 0;
250         }
251         if (func == GPIO_EVENT_FUNC_RESUME) {
252                 spin_lock_irqsave(&ds->irq_lock, irqflags);
253                 if (ds->use_irq)
254                         for (i = 0; i < di->keymap_size; i++)
255                                 enable_irq(gpio_to_irq(di->keymap[i].gpio));
256                 hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
257                 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
258                 return 0;
259         }
260
261         if (func == GPIO_EVENT_FUNC_INIT) {
262                 if (ktime_to_ns(di->poll_time) <= 0)
263                         di->poll_time = ktime_set(0, 20 * NSEC_PER_MSEC);
264
265                 *data = ds = kzalloc(sizeof(*ds) + sizeof(ds->key_state[0]) *
266                                         di->keymap_size, GFP_KERNEL);
267                 if (ds == NULL) {
268                         ret = -ENOMEM;
269                         pr_err("gpio_event_input_func: "
270                                 "Failed to allocate private data\n");
271                         goto err_ds_alloc_failed;
272                 }
273                 ds->debounce_count = di->keymap_size;
274                 ds->input_dev = input_dev;
275                 ds->info = di;
276                 spin_lock_init(&ds->irq_lock);
277
278                 for (i = 0; i < di->keymap_size; i++) {
279                         input_set_capability(input_dev, di->type,
280                                              di->keymap[i].code);
281                         ds->key_state[i].ds = ds;
282                         ds->key_state[i].debounce = DEBOUNCE_UNKNOWN;
283                 }
284
285                 for (i = 0; i < di->keymap_size; i++) {
286                         ret = gpio_request(di->keymap[i].gpio, "gpio_kp_in");
287                         if (ret) {
288                                 pr_err("gpio_event_input_func: gpio_request "
289                                         "failed for %d\n", di->keymap[i].gpio);
290                                 goto err_gpio_request_failed;
291                         }
292                         ret = gpio_direction_input(di->keymap[i].gpio);
293                         if (ret) {
294                                 pr_err("gpio_event_input_func: "
295                                         "gpio_direction_input failed for %d\n",
296                                         di->keymap[i].gpio);
297                                 goto err_gpio_configure_failed;
298                         }
299                 }
300
301                 ret = gpio_event_input_request_irqs(ds);
302
303                 spin_lock_irqsave(&ds->irq_lock, irqflags);
304                 ds->use_irq = ret == 0;
305
306                 pr_info("GPIO Input Driver: Start gpio inputs for %s in %s "
307                         "mode\n",
308                         input_dev->name, ret == 0 ? "interrupt" : "polling");
309
310                 hrtimer_init(&ds->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
311                 ds->timer.function = gpio_event_input_timer_func;
312                 hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
313                 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
314                 return 0;
315         }
316
317         ret = 0;
318         spin_lock_irqsave(&ds->irq_lock, irqflags);
319         hrtimer_cancel(&ds->timer);
320         if (ds->use_irq) {
321                 for (i = di->keymap_size - 1; i >= 0; i--) {
322                         free_irq(gpio_to_irq(di->keymap[i].gpio),
323                                  &ds->key_state[i]);
324                 }
325         }
326         spin_unlock_irqrestore(&ds->irq_lock, irqflags);
327
328         for (i = di->keymap_size - 1; i >= 0; i--) {
329 err_gpio_configure_failed:
330                 gpio_free(di->keymap[i].gpio);
331 err_gpio_request_failed:
332                 ;
333         }
334         kfree(ds);
335 err_ds_alloc_failed:
336         return ret;
337 }