]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/staging/dream/gpio_input.c
Staging: dream: remove wakelock support
[net-next-2.6.git] / drivers / staging / dream / gpio_input.c
CommitLineData
420818f9
AH
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>
420818f9
AH
22
23enum {
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
34struct gpio_key_state {
35 struct gpio_input_state *ds;
36 uint8_t debounce;
37};
38
39struct 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;
420818f9
AH
46 struct gpio_key_state key_state[0];
47};
48
49static 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);
420818f9
AH
144
145 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
146
147 return HRTIMER_NORESTART;
148}
149
150static 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) {
420818f9
AH
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
197static 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]);
223err_request_irq_failed:
224err_gpio_get_irq_num_failed:
225 ;
226 }
227 return err;
228}
229
230int 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;
420818f9
AH
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--) {
328err_gpio_configure_failed:
329 gpio_free(di->keymap[i].gpio);
330err_gpio_request_failed:
331 ;
332 }
420818f9
AH
333 kfree(ds);
334err_ds_alloc_failed:
335 return ret;
336}