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