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