linux/drivers/input/keyboard/matrix_keypad.c
<<
>>
Prefs
   1/*
   2 *  GPIO driven matrix keyboard driver
   3 *
   4 *  Copyright (c) 2008 Marek Vasut <marek.vasut@gmail.com>
   5 *
   6 *  Based on corgikbd.c
   7 *
   8 *  This program is free software; you can redistribute it and/or modify
   9 *  it under the terms of the GNU General Public License version 2 as
  10 *  published by the Free Software Foundation.
  11 *
  12 */
  13
  14#include <linux/types.h>
  15#include <linux/delay.h>
  16#include <linux/platform_device.h>
  17#include <linux/init.h>
  18#include <linux/input.h>
  19#include <linux/irq.h>
  20#include <linux/interrupt.h>
  21#include <linux/jiffies.h>
  22#include <linux/module.h>
  23#include <linux/gpio.h>
  24#include <linux/input/matrix_keypad.h>
  25
  26struct matrix_keypad {
  27        const struct matrix_keypad_platform_data *pdata;
  28        struct input_dev *input_dev;
  29        unsigned short *keycodes;
  30        unsigned int row_shift;
  31
  32        uint32_t last_key_state[MATRIX_MAX_COLS];
  33        struct delayed_work work;
  34        bool scan_pending;
  35        bool stopped;
  36        spinlock_t lock;
  37};
  38
  39/*
  40 * NOTE: normally the GPIO has to be put into HiZ when de-activated to cause
  41 * minmal side effect when scanning other columns, here it is configured to
  42 * be input, and it should work on most platforms.
  43 */
  44static void __activate_col(const struct matrix_keypad_platform_data *pdata,
  45                           int col, bool on)
  46{
  47        bool level_on = !pdata->active_low;
  48
  49        if (on) {
  50                gpio_direction_output(pdata->col_gpios[col], level_on);
  51        } else {
  52                gpio_set_value_cansleep(pdata->col_gpios[col], !level_on);
  53                gpio_direction_input(pdata->col_gpios[col]);
  54        }
  55}
  56
  57static void activate_col(const struct matrix_keypad_platform_data *pdata,
  58                         int col, bool on)
  59{
  60        __activate_col(pdata, col, on);
  61
  62        if (on && pdata->col_scan_delay_us)
  63                udelay(pdata->col_scan_delay_us);
  64}
  65
  66static void activate_all_cols(const struct matrix_keypad_platform_data *pdata,
  67                              bool on)
  68{
  69        int col;
  70
  71        for (col = 0; col < pdata->num_col_gpios; col++)
  72                __activate_col(pdata, col, on);
  73}
  74
  75static bool row_asserted(const struct matrix_keypad_platform_data *pdata,
  76                         int row)
  77{
  78        return gpio_get_value_cansleep(pdata->row_gpios[row]) ?
  79                        !pdata->active_low : pdata->active_low;
  80}
  81
  82static void enable_row_irqs(struct matrix_keypad *keypad)
  83{
  84        const struct matrix_keypad_platform_data *pdata = keypad->pdata;
  85        int i;
  86
  87        for (i = 0; i < pdata->num_row_gpios; i++)
  88                enable_irq(gpio_to_irq(pdata->row_gpios[i]));
  89}
  90
  91static void disable_row_irqs(struct matrix_keypad *keypad)
  92{
  93        const struct matrix_keypad_platform_data *pdata = keypad->pdata;
  94        int i;
  95
  96        for (i = 0; i < pdata->num_row_gpios; i++)
  97                disable_irq_nosync(gpio_to_irq(pdata->row_gpios[i]));
  98}
  99
 100/*
 101 * This gets the keys from keyboard and reports it to input subsystem
 102 */
 103static void matrix_keypad_scan(struct work_struct *work)
 104{
 105        struct matrix_keypad *keypad =
 106                container_of(work, struct matrix_keypad, work.work);
 107        struct input_dev *input_dev = keypad->input_dev;
 108        const struct matrix_keypad_platform_data *pdata = keypad->pdata;
 109        uint32_t new_state[MATRIX_MAX_COLS];
 110        int row, col, code;
 111
 112        /* de-activate all columns for scanning */
 113        activate_all_cols(pdata, false);
 114
 115        memset(new_state, 0, sizeof(new_state));
 116
 117        /* assert each column and read the row status out */
 118        for (col = 0; col < pdata->num_col_gpios; col++) {
 119
 120                activate_col(pdata, col, true);
 121
 122                for (row = 0; row < pdata->num_row_gpios; row++)
 123                        new_state[col] |=
 124                                row_asserted(pdata, row) ? (1 << row) : 0;
 125
 126                activate_col(pdata, col, false);
 127        }
 128
 129        for (col = 0; col < pdata->num_col_gpios; col++) {
 130                uint32_t bits_changed;
 131
 132                bits_changed = keypad->last_key_state[col] ^ new_state[col];
 133                if (bits_changed == 0)
 134                        continue;
 135
 136                for (row = 0; row < pdata->num_row_gpios; row++) {
 137                        if ((bits_changed & (1 << row)) == 0)
 138                                continue;
 139
 140                        code = MATRIX_SCAN_CODE(row, col, keypad->row_shift);
 141                        input_event(input_dev, EV_MSC, MSC_SCAN, code);
 142                        input_report_key(input_dev,
 143                                         keypad->keycodes[code],
 144                                         new_state[col] & (1 << row));
 145                }
 146        }
 147        input_sync(input_dev);
 148
 149        memcpy(keypad->last_key_state, new_state, sizeof(new_state));
 150
 151        activate_all_cols(pdata, true);
 152
 153        /* Enable IRQs again */
 154        spin_lock_irq(&keypad->lock);
 155        keypad->scan_pending = false;
 156        enable_row_irqs(keypad);
 157        spin_unlock_irq(&keypad->lock);
 158}
 159
 160static irqreturn_t matrix_keypad_interrupt(int irq, void *id)
 161{
 162        struct matrix_keypad *keypad = id;
 163        unsigned long flags;
 164
 165        spin_lock_irqsave(&keypad->lock, flags);
 166
 167        /*
 168         * See if another IRQ beaten us to it and scheduled the
 169         * scan already. In that case we should not try to
 170         * disable IRQs again.
 171         */
 172        if (unlikely(keypad->scan_pending || keypad->stopped))
 173                goto out;
 174
 175        disable_row_irqs(keypad);
 176        keypad->scan_pending = true;
 177        schedule_delayed_work(&keypad->work,
 178                msecs_to_jiffies(keypad->pdata->debounce_ms));
 179
 180out:
 181        spin_unlock_irqrestore(&keypad->lock, flags);
 182        return IRQ_HANDLED;
 183}
 184
 185static int matrix_keypad_start(struct input_dev *dev)
 186{
 187        struct matrix_keypad *keypad = input_get_drvdata(dev);
 188
 189        keypad->stopped = false;
 190        mb();
 191
 192        /*
 193         * Schedule an immediate key scan to capture current key state;
 194         * columns will be activated and IRQs be enabled after the scan.
 195         */
 196        schedule_delayed_work(&keypad->work, 0);
 197
 198        return 0;
 199}
 200
 201static void matrix_keypad_stop(struct input_dev *dev)
 202{
 203        struct matrix_keypad *keypad = input_get_drvdata(dev);
 204
 205        keypad->stopped = true;
 206        mb();
 207        flush_work(&keypad->work.work);
 208        /*
 209         * matrix_keypad_scan() will leave IRQs enabled;
 210         * we should disable them now.
 211         */
 212        disable_row_irqs(keypad);
 213}
 214
 215#ifdef CONFIG_PM
 216static int matrix_keypad_suspend(struct platform_device *pdev, pm_message_t state)
 217{
 218        struct matrix_keypad *keypad = platform_get_drvdata(pdev);
 219        const struct matrix_keypad_platform_data *pdata = keypad->pdata;
 220        int i;
 221
 222        matrix_keypad_stop(keypad->input_dev);
 223
 224        if (device_may_wakeup(&pdev->dev))
 225                for (i = 0; i < pdata->num_row_gpios; i++)
 226                        enable_irq_wake(gpio_to_irq(pdata->row_gpios[i]));
 227
 228        return 0;
 229}
 230
 231static int matrix_keypad_resume(struct platform_device *pdev)
 232{
 233        struct matrix_keypad *keypad = platform_get_drvdata(pdev);
 234        const struct matrix_keypad_platform_data *pdata = keypad->pdata;
 235        int i;
 236
 237        if (device_may_wakeup(&pdev->dev))
 238                for (i = 0; i < pdata->num_row_gpios; i++)
 239                        disable_irq_wake(gpio_to_irq(pdata->row_gpios[i]));
 240
 241        matrix_keypad_start(keypad->input_dev);
 242
 243        return 0;
 244}
 245#else
 246#define matrix_keypad_suspend   NULL
 247#define matrix_keypad_resume    NULL
 248#endif
 249
 250static int __devinit init_matrix_gpio(struct platform_device *pdev,
 251                                        struct matrix_keypad *keypad)
 252{
 253        const struct matrix_keypad_platform_data *pdata = keypad->pdata;
 254        int i, err = -EINVAL;
 255
 256        /* initialized strobe lines as outputs, activated */
 257        for (i = 0; i < pdata->num_col_gpios; i++) {
 258                err = gpio_request(pdata->col_gpios[i], "matrix_kbd_col");
 259                if (err) {
 260                        dev_err(&pdev->dev,
 261                                "failed to request GPIO%d for COL%d\n",
 262                                pdata->col_gpios[i], i);
 263                        goto err_free_cols;
 264                }
 265
 266                gpio_direction_output(pdata->col_gpios[i], !pdata->active_low);
 267        }
 268
 269        for (i = 0; i < pdata->num_row_gpios; i++) {
 270                err = gpio_request(pdata->row_gpios[i], "matrix_kbd_row");
 271                if (err) {
 272                        dev_err(&pdev->dev,
 273                                "failed to request GPIO%d for ROW%d\n",
 274                                pdata->row_gpios[i], i);
 275                        goto err_free_rows;
 276                }
 277
 278                gpio_direction_input(pdata->row_gpios[i]);
 279        }
 280
 281        for (i = 0; i < pdata->num_row_gpios; i++) {
 282                err = request_irq(gpio_to_irq(pdata->row_gpios[i]),
 283                                matrix_keypad_interrupt,
 284                                IRQF_DISABLED |
 285                                IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 286                                "matrix-keypad", keypad);
 287                if (err) {
 288                        dev_err(&pdev->dev,
 289                                "Unable to acquire interrupt for GPIO line %i\n",
 290                                pdata->row_gpios[i]);
 291                        goto err_free_irqs;
 292                }
 293        }
 294
 295        /* initialized as disabled - enabled by input->open */
 296        disable_row_irqs(keypad);
 297        return 0;
 298
 299err_free_irqs:
 300        while (--i >= 0)
 301                free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad);
 302        i = pdata->num_row_gpios;
 303err_free_rows:
 304        while (--i >= 0)
 305                gpio_free(pdata->row_gpios[i]);
 306        i = pdata->num_col_gpios;
 307err_free_cols:
 308        while (--i >= 0)
 309                gpio_free(pdata->col_gpios[i]);
 310
 311        return err;
 312}
 313
 314static int __devinit matrix_keypad_probe(struct platform_device *pdev)
 315{
 316        const struct matrix_keypad_platform_data *pdata;
 317        const struct matrix_keymap_data *keymap_data;
 318        struct matrix_keypad *keypad;
 319        struct input_dev *input_dev;
 320        unsigned short *keycodes;
 321        unsigned int row_shift;
 322        int err;
 323
 324        pdata = pdev->dev.platform_data;
 325        if (!pdata) {
 326                dev_err(&pdev->dev, "no platform data defined\n");
 327                return -EINVAL;
 328        }
 329
 330        keymap_data = pdata->keymap_data;
 331        if (!keymap_data) {
 332                dev_err(&pdev->dev, "no keymap data defined\n");
 333                return -EINVAL;
 334        }
 335
 336        row_shift = get_count_order(pdata->num_col_gpios);
 337
 338        keypad = kzalloc(sizeof(struct matrix_keypad), GFP_KERNEL);
 339        keycodes = kzalloc((pdata->num_row_gpios << row_shift) *
 340                                sizeof(*keycodes),
 341                           GFP_KERNEL);
 342        input_dev = input_allocate_device();
 343        if (!keypad || !keycodes || !input_dev) {
 344                err = -ENOMEM;
 345                goto err_free_mem;
 346        }
 347
 348        keypad->input_dev = input_dev;
 349        keypad->pdata = pdata;
 350        keypad->keycodes = keycodes;
 351        keypad->row_shift = row_shift;
 352        keypad->stopped = true;
 353        INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan);
 354        spin_lock_init(&keypad->lock);
 355
 356        input_dev->name         = pdev->name;
 357        input_dev->id.bustype   = BUS_HOST;
 358        input_dev->dev.parent   = &pdev->dev;
 359        input_dev->evbit[0]     = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
 360        input_dev->open         = matrix_keypad_start;
 361        input_dev->close        = matrix_keypad_stop;
 362
 363        input_dev->keycode      = keycodes;
 364        input_dev->keycodesize  = sizeof(*keycodes);
 365        input_dev->keycodemax   = pdata->num_row_gpios << row_shift;
 366
 367        matrix_keypad_build_keymap(keymap_data, row_shift,
 368                                   input_dev->keycode, input_dev->keybit);
 369
 370        input_set_capability(input_dev, EV_MSC, MSC_SCAN);
 371        input_set_drvdata(input_dev, keypad);
 372
 373        err = init_matrix_gpio(pdev, keypad);
 374        if (err)
 375                goto err_free_mem;
 376
 377        err = input_register_device(keypad->input_dev);
 378        if (err)
 379                goto err_free_mem;
 380
 381        device_init_wakeup(&pdev->dev, pdata->wakeup);
 382        platform_set_drvdata(pdev, keypad);
 383
 384        return 0;
 385
 386err_free_mem:
 387        input_free_device(input_dev);
 388        kfree(keycodes);
 389        kfree(keypad);
 390        return err;
 391}
 392
 393static int __devexit matrix_keypad_remove(struct platform_device *pdev)
 394{
 395        struct matrix_keypad *keypad = platform_get_drvdata(pdev);
 396        const struct matrix_keypad_platform_data *pdata = keypad->pdata;
 397        int i;
 398
 399        device_init_wakeup(&pdev->dev, 0);
 400
 401        for (i = 0; i < pdata->num_row_gpios; i++) {
 402                free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad);
 403                gpio_free(pdata->row_gpios[i]);
 404        }
 405
 406        for (i = 0; i < pdata->num_col_gpios; i++)
 407                gpio_free(pdata->col_gpios[i]);
 408
 409        input_unregister_device(keypad->input_dev);
 410        platform_set_drvdata(pdev, NULL);
 411        kfree(keypad->keycodes);
 412        kfree(keypad);
 413
 414        return 0;
 415}
 416
 417static struct platform_driver matrix_keypad_driver = {
 418        .probe          = matrix_keypad_probe,
 419        .remove         = __devexit_p(matrix_keypad_remove),
 420        .suspend        = matrix_keypad_suspend,
 421        .resume         = matrix_keypad_resume,
 422        .driver         = {
 423                .name   = "matrix-keypad",
 424                .owner  = THIS_MODULE,
 425        },
 426};
 427
 428static int __init matrix_keypad_init(void)
 429{
 430        return platform_driver_register(&matrix_keypad_driver);
 431}
 432
 433static void __exit matrix_keypad_exit(void)
 434{
 435        platform_driver_unregister(&matrix_keypad_driver);
 436}
 437
 438module_init(matrix_keypad_init);
 439module_exit(matrix_keypad_exit);
 440
 441MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
 442MODULE_DESCRIPTION("GPIO Driven Matrix Keypad Driver");
 443MODULE_LICENSE("GPL v2");
 444MODULE_ALIAS("platform:matrix-keypad");
 445