]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/staging/dream/gpio_input.c
xen: do not release any memory under 1M in domain 0
[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>
5a0e3ad6 22#include <linux/slab.h>
420818f9
AH
23
24enum {
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
35struct gpio_key_state {
36 struct gpio_input_state *ds;
37 uint8_t debounce;
38};
39
40struct 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;
420818f9
AH
47 struct gpio_key_state key_state[0];
48};
49
50static 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);
420818f9
AH
145
146 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
147
148 return HRTIMER_NORESTART;
149}
150
151static 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) {
420818f9
AH
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
198static 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]);
224err_request_irq_failed:
225err_gpio_get_irq_num_failed:
226 ;
227 }
228 return err;
229}
230
231int 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;
420818f9
AH
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--) {
329err_gpio_configure_failed:
330 gpio_free(di->keymap[i].gpio);
331err_gpio_request_failed:
332 ;
333 }
420818f9
AH
334 kfree(ds);
335err_ds_alloc_failed:
336 return ret;
337}