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