linux/drivers/input/keyboard/imx_keypad.c
<<
>>
Prefs
   1/*
   2 * Driver for the IMX keypad port.
   3 * Copyright (C) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License version 2 as
   7 * published by the Free Software Foundation.
   8 *
   9 * <<Power management needs to be implemented>>.
  10 */
  11
  12#include <linux/clk.h>
  13#include <linux/delay.h>
  14#include <linux/device.h>
  15#include <linux/err.h>
  16#include <linux/init.h>
  17#include <linux/input/matrix_keypad.h>
  18#include <linux/interrupt.h>
  19#include <linux/io.h>
  20#include <linux/jiffies.h>
  21#include <linux/kernel.h>
  22#include <linux/module.h>
  23#include <linux/of.h>
  24#include <linux/platform_device.h>
  25#include <linux/slab.h>
  26#include <linux/timer.h>
  27
  28/*
  29 * Keypad Controller registers (halfword)
  30 */
  31#define KPCR            0x00 /* Keypad Control Register */
  32
  33#define KPSR            0x02 /* Keypad Status Register */
  34#define KBD_STAT_KPKD   (0x1 << 0) /* Key Press Interrupt Status bit (w1c) */
  35#define KBD_STAT_KPKR   (0x1 << 1) /* Key Release Interrupt Status bit (w1c) */
  36#define KBD_STAT_KDSC   (0x1 << 2) /* Key Depress Synch Chain Status bit (w1c)*/
  37#define KBD_STAT_KRSS   (0x1 << 3) /* Key Release Synch Status bit (w1c)*/
  38#define KBD_STAT_KDIE   (0x1 << 8) /* Key Depress Interrupt Enable Status bit */
  39#define KBD_STAT_KRIE   (0x1 << 9) /* Key Release Interrupt Enable */
  40#define KBD_STAT_KPPEN  (0x1 << 10) /* Keypad Clock Enable */
  41
  42#define KDDR            0x04 /* Keypad Data Direction Register */
  43#define KPDR            0x06 /* Keypad Data Register */
  44
  45#define MAX_MATRIX_KEY_ROWS     8
  46#define MAX_MATRIX_KEY_COLS     8
  47#define MATRIX_ROW_SHIFT        3
  48
  49#define MAX_MATRIX_KEY_NUM      (MAX_MATRIX_KEY_ROWS * MAX_MATRIX_KEY_COLS)
  50
  51struct imx_keypad {
  52
  53        struct clk *clk;
  54        struct input_dev *input_dev;
  55        void __iomem *mmio_base;
  56
  57        int                     irq;
  58        struct timer_list       check_matrix_timer;
  59
  60        /*
  61         * The matrix is stable only if no changes are detected after
  62         * IMX_KEYPAD_SCANS_FOR_STABILITY scans
  63         */
  64#define IMX_KEYPAD_SCANS_FOR_STABILITY 3
  65        int                     stable_count;
  66
  67        bool                    enabled;
  68
  69        /* Masks for enabled rows/cols */
  70        unsigned short          rows_en_mask;
  71        unsigned short          cols_en_mask;
  72
  73        unsigned short          keycodes[MAX_MATRIX_KEY_NUM];
  74
  75        /*
  76         * Matrix states:
  77         * -stable: achieved after a complete debounce process.
  78         * -unstable: used in the debouncing process.
  79         */
  80        unsigned short          matrix_stable_state[MAX_MATRIX_KEY_COLS];
  81        unsigned short          matrix_unstable_state[MAX_MATRIX_KEY_COLS];
  82};
  83
  84/* Scan the matrix and return the new state in *matrix_volatile_state. */
  85static void imx_keypad_scan_matrix(struct imx_keypad *keypad,
  86                                  unsigned short *matrix_volatile_state)
  87{
  88        int col;
  89        unsigned short reg_val;
  90
  91        for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) {
  92                if ((keypad->cols_en_mask & (1 << col)) == 0)
  93                        continue;
  94                /*
  95                 * Discharge keypad capacitance:
  96                 * 2. write 1s on column data.
  97                 * 3. configure columns as totem-pole to discharge capacitance.
  98                 * 4. configure columns as open-drain.
  99                 */
 100                reg_val = readw(keypad->mmio_base + KPDR);
 101                reg_val |= 0xff00;
 102                writew(reg_val, keypad->mmio_base + KPDR);
 103
 104                reg_val = readw(keypad->mmio_base + KPCR);
 105                reg_val &= ~((keypad->cols_en_mask & 0xff) << 8);
 106                writew(reg_val, keypad->mmio_base + KPCR);
 107
 108                udelay(2);
 109
 110                reg_val = readw(keypad->mmio_base + KPCR);
 111                reg_val |= (keypad->cols_en_mask & 0xff) << 8;
 112                writew(reg_val, keypad->mmio_base + KPCR);
 113
 114                /*
 115                 * 5. Write a single column to 0, others to 1.
 116                 * 6. Sample row inputs and save data.
 117                 * 7. Repeat steps 2 - 6 for remaining columns.
 118                 */
 119                reg_val = readw(keypad->mmio_base + KPDR);
 120                reg_val &= ~(1 << (8 + col));
 121                writew(reg_val, keypad->mmio_base + KPDR);
 122
 123                /*
 124                 * Delay added to avoid propagating the 0 from column to row
 125                 * when scanning.
 126                 */
 127                udelay(5);
 128
 129                /*
 130                 * 1s in matrix_volatile_state[col] means key pressures
 131                 * throw data from non enabled rows.
 132                 */
 133                reg_val = readw(keypad->mmio_base + KPDR);
 134                matrix_volatile_state[col] = (~reg_val) & keypad->rows_en_mask;
 135        }
 136
 137        /*
 138         * Return in standby mode:
 139         * 9. write 0s to columns
 140         */
 141        reg_val = readw(keypad->mmio_base + KPDR);
 142        reg_val &= 0x00ff;
 143        writew(reg_val, keypad->mmio_base + KPDR);
 144}
 145
 146/*
 147 * Compare the new matrix state (volatile) with the stable one stored in
 148 * keypad->matrix_stable_state and fire events if changes are detected.
 149 */
 150static void imx_keypad_fire_events(struct imx_keypad *keypad,
 151                                   unsigned short *matrix_volatile_state)
 152{
 153        struct input_dev *input_dev = keypad->input_dev;
 154        int row, col;
 155
 156        for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) {
 157                unsigned short bits_changed;
 158                int code;
 159
 160                if ((keypad->cols_en_mask & (1 << col)) == 0)
 161                        continue; /* Column is not enabled */
 162
 163                bits_changed = keypad->matrix_stable_state[col] ^
 164                                                matrix_volatile_state[col];
 165
 166                if (bits_changed == 0)
 167                        continue; /* Column does not contain changes */
 168
 169                for (row = 0; row < MAX_MATRIX_KEY_ROWS; row++) {
 170                        if ((keypad->rows_en_mask & (1 << row)) == 0)
 171                                continue; /* Row is not enabled */
 172                        if ((bits_changed & (1 << row)) == 0)
 173                                continue; /* Row does not contain changes */
 174
 175                        code = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT);
 176                        input_event(input_dev, EV_MSC, MSC_SCAN, code);
 177                        input_report_key(input_dev, keypad->keycodes[code],
 178                                matrix_volatile_state[col] & (1 << row));
 179                        dev_dbg(&input_dev->dev, "Event code: %d, val: %d",
 180                                keypad->keycodes[code],
 181                                matrix_volatile_state[col] & (1 << row));
 182                }
 183        }
 184        input_sync(input_dev);
 185}
 186
 187/*
 188 * imx_keypad_check_for_events is the timer handler.
 189 */
 190static void imx_keypad_check_for_events(unsigned long data)
 191{
 192        struct imx_keypad *keypad = (struct imx_keypad *) data;
 193        unsigned short matrix_volatile_state[MAX_MATRIX_KEY_COLS];
 194        unsigned short reg_val;
 195        bool state_changed, is_zero_matrix;
 196        int i;
 197
 198        memset(matrix_volatile_state, 0, sizeof(matrix_volatile_state));
 199
 200        imx_keypad_scan_matrix(keypad, matrix_volatile_state);
 201
 202        state_changed = false;
 203        for (i = 0; i < MAX_MATRIX_KEY_COLS; i++) {
 204                if ((keypad->cols_en_mask & (1 << i)) == 0)
 205                        continue;
 206
 207                if (keypad->matrix_unstable_state[i] ^ matrix_volatile_state[i]) {
 208                        state_changed = true;
 209                        break;
 210                }
 211        }
 212
 213        /*
 214         * If the matrix state is changed from the previous scan
 215         *   (Re)Begin the debouncing process, saving the new state in
 216         *    keypad->matrix_unstable_state.
 217         * else
 218         *   Increase the count of number of scans with a stable state.
 219         */
 220        if (state_changed) {
 221                memcpy(keypad->matrix_unstable_state, matrix_volatile_state,
 222                        sizeof(matrix_volatile_state));
 223                keypad->stable_count = 0;
 224        } else
 225                keypad->stable_count++;
 226
 227        /*
 228         * If the matrix is not as stable as we want reschedule scan
 229         * in the near future.
 230         */
 231        if (keypad->stable_count < IMX_KEYPAD_SCANS_FOR_STABILITY) {
 232                mod_timer(&keypad->check_matrix_timer,
 233                          jiffies + msecs_to_jiffies(10));
 234                return;
 235        }
 236
 237        /*
 238         * If the matrix state is stable, fire the events and save the new
 239         * stable state. Note, if the matrix is kept stable for longer
 240         * (keypad->stable_count > IMX_KEYPAD_SCANS_FOR_STABILITY) all
 241         * events have already been generated.
 242         */
 243        if (keypad->stable_count == IMX_KEYPAD_SCANS_FOR_STABILITY) {
 244                imx_keypad_fire_events(keypad, matrix_volatile_state);
 245
 246                memcpy(keypad->matrix_stable_state, matrix_volatile_state,
 247                        sizeof(matrix_volatile_state));
 248        }
 249
 250        is_zero_matrix = true;
 251        for (i = 0; i < MAX_MATRIX_KEY_COLS; i++) {
 252                if (matrix_volatile_state[i] != 0) {
 253                        is_zero_matrix = false;
 254                        break;
 255                }
 256        }
 257
 258
 259        if (is_zero_matrix) {
 260                /*
 261                 * All keys have been released. Enable only the KDI
 262                 * interrupt for future key presses (clear the KDI
 263                 * status bit and its sync chain before that).
 264                 */
 265                reg_val = readw(keypad->mmio_base + KPSR);
 266                reg_val |= KBD_STAT_KPKD | KBD_STAT_KDSC;
 267                writew(reg_val, keypad->mmio_base + KPSR);
 268
 269                reg_val = readw(keypad->mmio_base + KPSR);
 270                reg_val |= KBD_STAT_KDIE;
 271                reg_val &= ~KBD_STAT_KRIE;
 272                writew(reg_val, keypad->mmio_base + KPSR);
 273        } else {
 274                /*
 275                 * Some keys are still pressed. Schedule a rescan in
 276                 * attempt to detect multiple key presses and enable
 277                 * the KRI interrupt to react quickly to key release
 278                 * event.
 279                 */
 280                mod_timer(&keypad->check_matrix_timer,
 281                          jiffies + msecs_to_jiffies(60));
 282
 283                reg_val = readw(keypad->mmio_base + KPSR);
 284                reg_val |= KBD_STAT_KPKR | KBD_STAT_KRSS;
 285                writew(reg_val, keypad->mmio_base + KPSR);
 286
 287                reg_val = readw(keypad->mmio_base + KPSR);
 288                reg_val |= KBD_STAT_KRIE;
 289                reg_val &= ~KBD_STAT_KDIE;
 290                writew(reg_val, keypad->mmio_base + KPSR);
 291        }
 292}
 293
 294static irqreturn_t imx_keypad_irq_handler(int irq, void *dev_id)
 295{
 296        struct imx_keypad *keypad = dev_id;
 297        unsigned short reg_val;
 298
 299        reg_val = readw(keypad->mmio_base + KPSR);
 300
 301        /* Disable both interrupt types */
 302        reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE);
 303        /* Clear interrupts status bits */
 304        reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD;
 305        writew(reg_val, keypad->mmio_base + KPSR);
 306
 307        if (keypad->enabled) {
 308                /* The matrix is supposed to be changed */
 309                keypad->stable_count = 0;
 310
 311                /* Schedule the scanning procedure near in the future */
 312                mod_timer(&keypad->check_matrix_timer,
 313                          jiffies + msecs_to_jiffies(2));
 314        }
 315
 316        return IRQ_HANDLED;
 317}
 318
 319static void imx_keypad_config(struct imx_keypad *keypad)
 320{
 321        unsigned short reg_val;
 322
 323        /*
 324         * Include enabled rows in interrupt generation (KPCR[7:0])
 325         * Configure keypad columns as open-drain (KPCR[15:8])
 326         */
 327        reg_val = readw(keypad->mmio_base + KPCR);
 328        reg_val |= keypad->rows_en_mask & 0xff;         /* rows */
 329        reg_val |= (keypad->cols_en_mask & 0xff) << 8;  /* cols */
 330        writew(reg_val, keypad->mmio_base + KPCR);
 331
 332        /* Write 0's to KPDR[15:8] (Colums) */
 333        reg_val = readw(keypad->mmio_base + KPDR);
 334        reg_val &= 0x00ff;
 335        writew(reg_val, keypad->mmio_base + KPDR);
 336
 337        /* Configure columns as output, rows as input (KDDR[15:0]) */
 338        writew(0xff00, keypad->mmio_base + KDDR);
 339
 340        /*
 341         * Clear Key Depress and Key Release status bit.
 342         * Clear both synchronizer chain.
 343         */
 344        reg_val = readw(keypad->mmio_base + KPSR);
 345        reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD |
 346                   KBD_STAT_KDSC | KBD_STAT_KRSS;
 347        writew(reg_val, keypad->mmio_base + KPSR);
 348
 349        /* Enable KDI and disable KRI (avoid false release events). */
 350        reg_val |= KBD_STAT_KDIE;
 351        reg_val &= ~KBD_STAT_KRIE;
 352        writew(reg_val, keypad->mmio_base + KPSR);
 353}
 354
 355static void imx_keypad_inhibit(struct imx_keypad *keypad)
 356{
 357        unsigned short reg_val;
 358
 359        /* Inhibit KDI and KRI interrupts. */
 360        reg_val = readw(keypad->mmio_base + KPSR);
 361        reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE);
 362        reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD;
 363        writew(reg_val, keypad->mmio_base + KPSR);
 364
 365        /* Colums as open drain and disable all rows */
 366        reg_val = (keypad->cols_en_mask & 0xff) << 8;
 367        writew(reg_val, keypad->mmio_base + KPCR);
 368}
 369
 370static void imx_keypad_close(struct input_dev *dev)
 371{
 372        struct imx_keypad *keypad = input_get_drvdata(dev);
 373
 374        dev_dbg(&dev->dev, ">%s\n", __func__);
 375
 376        /* Mark keypad as being inactive */
 377        keypad->enabled = false;
 378        synchronize_irq(keypad->irq);
 379        del_timer_sync(&keypad->check_matrix_timer);
 380
 381        imx_keypad_inhibit(keypad);
 382
 383        /* Disable clock unit */
 384        clk_disable_unprepare(keypad->clk);
 385}
 386
 387static int imx_keypad_open(struct input_dev *dev)
 388{
 389        struct imx_keypad *keypad = input_get_drvdata(dev);
 390        int error;
 391
 392        dev_dbg(&dev->dev, ">%s\n", __func__);
 393
 394        /* Enable the kpp clock */
 395        error = clk_prepare_enable(keypad->clk);
 396        if (error)
 397                return error;
 398
 399        /* We became active from now */
 400        keypad->enabled = true;
 401
 402        imx_keypad_config(keypad);
 403
 404        /* Sanity control, not all the rows must be actived now. */
 405        if ((readw(keypad->mmio_base + KPDR) & keypad->rows_en_mask) == 0) {
 406                dev_err(&dev->dev,
 407                        "too many keys pressed, control pins initialisation\n");
 408                goto open_err;
 409        }
 410
 411        return 0;
 412
 413open_err:
 414        imx_keypad_close(dev);
 415        return -EIO;
 416}
 417
 418#ifdef CONFIG_OF
 419static struct of_device_id imx_keypad_of_match[] = {
 420        { .compatible = "fsl,imx21-kpp", },
 421        { /* sentinel */ }
 422};
 423MODULE_DEVICE_TABLE(of, imx_keypad_of_match);
 424#endif
 425
 426static int imx_keypad_probe(struct platform_device *pdev)
 427{
 428        const struct matrix_keymap_data *keymap_data = pdev->dev.platform_data;
 429        struct imx_keypad *keypad;
 430        struct input_dev *input_dev;
 431        struct resource *res;
 432        int irq, error, i, row, col;
 433
 434        if (!keymap_data && !pdev->dev.of_node) {
 435                dev_err(&pdev->dev, "no keymap defined\n");
 436                return -EINVAL;
 437        }
 438
 439        irq = platform_get_irq(pdev, 0);
 440        if (irq < 0) {
 441                dev_err(&pdev->dev, "no irq defined in platform data\n");
 442                return -EINVAL;
 443        }
 444
 445        input_dev = devm_input_allocate_device(&pdev->dev);
 446        if (!input_dev) {
 447                dev_err(&pdev->dev, "failed to allocate the input device\n");
 448                return -ENOMEM;
 449        }
 450
 451        keypad = devm_kzalloc(&pdev->dev, sizeof(struct imx_keypad),
 452                             GFP_KERNEL);
 453        if (!keypad) {
 454                dev_err(&pdev->dev, "not enough memory for driver data\n");
 455                return -ENOMEM;
 456        }
 457
 458        keypad->input_dev = input_dev;
 459        keypad->irq = irq;
 460        keypad->stable_count = 0;
 461
 462        setup_timer(&keypad->check_matrix_timer,
 463                    imx_keypad_check_for_events, (unsigned long) keypad);
 464
 465        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 466        keypad->mmio_base = devm_ioremap_resource(&pdev->dev, res);
 467        if (IS_ERR(keypad->mmio_base))
 468                return PTR_ERR(keypad->mmio_base);
 469
 470        keypad->clk = devm_clk_get(&pdev->dev, NULL);
 471        if (IS_ERR(keypad->clk)) {
 472                dev_err(&pdev->dev, "failed to get keypad clock\n");
 473                return PTR_ERR(keypad->clk);
 474        }
 475
 476        /* Init the Input device */
 477        input_dev->name = pdev->name;
 478        input_dev->id.bustype = BUS_HOST;
 479        input_dev->dev.parent = &pdev->dev;
 480        input_dev->open = imx_keypad_open;
 481        input_dev->close = imx_keypad_close;
 482
 483        error = matrix_keypad_build_keymap(keymap_data, NULL,
 484                                           MAX_MATRIX_KEY_ROWS,
 485                                           MAX_MATRIX_KEY_COLS,
 486                                           keypad->keycodes, input_dev);
 487        if (error) {
 488                dev_err(&pdev->dev, "failed to build keymap\n");
 489                return error;
 490        }
 491
 492        /* Search for rows and cols enabled */
 493        for (row = 0; row < MAX_MATRIX_KEY_ROWS; row++) {
 494                for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) {
 495                        i = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT);
 496                        if (keypad->keycodes[i] != KEY_RESERVED) {
 497                                keypad->rows_en_mask |= 1 << row;
 498                                keypad->cols_en_mask |= 1 << col;
 499                        }
 500                }
 501        }
 502        dev_dbg(&pdev->dev, "enabled rows mask: %x\n", keypad->rows_en_mask);
 503        dev_dbg(&pdev->dev, "enabled cols mask: %x\n", keypad->cols_en_mask);
 504
 505        __set_bit(EV_REP, input_dev->evbit);
 506        input_set_capability(input_dev, EV_MSC, MSC_SCAN);
 507        input_set_drvdata(input_dev, keypad);
 508
 509        /* Ensure that the keypad will stay dormant until opened */
 510        clk_prepare_enable(keypad->clk);
 511        imx_keypad_inhibit(keypad);
 512        clk_disable_unprepare(keypad->clk);
 513
 514        error = devm_request_irq(&pdev->dev, irq, imx_keypad_irq_handler, 0,
 515                            pdev->name, keypad);
 516        if (error) {
 517                dev_err(&pdev->dev, "failed to request IRQ\n");
 518                return error;
 519        }
 520
 521        /* Register the input device */
 522        error = input_register_device(input_dev);
 523        if (error) {
 524                dev_err(&pdev->dev, "failed to register input device\n");
 525                return error;
 526        }
 527
 528        platform_set_drvdata(pdev, keypad);
 529        device_init_wakeup(&pdev->dev, 1);
 530
 531        return 0;
 532}
 533
 534#ifdef CONFIG_PM_SLEEP
 535static int imx_kbd_suspend(struct device *dev)
 536{
 537        struct platform_device *pdev = to_platform_device(dev);
 538        struct imx_keypad *kbd = platform_get_drvdata(pdev);
 539        struct input_dev *input_dev = kbd->input_dev;
 540
 541        /* imx kbd can wake up system even clock is disabled */
 542        mutex_lock(&input_dev->mutex);
 543
 544        if (input_dev->users)
 545                clk_disable_unprepare(kbd->clk);
 546
 547        mutex_unlock(&input_dev->mutex);
 548
 549        if (device_may_wakeup(&pdev->dev))
 550                enable_irq_wake(kbd->irq);
 551
 552        return 0;
 553}
 554
 555static int imx_kbd_resume(struct device *dev)
 556{
 557        struct platform_device *pdev = to_platform_device(dev);
 558        struct imx_keypad *kbd = platform_get_drvdata(pdev);
 559        struct input_dev *input_dev = kbd->input_dev;
 560        int ret = 0;
 561
 562        if (device_may_wakeup(&pdev->dev))
 563                disable_irq_wake(kbd->irq);
 564
 565        mutex_lock(&input_dev->mutex);
 566
 567        if (input_dev->users) {
 568                ret = clk_prepare_enable(kbd->clk);
 569                if (ret)
 570                        goto err_clk;
 571        }
 572
 573err_clk:
 574        mutex_unlock(&input_dev->mutex);
 575
 576        return ret;
 577}
 578#endif
 579
 580static SIMPLE_DEV_PM_OPS(imx_kbd_pm_ops, imx_kbd_suspend, imx_kbd_resume);
 581
 582static struct platform_driver imx_keypad_driver = {
 583        .driver         = {
 584                .name   = "imx-keypad",
 585                .owner  = THIS_MODULE,
 586                .pm     = &imx_kbd_pm_ops,
 587                .of_match_table = of_match_ptr(imx_keypad_of_match),
 588        },
 589        .probe          = imx_keypad_probe,
 590};
 591module_platform_driver(imx_keypad_driver);
 592
 593MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>");
 594MODULE_DESCRIPTION("IMX Keypad Port Driver");
 595MODULE_LICENSE("GPL v2");
 596MODULE_ALIAS("platform:imx-keypad");
 597