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