ALSA: hda - Add position_fix quirk for Biostar mobo
[pandora-kernel.git] / drivers / staging / dream / gpio_matrix.c
1 /* drivers/input/misc/gpio_matrix.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/interrupt.h>
21
22 struct gpio_kp {
23         struct input_dev *input_dev;
24         struct gpio_event_matrix_info *keypad_info;
25         struct hrtimer timer;
26         int current_output;
27         unsigned int use_irq:1;
28         unsigned int key_state_changed:1;
29         unsigned int last_key_state_changed:1;
30         unsigned int some_keys_pressed:2;
31         unsigned long keys_pressed[0];
32 };
33
34 static void clear_phantom_key(struct gpio_kp *kp, int out, int in)
35 {
36         struct gpio_event_matrix_info *mi = kp->keypad_info;
37         int key_index = out * mi->ninputs + in;
38         unsigned short keycode = mi->keymap[key_index];;
39
40         if (!test_bit(keycode, kp->input_dev->key)) {
41                 if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS)
42                         pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) "
43                                 "cleared\n", keycode, out, in,
44                                 mi->output_gpios[out], mi->input_gpios[in]);
45                 __clear_bit(key_index, kp->keys_pressed);
46         } else {
47                 if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS)
48                         pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) "
49                                 "not cleared\n", keycode, out, in,
50                                 mi->output_gpios[out], mi->input_gpios[in]);
51         }
52 }
53
54 static int restore_keys_for_input(struct gpio_kp *kp, int out, int in)
55 {
56         int rv = 0;
57         int key_index;
58
59         key_index = out * kp->keypad_info->ninputs + in;
60         while (out < kp->keypad_info->noutputs) {
61                 if (test_bit(key_index, kp->keys_pressed)) {
62                         rv = 1;
63                         clear_phantom_key(kp, out, in);
64                 }
65                 key_index += kp->keypad_info->ninputs;
66                 out++;
67         }
68         return rv;
69 }
70
71 static void remove_phantom_keys(struct gpio_kp *kp)
72 {
73         int out, in, inp;
74         int key_index;
75
76         if (kp->some_keys_pressed < 3)
77                 return;
78
79         for (out = 0; out < kp->keypad_info->noutputs; out++) {
80                 inp = -1;
81                 key_index = out * kp->keypad_info->ninputs;
82                 for (in = 0; in < kp->keypad_info->ninputs; in++, key_index++) {
83                         if (test_bit(key_index, kp->keys_pressed)) {
84                                 if (inp == -1) {
85                                         inp = in;
86                                         continue;
87                                 }
88                                 if (inp >= 0) {
89                                         if (!restore_keys_for_input(kp, out + 1,
90                                                                         inp))
91                                                 break;
92                                         clear_phantom_key(kp, out, inp);
93                                         inp = -2;
94                                 }
95                                 restore_keys_for_input(kp, out, in);
96                         }
97                 }
98         }
99 }
100
101 static void report_key(struct gpio_kp *kp, int key_index, int out, int in)
102 {
103         struct gpio_event_matrix_info *mi = kp->keypad_info;
104         int pressed = test_bit(key_index, kp->keys_pressed);
105         unsigned short keycode = mi->keymap[key_index];
106         if (pressed != test_bit(keycode, kp->input_dev->key)) {
107                 if (keycode == KEY_RESERVED) {
108                         if (mi->flags & GPIOKPF_PRINT_UNMAPPED_KEYS)
109                                 pr_info("gpiomatrix: unmapped key, %d-%d "
110                                         "(%d-%d) changed to %d\n",
111                                         out, in, mi->output_gpios[out],
112                                         mi->input_gpios[in], pressed);
113                 } else {
114                         if (mi->flags & GPIOKPF_PRINT_MAPPED_KEYS)
115                                 pr_info("gpiomatrix: key %x, %d-%d (%d-%d) "
116                                         "changed to %d\n", keycode,
117                                         out, in, mi->output_gpios[out],
118                                         mi->input_gpios[in], pressed);
119                         input_report_key(kp->input_dev, keycode, pressed);
120                 }
121         }
122 }
123
124 static enum hrtimer_restart gpio_keypad_timer_func(struct hrtimer *timer)
125 {
126         int out, in;
127         int key_index;
128         int gpio;
129         struct gpio_kp *kp = container_of(timer, struct gpio_kp, timer);
130         struct gpio_event_matrix_info *mi = kp->keypad_info;
131         unsigned gpio_keypad_flags = mi->flags;
132         unsigned polarity = !!(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH);
133
134         out = kp->current_output;
135         if (out == mi->noutputs) {
136                 out = 0;
137                 kp->last_key_state_changed = kp->key_state_changed;
138                 kp->key_state_changed = 0;
139                 kp->some_keys_pressed = 0;
140         } else {
141                 key_index = out * mi->ninputs;
142                 for (in = 0; in < mi->ninputs; in++, key_index++) {
143                         gpio = mi->input_gpios[in];
144                         if (gpio_get_value(gpio) ^ !polarity) {
145                                 if (kp->some_keys_pressed < 3)
146                                         kp->some_keys_pressed++;
147                                 kp->key_state_changed |= !__test_and_set_bit(
148                                                 key_index, kp->keys_pressed);
149                         } else
150                                 kp->key_state_changed |= __test_and_clear_bit(
151                                                 key_index, kp->keys_pressed);
152                 }
153                 gpio = mi->output_gpios[out];
154                 if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
155                         gpio_set_value(gpio, !polarity);
156                 else
157                         gpio_direction_input(gpio);
158                 out++;
159         }
160         kp->current_output = out;
161         if (out < mi->noutputs) {
162                 gpio = mi->output_gpios[out];
163                 if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
164                         gpio_set_value(gpio, polarity);
165                 else
166                         gpio_direction_output(gpio, polarity);
167                 hrtimer_start(timer, mi->settle_time, HRTIMER_MODE_REL);
168                 return HRTIMER_NORESTART;
169         }
170         if (gpio_keypad_flags & GPIOKPF_DEBOUNCE) {
171                 if (kp->key_state_changed) {
172                         hrtimer_start(&kp->timer, mi->debounce_delay,
173                                       HRTIMER_MODE_REL);
174                         return HRTIMER_NORESTART;
175                 }
176                 kp->key_state_changed = kp->last_key_state_changed;
177         }
178         if (kp->key_state_changed) {
179                 if (gpio_keypad_flags & GPIOKPF_REMOVE_SOME_PHANTOM_KEYS)
180                         remove_phantom_keys(kp);
181                 key_index = 0;
182                 for (out = 0; out < mi->noutputs; out++)
183                         for (in = 0; in < mi->ninputs; in++, key_index++)
184                                 report_key(kp, key_index, out, in);
185         }
186         if (!kp->use_irq || kp->some_keys_pressed) {
187                 hrtimer_start(timer, mi->poll_time, HRTIMER_MODE_REL);
188                 return HRTIMER_NORESTART;
189         }
190
191         /* No keys are pressed, reenable interrupt */
192         for (out = 0; out < mi->noutputs; out++) {
193                 if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
194                         gpio_set_value(mi->output_gpios[out], polarity);
195                 else
196                         gpio_direction_output(mi->output_gpios[out], polarity);
197         }
198         for (in = 0; in < mi->ninputs; in++)
199                 enable_irq(gpio_to_irq(mi->input_gpios[in]));
200         return HRTIMER_NORESTART;
201 }
202
203 static irqreturn_t gpio_keypad_irq_handler(int irq_in, void *dev_id)
204 {
205         int i;
206         struct gpio_kp *kp = dev_id;
207         struct gpio_event_matrix_info *mi = kp->keypad_info;
208         unsigned gpio_keypad_flags = mi->flags;
209
210         if (!kp->use_irq) /* ignore interrupt while registering the handler */
211                 return IRQ_HANDLED;
212
213         for (i = 0; i < mi->ninputs; i++)
214                 disable_irq(gpio_to_irq(mi->input_gpios[i]));
215         for (i = 0; i < mi->noutputs; i++) {
216                 if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
217                         gpio_set_value(mi->output_gpios[i],
218                                 !(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH));
219                 else
220                         gpio_direction_input(mi->output_gpios[i]);
221         }
222         hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
223         return IRQ_HANDLED;
224 }
225
226 static int gpio_keypad_request_irqs(struct gpio_kp *kp)
227 {
228         int i;
229         int err;
230         unsigned int irq;
231         unsigned long request_flags;
232         struct gpio_event_matrix_info *mi = kp->keypad_info;
233
234         switch (mi->flags & (GPIOKPF_ACTIVE_HIGH|GPIOKPF_LEVEL_TRIGGERED_IRQ)) {
235         default:
236                 request_flags = IRQF_TRIGGER_FALLING;
237                 break;
238         case GPIOKPF_ACTIVE_HIGH:
239                 request_flags = IRQF_TRIGGER_RISING;
240                 break;
241         case GPIOKPF_LEVEL_TRIGGERED_IRQ:
242                 request_flags = IRQF_TRIGGER_LOW;
243                 break;
244         case GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_ACTIVE_HIGH:
245                 request_flags = IRQF_TRIGGER_HIGH;
246                 break;
247         }
248
249         for (i = 0; i < mi->ninputs; i++) {
250                 err = irq = gpio_to_irq(mi->input_gpios[i]);
251                 if (err < 0)
252                         goto err_gpio_get_irq_num_failed;
253                 err = request_irq(irq, gpio_keypad_irq_handler, request_flags,
254                                   "gpio_kp", kp);
255                 if (err) {
256                         pr_err("gpiomatrix: request_irq failed for input %d, "
257                                 "irq %d\n", mi->input_gpios[i], irq);
258                         goto err_request_irq_failed;
259                 }
260                 err = set_irq_wake(irq, 1);
261                 if (err) {
262                         pr_err("gpiomatrix: set_irq_wake failed for input %d, "
263                                 "irq %d\n", mi->input_gpios[i], irq);
264                 }
265                 disable_irq(irq);
266         }
267         return 0;
268
269         for (i = mi->noutputs - 1; i >= 0; i--) {
270                 free_irq(gpio_to_irq(mi->input_gpios[i]), kp);
271 err_request_irq_failed:
272 err_gpio_get_irq_num_failed:
273                 ;
274         }
275         return err;
276 }
277
278 int gpio_event_matrix_func(struct input_dev *input_dev,
279         struct gpio_event_info *info, void **data, int func)
280 {
281         int i;
282         int err;
283         int key_count;
284         struct gpio_kp *kp;
285         struct gpio_event_matrix_info *mi;
286
287         mi = container_of(info, struct gpio_event_matrix_info, info);
288         if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) {
289                 /* TODO: disable scanning */
290                 return 0;
291         }
292
293         if (func == GPIO_EVENT_FUNC_INIT) {
294                 if (mi->keymap == NULL ||
295                    mi->input_gpios == NULL ||
296                    mi->output_gpios == NULL) {
297                         err = -ENODEV;
298                         pr_err("gpiomatrix: Incomplete pdata\n");
299                         goto err_invalid_platform_data;
300                 }
301                 key_count = mi->ninputs * mi->noutputs;
302
303                 *data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) *
304                                      BITS_TO_LONGS(key_count), GFP_KERNEL);
305                 if (kp == NULL) {
306                         err = -ENOMEM;
307                         pr_err("gpiomatrix: Failed to allocate private data\n");
308                         goto err_kp_alloc_failed;
309                 }
310                 kp->input_dev = input_dev;
311                 kp->keypad_info = mi;
312                 set_bit(EV_KEY, input_dev->evbit);
313                 for (i = 0; i < key_count; i++) {
314                         if (mi->keymap[i])
315                                 set_bit(mi->keymap[i] & KEY_MAX,
316                                         input_dev->keybit);
317                 }
318
319                 for (i = 0; i < mi->noutputs; i++) {
320                         if (gpio_cansleep(mi->output_gpios[i])) {
321                                 pr_err("gpiomatrix: unsupported output gpio %d,"
322                                         " can sleep\n", mi->output_gpios[i]);
323                                 err = -EINVAL;
324                                 goto err_request_output_gpio_failed;
325                         }
326                         err = gpio_request(mi->output_gpios[i], "gpio_kp_out");
327                         if (err) {
328                                 pr_err("gpiomatrix: gpio_request failed for "
329                                         "output %d\n", mi->output_gpios[i]);
330                                 goto err_request_output_gpio_failed;
331                         }
332                         if (mi->flags & GPIOKPF_DRIVE_INACTIVE)
333                                 err = gpio_direction_output(mi->output_gpios[i],
334                                         !(mi->flags & GPIOKPF_ACTIVE_HIGH));
335                         else
336                                 err = gpio_direction_input(mi->output_gpios[i]);
337                         if (err) {
338                                 pr_err("gpiomatrix: gpio_configure failed for "
339                                         "output %d\n", mi->output_gpios[i]);
340                                 goto err_output_gpio_configure_failed;
341                         }
342                 }
343                 for (i = 0; i < mi->ninputs; i++) {
344                         err = gpio_request(mi->input_gpios[i], "gpio_kp_in");
345                         if (err) {
346                                 pr_err("gpiomatrix: gpio_request failed for "
347                                         "input %d\n", mi->input_gpios[i]);
348                                 goto err_request_input_gpio_failed;
349                         }
350                         err = gpio_direction_input(mi->input_gpios[i]);
351                         if (err) {
352                                 pr_err("gpiomatrix: gpio_direction_input failed"
353                                         " for input %d\n", mi->input_gpios[i]);
354                                 goto err_gpio_direction_input_failed;
355                         }
356                 }
357                 kp->current_output = mi->noutputs;
358                 kp->key_state_changed = 1;
359
360                 hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
361                 kp->timer.function = gpio_keypad_timer_func;
362                 err = gpio_keypad_request_irqs(kp);
363                 kp->use_irq = err == 0;
364
365                 pr_info("GPIO Matrix Keypad Driver: Start keypad matrix for %s "
366                         "in %s mode\n", input_dev->name,
367                         kp->use_irq ? "interrupt" : "polling");
368
369                 hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
370
371                 return 0;
372         }
373
374         err = 0;
375         kp = *data;
376
377         if (kp->use_irq)
378                 for (i = mi->noutputs - 1; i >= 0; i--)
379                         free_irq(gpio_to_irq(mi->input_gpios[i]), kp);
380
381         hrtimer_cancel(&kp->timer);
382         for (i = mi->noutputs - 1; i >= 0; i--) {
383 err_gpio_direction_input_failed:
384                 gpio_free(mi->input_gpios[i]);
385 err_request_input_gpio_failed:
386                 ;
387         }
388         for (i = mi->noutputs - 1; i >= 0; i--) {
389 err_output_gpio_configure_failed:
390                 gpio_free(mi->output_gpios[i]);
391 err_request_output_gpio_failed:
392                 ;
393         }
394         kfree(kp);
395 err_kp_alloc_failed:
396 err_invalid_platform_data:
397         return err;
398 }