linux/drivers/staging/dream/gpio_input.c
<<
>>
Prefs
   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#include <linux/wakelock.h>
  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;
  47        struct wake_lock wake_lock;
  48        struct gpio_key_state key_state[0];
  49};
  50
  51static enum hrtimer_restart gpio_event_input_timer_func(struct hrtimer *timer)
  52{
  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;
  64
  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);
  86                }
  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);
  98                        }
  99                        continue;
 100                }
 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;
 109                }
 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;
 118                }
 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);
 131        }
 132
 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));
 139        }
 140#endif
 141
 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);
 148
 149        spin_unlock_irqrestore(&ds->irq_lock, irqflags);
 150
 151        return HRTIMER_NORESTART;
 152}
 153
 154static irqreturn_t gpio_event_input_irq_handler(int irq, void *dev_id)
 155{
 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;
 162
 163        if (!ds->use_irq)
 164                return IRQ_HANDLED;
 165
 166        key_entry = &ds->info->keymap[keymap_index];
 167
 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);
 177                        }
 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;
 186                }
 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);
 198        }
 199        return IRQ_HANDLED;
 200}
 201
 202static int gpio_event_input_request_irqs(struct gpio_input_state *ds)
 203{
 204        int i;
 205        int err;
 206        unsigned int irq;
 207        unsigned long req_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
 208
 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;
 220                }
 221                enable_irq_wake(irq);
 222        }
 223        return 0;
 224
 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]);
 228err_request_irq_failed:
 229err_gpio_get_irq_num_failed:
 230                ;
 231        }
 232        return err;
 233}
 234
 235int gpio_event_input_func(struct input_dev *input_dev,
 236                        struct gpio_event_info *info, void **data, int func)
 237{
 238        int ret;
 239        int i;
 240        unsigned long irqflags;
 241        struct gpio_event_input_info *di;
 242        struct gpio_input_state *ds = *data;
 243
 244        di = container_of(info, struct gpio_event_input_info, info);
 245
 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;
 254        }
 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;
 263        }
 264
 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);
 268
 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;
 276                }
 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);
 282
 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;
 288                }
 289
 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;
 296                        }
 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;
 303                        }
 304                }
 305
 306                ret = gpio_event_input_request_irqs(ds);
 307
 308                spin_lock_irqsave(&ds->irq_lock, irqflags);
 309                ds->use_irq = ret == 0;
 310
 311                pr_info("GPIO Input Driver: Start gpio inputs for %s in %s "
 312                        "mode\n",
 313                        input_dev->name, ret == 0 ? "interrupt" : "polling");
 314
 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;
 320        }
 321
 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]);
 329                }
 330        }
 331        spin_unlock_irqrestore(&ds->irq_lock, irqflags);
 332
 333        for (i = di->keymap_size - 1; i >= 0; i--) {
 334err_gpio_configure_failed:
 335                gpio_free(di->keymap[i].gpio);
 336err_gpio_request_failed:
 337                ;
 338        }
 339        wake_lock_destroy(&ds->wake_lock);
 340        kfree(ds);
 341err_ds_alloc_failed:
 342        return ret;
 343}
 344