linux/drivers/input/keyboard/tnetv107x-keypad.c
<<
>>
Prefs
   1/*
   2 * Texas Instruments TNETV107X Keypad Driver
   3 *
   4 * Copyright (C) 2010 Texas Instruments
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License as
   8 * published by the Free Software Foundation version 2.
   9 *
  10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  11 * kind, whether express or implied; without even the implied warranty
  12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 */
  15
  16#include <linux/kernel.h>
  17#include <linux/err.h>
  18#include <linux/errno.h>
  19#include <linux/input.h>
  20#include <linux/platform_device.h>
  21#include <linux/interrupt.h>
  22#include <linux/slab.h>
  23#include <linux/delay.h>
  24#include <linux/io.h>
  25#include <linux/clk.h>
  26#include <linux/input/matrix_keypad.h>
  27
  28#define BITS(x)                 (BIT(x) - 1)
  29
  30#define KEYPAD_ROWS             9
  31#define KEYPAD_COLS             9
  32
  33#define DEBOUNCE_MIN            0x400ul
  34#define DEBOUNCE_MAX            0x3ffffffful
  35
  36struct keypad_regs {
  37        u32     rev;
  38        u32     mode;
  39        u32     mask;
  40        u32     pol;
  41        u32     dclock;
  42        u32     rclock;
  43        u32     stable_cnt;
  44        u32     in_en;
  45        u32     out;
  46        u32     out_en;
  47        u32     in;
  48        u32     lock;
  49        u32     pres[3];
  50};
  51
  52#define keypad_read(kp, reg)            __raw_readl(&(kp)->regs->reg)
  53#define keypad_write(kp, reg, val)      __raw_writel(val, &(kp)->regs->reg)
  54
  55struct keypad_data {
  56        struct input_dev                *input_dev;
  57        struct resource                 *res;
  58        struct keypad_regs __iomem      *regs;
  59        struct clk                      *clk;
  60        struct device                   *dev;
  61        spinlock_t                      lock;
  62        u32                             irq_press;
  63        u32                             irq_release;
  64        int                             rows, cols, row_shift;
  65        int                             debounce_ms, active_low;
  66        u32                             prev_keys[3];
  67        unsigned short                  keycodes[];
  68};
  69
  70static irqreturn_t keypad_irq(int irq, void *data)
  71{
  72        struct keypad_data *kp = data;
  73        int i, bit, val, row, col, code;
  74        unsigned long flags;
  75        u32 curr_keys[3];
  76        u32 change;
  77
  78        spin_lock_irqsave(&kp->lock, flags);
  79
  80        memset(curr_keys, 0, sizeof(curr_keys));
  81        if (irq == kp->irq_press)
  82                for (i = 0; i < 3; i++)
  83                        curr_keys[i] = keypad_read(kp, pres[i]);
  84
  85        for (i = 0; i < 3; i++) {
  86                change = curr_keys[i] ^ kp->prev_keys[i];
  87
  88                while (change) {
  89                        bit     = fls(change) - 1;
  90                        change ^= BIT(bit);
  91                        val     = curr_keys[i] & BIT(bit);
  92                        bit    += i * 32;
  93                        row     = bit / KEYPAD_COLS;
  94                        col     = bit % KEYPAD_COLS;
  95
  96                        code = MATRIX_SCAN_CODE(row, col, kp->row_shift);
  97                        input_event(kp->input_dev, EV_MSC, MSC_SCAN, code);
  98                        input_report_key(kp->input_dev, kp->keycodes[code],
  99                                         val);
 100                }
 101        }
 102        input_sync(kp->input_dev);
 103        memcpy(kp->prev_keys, curr_keys, sizeof(curr_keys));
 104
 105        if (irq == kp->irq_press)
 106                keypad_write(kp, lock, 0); /* Allow hardware updates */
 107
 108        spin_unlock_irqrestore(&kp->lock, flags);
 109
 110        return IRQ_HANDLED;
 111}
 112
 113static int keypad_start(struct input_dev *dev)
 114{
 115        struct keypad_data *kp = input_get_drvdata(dev);
 116        unsigned long mask, debounce, clk_rate_khz;
 117        unsigned long flags;
 118
 119        clk_enable(kp->clk);
 120        clk_rate_khz = clk_get_rate(kp->clk) / 1000;
 121
 122        spin_lock_irqsave(&kp->lock, flags);
 123
 124        /* Initialize device registers */
 125        keypad_write(kp, mode, 0);
 126
 127        mask  = BITS(kp->rows) << KEYPAD_COLS;
 128        mask |= BITS(kp->cols);
 129        keypad_write(kp, mask, ~mask);
 130
 131        keypad_write(kp, pol, kp->active_low ? 0 : 0x3ffff);
 132        keypad_write(kp, stable_cnt, 3);
 133
 134        debounce = kp->debounce_ms * clk_rate_khz;
 135        debounce = clamp(debounce, DEBOUNCE_MIN, DEBOUNCE_MAX);
 136        keypad_write(kp, dclock, debounce);
 137        keypad_write(kp, rclock, 4 * debounce);
 138
 139        keypad_write(kp, in_en, 1);
 140
 141        spin_unlock_irqrestore(&kp->lock, flags);
 142
 143        return 0;
 144}
 145
 146static void keypad_stop(struct input_dev *dev)
 147{
 148        struct keypad_data *kp = input_get_drvdata(dev);
 149
 150        synchronize_irq(kp->irq_press);
 151        synchronize_irq(kp->irq_release);
 152        clk_disable(kp->clk);
 153}
 154
 155static int __devinit keypad_probe(struct platform_device *pdev)
 156{
 157        const struct matrix_keypad_platform_data *pdata;
 158        const struct matrix_keymap_data *keymap_data;
 159        struct device *dev = &pdev->dev;
 160        struct keypad_data *kp;
 161        int error = 0, sz, row_shift;
 162        u32 rev = 0;
 163
 164        pdata = pdev->dev.platform_data;
 165        if (!pdata) {
 166                dev_err(dev, "cannot find device data\n");
 167                return -EINVAL;
 168        }
 169
 170        keymap_data = pdata->keymap_data;
 171        if (!keymap_data) {
 172                dev_err(dev, "cannot find keymap data\n");
 173                return -EINVAL;
 174        }
 175
 176        row_shift = get_count_order(pdata->num_col_gpios);
 177        sz  = offsetof(struct keypad_data, keycodes);
 178        sz += (pdata->num_row_gpios << row_shift) * sizeof(kp->keycodes[0]);
 179        kp = kzalloc(sz, GFP_KERNEL);
 180        if (!kp) {
 181                dev_err(dev, "cannot allocate device info\n");
 182                return -ENOMEM;
 183        }
 184
 185        kp->dev  = dev;
 186        kp->rows = pdata->num_row_gpios;
 187        kp->cols = pdata->num_col_gpios;
 188        kp->row_shift = row_shift;
 189        platform_set_drvdata(pdev, kp);
 190        spin_lock_init(&kp->lock);
 191
 192        kp->irq_press   = platform_get_irq_byname(pdev, "press");
 193        kp->irq_release = platform_get_irq_byname(pdev, "release");
 194        if (kp->irq_press < 0 || kp->irq_release < 0) {
 195                dev_err(dev, "cannot determine device interrupts\n");
 196                error = -ENODEV;
 197                goto error_res;
 198        }
 199
 200        kp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 201        if (!kp->res) {
 202                dev_err(dev, "cannot determine register area\n");
 203                error = -ENODEV;
 204                goto error_res;
 205        }
 206
 207        if (!request_mem_region(kp->res->start, resource_size(kp->res),
 208                                pdev->name)) {
 209                dev_err(dev, "cannot claim register memory\n");
 210                kp->res = NULL;
 211                error = -EINVAL;
 212                goto error_res;
 213        }
 214
 215        kp->regs = ioremap(kp->res->start, resource_size(kp->res));
 216        if (!kp->regs) {
 217                dev_err(dev, "cannot map register memory\n");
 218                error = -ENOMEM;
 219                goto error_map;
 220        }
 221
 222        kp->clk = clk_get(dev, NULL);
 223        if (IS_ERR(kp->clk)) {
 224                dev_err(dev, "cannot claim device clock\n");
 225                error = PTR_ERR(kp->clk);
 226                goto error_clk;
 227        }
 228
 229        error = request_threaded_irq(kp->irq_press, NULL, keypad_irq, 0,
 230                                     dev_name(dev), kp);
 231        if (error < 0) {
 232                dev_err(kp->dev, "Could not allocate keypad press key irq\n");
 233                goto error_irq_press;
 234        }
 235
 236        error = request_threaded_irq(kp->irq_release, NULL, keypad_irq, 0,
 237                                     dev_name(dev), kp);
 238        if (error < 0) {
 239                dev_err(kp->dev, "Could not allocate keypad release key irq\n");
 240                goto error_irq_release;
 241        }
 242
 243        kp->input_dev = input_allocate_device();
 244        if (!kp->input_dev) {
 245                dev_err(dev, "cannot allocate input device\n");
 246                error = -ENOMEM;
 247                goto error_input;
 248        }
 249        input_set_drvdata(kp->input_dev, kp);
 250
 251        kp->input_dev->name       = pdev->name;
 252        kp->input_dev->dev.parent = &pdev->dev;
 253        kp->input_dev->open       = keypad_start;
 254        kp->input_dev->close      = keypad_stop;
 255        kp->input_dev->evbit[0]   = BIT_MASK(EV_KEY);
 256        if (!pdata->no_autorepeat)
 257                kp->input_dev->evbit[0] |= BIT_MASK(EV_REP);
 258
 259        clk_enable(kp->clk);
 260        rev = keypad_read(kp, rev);
 261        kp->input_dev->id.bustype = BUS_HOST;
 262        kp->input_dev->id.product = ((rev >>  8) & 0x07);
 263        kp->input_dev->id.version = ((rev >> 16) & 0xfff);
 264        clk_disable(kp->clk);
 265
 266        kp->input_dev->keycode     = kp->keycodes;
 267        kp->input_dev->keycodesize = sizeof(kp->keycodes[0]);
 268        kp->input_dev->keycodemax  = kp->rows << kp->row_shift;
 269
 270        matrix_keypad_build_keymap(keymap_data, kp->row_shift, kp->keycodes,
 271                                   kp->input_dev->keybit);
 272
 273        input_set_capability(kp->input_dev, EV_MSC, MSC_SCAN);
 274
 275        error = input_register_device(kp->input_dev);
 276        if (error < 0) {
 277                dev_err(dev, "Could not register input device\n");
 278                goto error_reg;
 279        }
 280
 281        return 0;
 282
 283
 284error_reg:
 285        input_free_device(kp->input_dev);
 286error_input:
 287        free_irq(kp->irq_release, kp);
 288error_irq_release:
 289        free_irq(kp->irq_press, kp);
 290error_irq_press:
 291        clk_put(kp->clk);
 292error_clk:
 293        iounmap(kp->regs);
 294error_map:
 295        release_mem_region(kp->res->start, resource_size(kp->res));
 296error_res:
 297        platform_set_drvdata(pdev, NULL);
 298        kfree(kp);
 299        return error;
 300}
 301
 302static int __devexit keypad_remove(struct platform_device *pdev)
 303{
 304        struct keypad_data *kp = platform_get_drvdata(pdev);
 305
 306        free_irq(kp->irq_press, kp);
 307        free_irq(kp->irq_release, kp);
 308        input_unregister_device(kp->input_dev);
 309        clk_put(kp->clk);
 310        iounmap(kp->regs);
 311        release_mem_region(kp->res->start, resource_size(kp->res));
 312        platform_set_drvdata(pdev, NULL);
 313        kfree(kp);
 314
 315        return 0;
 316}
 317
 318static struct platform_driver keypad_driver = {
 319        .probe          = keypad_probe,
 320        .remove         = __devexit_p(keypad_remove),
 321        .driver.name    = "tnetv107x-keypad",
 322        .driver.owner   = THIS_MODULE,
 323};
 324
 325static int __init keypad_init(void)
 326{
 327        return platform_driver_register(&keypad_driver);
 328}
 329
 330static void __exit keypad_exit(void)
 331{
 332        platform_driver_unregister(&keypad_driver);
 333}
 334
 335module_init(keypad_init);
 336module_exit(keypad_exit);
 337
 338MODULE_AUTHOR("Cyril Chemparathy");
 339MODULE_DESCRIPTION("TNETV107X Keypad Driver");
 340MODULE_ALIAS("platform:tnetv107x-keypad");
 341MODULE_LICENSE("GPL");
 342