linux/drivers/input/keyboard/nomadik-ske-keypad.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) ST-Ericsson SA 2010
   4 *
   5 * Author: Naveen Kumar G <naveen.gaddipati@stericsson.com> for ST-Ericsson
   6 * Author: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson
   7 *
   8 * Keypad controller driver for the SKE (Scroll Key Encoder) module used in
   9 * the Nomadik 8815 and Ux500 platforms.
  10 */
  11
  12#include <linux/platform_device.h>
  13#include <linux/interrupt.h>
  14#include <linux/spinlock.h>
  15#include <linux/io.h>
  16#include <linux/delay.h>
  17#include <linux/input.h>
  18#include <linux/slab.h>
  19#include <linux/clk.h>
  20#include <linux/module.h>
  21
  22#include <linux/platform_data/keypad-nomadik-ske.h>
  23
  24/* SKE_CR bits */
  25#define SKE_KPMLT       (0x1 << 6)
  26#define SKE_KPCN        (0x7 << 3)
  27#define SKE_KPASEN      (0x1 << 2)
  28#define SKE_KPASON      (0x1 << 7)
  29
  30/* SKE_IMSC bits */
  31#define SKE_KPIMA       (0x1 << 2)
  32
  33/* SKE_ICR bits */
  34#define SKE_KPICS       (0x1 << 3)
  35#define SKE_KPICA       (0x1 << 2)
  36
  37/* SKE_RIS bits */
  38#define SKE_KPRISA      (0x1 << 2)
  39
  40#define SKE_KEYPAD_ROW_SHIFT    3
  41#define SKE_KPD_NUM_ROWS        8
  42#define SKE_KPD_NUM_COLS        8
  43
  44/* keypad auto scan registers */
  45#define SKE_ASR0        0x20
  46#define SKE_ASR1        0x24
  47#define SKE_ASR2        0x28
  48#define SKE_ASR3        0x2C
  49
  50#define SKE_NUM_ASRX_REGISTERS  (4)
  51#define KEY_PRESSED_DELAY       10
  52
  53/**
  54 * struct ske_keypad  - data structure used by keypad driver
  55 * @irq:        irq no
  56 * @reg_base:   ske registers base address
  57 * @input:      pointer to input device object
  58 * @board:      keypad platform device
  59 * @keymap:     matrix scan code table for keycodes
  60 * @clk:        clock structure pointer
  61 */
  62struct ske_keypad {
  63        int irq;
  64        void __iomem *reg_base;
  65        struct input_dev *input;
  66        const struct ske_keypad_platform_data *board;
  67        unsigned short keymap[SKE_KPD_NUM_ROWS * SKE_KPD_NUM_COLS];
  68        struct clk *clk;
  69        struct clk *pclk;
  70        spinlock_t ske_keypad_lock;
  71};
  72
  73static void ske_keypad_set_bits(struct ske_keypad *keypad, u16 addr,
  74                u8 mask, u8 data)
  75{
  76        u32 ret;
  77
  78        spin_lock(&keypad->ske_keypad_lock);
  79
  80        ret = readl(keypad->reg_base + addr);
  81        ret &= ~mask;
  82        ret |= data;
  83        writel(ret, keypad->reg_base + addr);
  84
  85        spin_unlock(&keypad->ske_keypad_lock);
  86}
  87
  88/*
  89 * ske_keypad_chip_init: init keypad controller configuration
  90 *
  91 * Enable Multi key press detection, auto scan mode
  92 */
  93static int __init ske_keypad_chip_init(struct ske_keypad *keypad)
  94{
  95        u32 value;
  96        int timeout = keypad->board->debounce_ms;
  97
  98        /* check SKE_RIS to be 0 */
  99        while ((readl(keypad->reg_base + SKE_RIS) != 0x00000000) && timeout--)
 100                cpu_relax();
 101
 102        if (timeout == -1)
 103                return -EINVAL;
 104
 105        /*
 106         * set debounce value
 107         * keypad dbounce is configured in DBCR[15:8]
 108         * dbounce value in steps of 32/32.768 ms
 109         */
 110        spin_lock(&keypad->ske_keypad_lock);
 111        value = readl(keypad->reg_base + SKE_DBCR);
 112        value = value & 0xff;
 113        value |= ((keypad->board->debounce_ms * 32000)/32768) << 8;
 114        writel(value, keypad->reg_base + SKE_DBCR);
 115        spin_unlock(&keypad->ske_keypad_lock);
 116
 117        /* enable multi key detection */
 118        ske_keypad_set_bits(keypad, SKE_CR, 0x0, SKE_KPMLT);
 119
 120        /*
 121         * set up the number of columns
 122         * KPCN[5:3] defines no. of keypad columns to be auto scanned
 123         */
 124        value = (keypad->board->kcol - 1) << 3;
 125        ske_keypad_set_bits(keypad, SKE_CR, SKE_KPCN, value);
 126
 127        /* clear keypad interrupt for auto(and pending SW) scans */
 128        ske_keypad_set_bits(keypad, SKE_ICR, 0x0, SKE_KPICA | SKE_KPICS);
 129
 130        /* un-mask keypad interrupts */
 131        ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA);
 132
 133        /* enable automatic scan */
 134        ske_keypad_set_bits(keypad, SKE_CR, 0x0, SKE_KPASEN);
 135
 136        return 0;
 137}
 138
 139static void ske_keypad_report(struct ske_keypad *keypad, u8 status, int col)
 140{
 141        int row = 0, code, pos;
 142        struct input_dev *input = keypad->input;
 143        u32 ske_ris;
 144        int key_pressed;
 145        int num_of_rows;
 146
 147        /* find out the row */
 148        num_of_rows = hweight8(status);
 149        do {
 150                pos = __ffs(status);
 151                row = pos;
 152                status &= ~(1 << pos);
 153
 154                code = MATRIX_SCAN_CODE(row, col, SKE_KEYPAD_ROW_SHIFT);
 155                ske_ris = readl(keypad->reg_base + SKE_RIS);
 156                key_pressed = ske_ris & SKE_KPRISA;
 157
 158                input_event(input, EV_MSC, MSC_SCAN, code);
 159                input_report_key(input, keypad->keymap[code], key_pressed);
 160                input_sync(input);
 161                num_of_rows--;
 162        } while (num_of_rows);
 163}
 164
 165static void ske_keypad_read_data(struct ske_keypad *keypad)
 166{
 167        u8 status;
 168        int col = 0;
 169        int ske_asr, i;
 170
 171        /*
 172         * Read the auto scan registers
 173         *
 174         * Each SKE_ASRx (x=0 to x=3) contains two row values.
 175         * lower byte contains row value for column 2*x,
 176         * upper byte contains row value for column 2*x + 1
 177         */
 178        for (i = 0; i < SKE_NUM_ASRX_REGISTERS; i++) {
 179                ske_asr = readl(keypad->reg_base + SKE_ASR0 + (4 * i));
 180                if (!ske_asr)
 181                        continue;
 182
 183                /* now that ASRx is zero, find out the coloumn x and row y */
 184                status = ske_asr & 0xff;
 185                if (status) {
 186                        col = i * 2;
 187                        ske_keypad_report(keypad, status, col);
 188                }
 189                status = (ske_asr & 0xff00) >> 8;
 190                if (status) {
 191                        col = (i * 2) + 1;
 192                        ske_keypad_report(keypad, status, col);
 193                }
 194        }
 195}
 196
 197static irqreturn_t ske_keypad_irq(int irq, void *dev_id)
 198{
 199        struct ske_keypad *keypad = dev_id;
 200        int timeout = keypad->board->debounce_ms;
 201
 202        /* disable auto scan interrupt; mask the interrupt generated */
 203        ske_keypad_set_bits(keypad, SKE_IMSC, ~SKE_KPIMA, 0x0);
 204        ske_keypad_set_bits(keypad, SKE_ICR, 0x0, SKE_KPICA);
 205
 206        while ((readl(keypad->reg_base + SKE_CR) & SKE_KPASON) && --timeout)
 207                cpu_relax();
 208
 209        /* SKEx registers are stable and can be read */
 210        ske_keypad_read_data(keypad);
 211
 212        /* wait until raw interrupt is clear */
 213        while ((readl(keypad->reg_base + SKE_RIS)) && --timeout)
 214                msleep(KEY_PRESSED_DELAY);
 215
 216        /* enable auto scan interrupts */
 217        ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA);
 218
 219        return IRQ_HANDLED;
 220}
 221
 222static int __init ske_keypad_probe(struct platform_device *pdev)
 223{
 224        const struct ske_keypad_platform_data *plat =
 225                        dev_get_platdata(&pdev->dev);
 226        struct ske_keypad *keypad;
 227        struct input_dev *input;
 228        struct resource *res;
 229        int irq;
 230        int error;
 231
 232        if (!plat) {
 233                dev_err(&pdev->dev, "invalid keypad platform data\n");
 234                return -EINVAL;
 235        }
 236
 237        irq = platform_get_irq(pdev, 0);
 238        if (irq < 0)
 239                return -EINVAL;
 240
 241        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 242        if (!res) {
 243                dev_err(&pdev->dev, "missing platform resources\n");
 244                return -EINVAL;
 245        }
 246
 247        keypad = kzalloc(sizeof(struct ske_keypad), GFP_KERNEL);
 248        input = input_allocate_device();
 249        if (!keypad || !input) {
 250                dev_err(&pdev->dev, "failed to allocate keypad memory\n");
 251                error = -ENOMEM;
 252                goto err_free_mem;
 253        }
 254
 255        keypad->irq = irq;
 256        keypad->board = plat;
 257        keypad->input = input;
 258        spin_lock_init(&keypad->ske_keypad_lock);
 259
 260        if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
 261                dev_err(&pdev->dev, "failed to request I/O memory\n");
 262                error = -EBUSY;
 263                goto err_free_mem;
 264        }
 265
 266        keypad->reg_base = ioremap(res->start, resource_size(res));
 267        if (!keypad->reg_base) {
 268                dev_err(&pdev->dev, "failed to remap I/O memory\n");
 269                error = -ENXIO;
 270                goto err_free_mem_region;
 271        }
 272
 273        keypad->pclk = clk_get(&pdev->dev, "apb_pclk");
 274        if (IS_ERR(keypad->pclk)) {
 275                dev_err(&pdev->dev, "failed to get pclk\n");
 276                error = PTR_ERR(keypad->pclk);
 277                goto err_iounmap;
 278        }
 279
 280        keypad->clk = clk_get(&pdev->dev, NULL);
 281        if (IS_ERR(keypad->clk)) {
 282                dev_err(&pdev->dev, "failed to get clk\n");
 283                error = PTR_ERR(keypad->clk);
 284                goto err_pclk;
 285        }
 286
 287        input->id.bustype = BUS_HOST;
 288        input->name = "ux500-ske-keypad";
 289        input->dev.parent = &pdev->dev;
 290
 291        error = matrix_keypad_build_keymap(plat->keymap_data, NULL,
 292                                           SKE_KPD_NUM_ROWS, SKE_KPD_NUM_COLS,
 293                                           keypad->keymap, input);
 294        if (error) {
 295                dev_err(&pdev->dev, "Failed to build keymap\n");
 296                goto err_clk;
 297        }
 298
 299        input_set_capability(input, EV_MSC, MSC_SCAN);
 300        if (!plat->no_autorepeat)
 301                __set_bit(EV_REP, input->evbit);
 302
 303        error = clk_prepare_enable(keypad->pclk);
 304        if (error) {
 305                dev_err(&pdev->dev, "Failed to prepare/enable pclk\n");
 306                goto err_clk;
 307        }
 308
 309        error = clk_prepare_enable(keypad->clk);
 310        if (error) {
 311                dev_err(&pdev->dev, "Failed to prepare/enable clk\n");
 312                goto err_pclk_disable;
 313        }
 314
 315
 316        /* go through board initialization helpers */
 317        if (keypad->board->init)
 318                keypad->board->init();
 319
 320        error = ske_keypad_chip_init(keypad);
 321        if (error) {
 322                dev_err(&pdev->dev, "unable to init keypad hardware\n");
 323                goto err_clk_disable;
 324        }
 325
 326        error = request_threaded_irq(keypad->irq, NULL, ske_keypad_irq,
 327                                     IRQF_ONESHOT, "ske-keypad", keypad);
 328        if (error) {
 329                dev_err(&pdev->dev, "allocate irq %d failed\n", keypad->irq);
 330                goto err_clk_disable;
 331        }
 332
 333        error = input_register_device(input);
 334        if (error) {
 335                dev_err(&pdev->dev,
 336                                "unable to register input device: %d\n", error);
 337                goto err_free_irq;
 338        }
 339
 340        if (plat->wakeup_enable)
 341                device_init_wakeup(&pdev->dev, true);
 342
 343        platform_set_drvdata(pdev, keypad);
 344
 345        return 0;
 346
 347err_free_irq:
 348        free_irq(keypad->irq, keypad);
 349err_clk_disable:
 350        clk_disable_unprepare(keypad->clk);
 351err_pclk_disable:
 352        clk_disable_unprepare(keypad->pclk);
 353err_clk:
 354        clk_put(keypad->clk);
 355err_pclk:
 356        clk_put(keypad->pclk);
 357err_iounmap:
 358        iounmap(keypad->reg_base);
 359err_free_mem_region:
 360        release_mem_region(res->start, resource_size(res));
 361err_free_mem:
 362        input_free_device(input);
 363        kfree(keypad);
 364        return error;
 365}
 366
 367static int ske_keypad_remove(struct platform_device *pdev)
 368{
 369        struct ske_keypad *keypad = platform_get_drvdata(pdev);
 370        struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 371
 372        free_irq(keypad->irq, keypad);
 373
 374        input_unregister_device(keypad->input);
 375
 376        clk_disable_unprepare(keypad->clk);
 377        clk_put(keypad->clk);
 378
 379        if (keypad->board->exit)
 380                keypad->board->exit();
 381
 382        iounmap(keypad->reg_base);
 383        release_mem_region(res->start, resource_size(res));
 384        kfree(keypad);
 385
 386        return 0;
 387}
 388
 389#ifdef CONFIG_PM_SLEEP
 390static int ske_keypad_suspend(struct device *dev)
 391{
 392        struct platform_device *pdev = to_platform_device(dev);
 393        struct ske_keypad *keypad = platform_get_drvdata(pdev);
 394        int irq = platform_get_irq(pdev, 0);
 395
 396        if (device_may_wakeup(dev))
 397                enable_irq_wake(irq);
 398        else
 399                ske_keypad_set_bits(keypad, SKE_IMSC, ~SKE_KPIMA, 0x0);
 400
 401        return 0;
 402}
 403
 404static int ske_keypad_resume(struct device *dev)
 405{
 406        struct platform_device *pdev = to_platform_device(dev);
 407        struct ske_keypad *keypad = platform_get_drvdata(pdev);
 408        int irq = platform_get_irq(pdev, 0);
 409
 410        if (device_may_wakeup(dev))
 411                disable_irq_wake(irq);
 412        else
 413                ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA);
 414
 415        return 0;
 416}
 417#endif
 418
 419static SIMPLE_DEV_PM_OPS(ske_keypad_dev_pm_ops,
 420                         ske_keypad_suspend, ske_keypad_resume);
 421
 422static struct platform_driver ske_keypad_driver = {
 423        .driver = {
 424                .name = "nmk-ske-keypad",
 425                .pm = &ske_keypad_dev_pm_ops,
 426        },
 427        .remove = ske_keypad_remove,
 428};
 429
 430module_platform_driver_probe(ske_keypad_driver, ske_keypad_probe);
 431
 432MODULE_LICENSE("GPL v2");
 433MODULE_AUTHOR("Naveen Kumar <naveen.gaddipati@stericsson.com> / Sundar Iyer <sundar.iyer@stericsson.com>");
 434MODULE_DESCRIPTION("Nomadik Scroll-Key-Encoder Keypad Driver");
 435MODULE_ALIAS("platform:nomadik-ske-keypad");
 436