Staging: dream: add support for input on GPIO pins
[linux-2.6/linux-2.6-openrd.git] / drivers / staging / dream / gpio_input.c
blob7e307f267a2a059b64a3fb9c8a379b149016b2f8
1 /* drivers/input/misc/gpio_input.c
3 * Copyright (C) 2007 Google, Inc.
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.
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.
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/wakelock.h>
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 */
31 DEBOUNCE_UNKNOWN =
32 DEBOUNCE_PRESSED | DEBOUNCE_NOTPRESSED,
35 struct gpio_key_state {
36 struct gpio_input_state *ds;
37 uint8_t debounce;
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 wake_lock wake_lock;
48 struct gpio_key_state key_state[0];
51 static enum hrtimer_restart gpio_event_input_timer_func(struct hrtimer *timer)
53 int i;
54 int pressed;
55 struct gpio_input_state *ds =
56 container_of(timer, struct gpio_input_state, timer);
57 unsigned gpio_flags = ds->info->flags;
58 unsigned npolarity;
59 int nkeys = ds->info->keymap_size;
60 const struct gpio_event_direct_entry *key_entry;
61 struct gpio_key_state *key_state;
62 unsigned long irqflags;
63 uint8_t debounce;
65 #if 0
66 key_entry = kp->keys_info->keymap;
67 key_state = kp->key_state;
68 for (i = 0; i < nkeys; i++, key_entry++, key_state++)
69 pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
70 gpio_read_detect_status(key_entry->gpio));
71 #endif
72 key_entry = ds->info->keymap;
73 key_state = ds->key_state;
74 spin_lock_irqsave(&ds->irq_lock, irqflags);
75 for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
76 debounce = key_state->debounce;
77 if (debounce & DEBOUNCE_WAIT_IRQ)
78 continue;
79 if (key_state->debounce & DEBOUNCE_UNSTABLE) {
80 debounce = key_state->debounce = DEBOUNCE_UNKNOWN;
81 enable_irq(gpio_to_irq(key_entry->gpio));
82 pr_info("gpio_keys_scan_keys: key %x-%x, %d "
83 "(%d) continue debounce\n",
84 ds->info->type, key_entry->code,
85 i, key_entry->gpio);
87 npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH);
88 pressed = gpio_get_value(key_entry->gpio) ^ npolarity;
89 if (debounce & DEBOUNCE_POLL) {
90 if (pressed == !(debounce & DEBOUNCE_PRESSED)) {
91 ds->debounce_count++;
92 key_state->debounce = DEBOUNCE_UNKNOWN;
93 if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
94 pr_info("gpio_keys_scan_keys: key %x-"
95 "%x, %d (%d) start debounce\n",
96 ds->info->type, key_entry->code,
97 i, key_entry->gpio);
99 continue;
101 if (pressed && (debounce & DEBOUNCE_NOTPRESSED)) {
102 if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
103 pr_info("gpio_keys_scan_keys: key %x-%x, %d "
104 "(%d) debounce pressed 1\n",
105 ds->info->type, key_entry->code,
106 i, key_entry->gpio);
107 key_state->debounce = DEBOUNCE_PRESSED;
108 continue;
110 if (!pressed && (debounce & DEBOUNCE_PRESSED)) {
111 if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
112 pr_info("gpio_keys_scan_keys: key %x-%x, %d "
113 "(%d) debounce pressed 0\n",
114 ds->info->type, key_entry->code,
115 i, key_entry->gpio);
116 key_state->debounce = DEBOUNCE_NOTPRESSED;
117 continue;
119 /* key is stable */
120 ds->debounce_count--;
121 if (ds->use_irq)
122 key_state->debounce |= DEBOUNCE_WAIT_IRQ;
123 else
124 key_state->debounce |= DEBOUNCE_POLL;
125 if (gpio_flags & GPIOEDF_PRINT_KEYS)
126 pr_info("gpio_keys_scan_keys: key %x-%x, %d (%d) "
127 "changed to %d\n", ds->info->type,
128 key_entry->code, i, key_entry->gpio, pressed);
129 input_event(ds->input_dev, ds->info->type,
130 key_entry->code, pressed);
133 #if 0
134 key_entry = kp->keys_info->keymap;
135 key_state = kp->key_state;
136 for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
137 pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
138 gpio_read_detect_status(key_entry->gpio));
140 #endif
142 if (ds->debounce_count)
143 hrtimer_start(timer, ds->info->debounce_time, HRTIMER_MODE_REL);
144 else if (!ds->use_irq)
145 hrtimer_start(timer, ds->info->poll_time, HRTIMER_MODE_REL);
146 else
147 wake_unlock(&ds->wake_lock);
149 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
151 return HRTIMER_NORESTART;
154 static irqreturn_t gpio_event_input_irq_handler(int irq, void *dev_id)
156 struct gpio_key_state *ks = dev_id;
157 struct gpio_input_state *ds = ks->ds;
158 int keymap_index = ks - ds->key_state;
159 const struct gpio_event_direct_entry *key_entry;
160 unsigned long irqflags;
161 int pressed;
163 if (!ds->use_irq)
164 return IRQ_HANDLED;
166 key_entry = &ds->info->keymap[keymap_index];
168 if (ds->info->debounce_time.tv64) {
169 spin_lock_irqsave(&ds->irq_lock, irqflags);
170 if (ks->debounce & DEBOUNCE_WAIT_IRQ) {
171 ks->debounce = DEBOUNCE_UNKNOWN;
172 if (ds->debounce_count++ == 0) {
173 wake_lock(&ds->wake_lock);
174 hrtimer_start(
175 &ds->timer, ds->info->debounce_time,
176 HRTIMER_MODE_REL);
178 if (ds->info->flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
179 pr_info("gpio_event_input_irq_handler: "
180 "key %x-%x, %d (%d) start debounce\n",
181 ds->info->type, key_entry->code,
182 keymap_index, key_entry->gpio);
183 } else {
184 disable_irq(irq);
185 ks->debounce = DEBOUNCE_UNSTABLE;
187 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
188 } else {
189 pressed = gpio_get_value(key_entry->gpio) ^
190 !(ds->info->flags & GPIOEDF_ACTIVE_HIGH);
191 if (ds->info->flags & GPIOEDF_PRINT_KEYS)
192 pr_info("gpio_event_input_irq_handler: key %x-%x, %d "
193 "(%d) changed to %d\n",
194 ds->info->type, key_entry->code, keymap_index,
195 key_entry->gpio, pressed);
196 input_event(ds->input_dev, ds->info->type,
197 key_entry->code, pressed);
199 return IRQ_HANDLED;
202 static int gpio_event_input_request_irqs(struct gpio_input_state *ds)
204 int i;
205 int err;
206 unsigned int irq;
207 unsigned long req_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
209 for (i = 0; i < ds->info->keymap_size; i++) {
210 err = irq = gpio_to_irq(ds->info->keymap[i].gpio);
211 if (err < 0)
212 goto err_gpio_get_irq_num_failed;
213 err = request_irq(irq, gpio_event_input_irq_handler,
214 req_flags, "gpio_keys", &ds->key_state[i]);
215 if (err) {
216 pr_err("gpio_event_input_request_irqs: request_irq "
217 "failed for input %d, irq %d\n",
218 ds->info->keymap[i].gpio, irq);
219 goto err_request_irq_failed;
221 enable_irq_wake(irq);
223 return 0;
225 for (i = ds->info->keymap_size - 1; i >= 0; i--) {
226 free_irq(gpio_to_irq(ds->info->keymap[i].gpio),
227 &ds->key_state[i]);
228 err_request_irq_failed:
229 err_gpio_get_irq_num_failed:
232 return err;
235 int gpio_event_input_func(struct input_dev *input_dev,
236 struct gpio_event_info *info, void **data, int func)
238 int ret;
239 int i;
240 unsigned long irqflags;
241 struct gpio_event_input_info *di;
242 struct gpio_input_state *ds = *data;
244 di = container_of(info, struct gpio_event_input_info, info);
246 if (func == GPIO_EVENT_FUNC_SUSPEND) {
247 spin_lock_irqsave(&ds->irq_lock, irqflags);
248 if (ds->use_irq)
249 for (i = 0; i < di->keymap_size; i++)
250 disable_irq(gpio_to_irq(di->keymap[i].gpio));
251 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
252 hrtimer_cancel(&ds->timer);
253 return 0;
255 if (func == GPIO_EVENT_FUNC_RESUME) {
256 spin_lock_irqsave(&ds->irq_lock, irqflags);
257 if (ds->use_irq)
258 for (i = 0; i < di->keymap_size; i++)
259 enable_irq(gpio_to_irq(di->keymap[i].gpio));
260 hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
261 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
262 return 0;
265 if (func == GPIO_EVENT_FUNC_INIT) {
266 if (ktime_to_ns(di->poll_time) <= 0)
267 di->poll_time = ktime_set(0, 20 * NSEC_PER_MSEC);
269 *data = ds = kzalloc(sizeof(*ds) + sizeof(ds->key_state[0]) *
270 di->keymap_size, GFP_KERNEL);
271 if (ds == NULL) {
272 ret = -ENOMEM;
273 pr_err("gpio_event_input_func: "
274 "Failed to allocate private data\n");
275 goto err_ds_alloc_failed;
277 ds->debounce_count = di->keymap_size;
278 ds->input_dev = input_dev;
279 ds->info = di;
280 wake_lock_init(&ds->wake_lock, WAKE_LOCK_SUSPEND, "gpio_input");
281 spin_lock_init(&ds->irq_lock);
283 for (i = 0; i < di->keymap_size; i++) {
284 input_set_capability(input_dev, di->type,
285 di->keymap[i].code);
286 ds->key_state[i].ds = ds;
287 ds->key_state[i].debounce = DEBOUNCE_UNKNOWN;
290 for (i = 0; i < di->keymap_size; i++) {
291 ret = gpio_request(di->keymap[i].gpio, "gpio_kp_in");
292 if (ret) {
293 pr_err("gpio_event_input_func: gpio_request "
294 "failed for %d\n", di->keymap[i].gpio);
295 goto err_gpio_request_failed;
297 ret = gpio_direction_input(di->keymap[i].gpio);
298 if (ret) {
299 pr_err("gpio_event_input_func: "
300 "gpio_direction_input failed for %d\n",
301 di->keymap[i].gpio);
302 goto err_gpio_configure_failed;
306 ret = gpio_event_input_request_irqs(ds);
308 spin_lock_irqsave(&ds->irq_lock, irqflags);
309 ds->use_irq = ret == 0;
311 pr_info("GPIO Input Driver: Start gpio inputs for %s in %s "
312 "mode\n",
313 input_dev->name, ret == 0 ? "interrupt" : "polling");
315 hrtimer_init(&ds->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
316 ds->timer.function = gpio_event_input_timer_func;
317 hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
318 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
319 return 0;
322 ret = 0;
323 spin_lock_irqsave(&ds->irq_lock, irqflags);
324 hrtimer_cancel(&ds->timer);
325 if (ds->use_irq) {
326 for (i = di->keymap_size - 1; i >= 0; i--) {
327 free_irq(gpio_to_irq(di->keymap[i].gpio),
328 &ds->key_state[i]);
331 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
333 for (i = di->keymap_size - 1; i >= 0; i--) {
334 err_gpio_configure_failed:
335 gpio_free(di->keymap[i].gpio);
336 err_gpio_request_failed:
339 wake_lock_destroy(&ds->wake_lock);
340 kfree(ds);
341 err_ds_alloc_failed:
342 return ret;