Commit 76f10845318b8c1baa8a2249f274ff847f31af5a

Authored by Rabin Vincent
Committed by Samuel Ortiz
1 parent 03f822f5e5

input: Add STMPE keypad driver

Add an input driver for the keypad on STMPE I/O expanders.  This driver
uses the common support provided by the STMPE MFD driver.

Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

Showing 3 changed files with 397 additions and 0 deletions Side-by-side Diff

drivers/input/keyboard/Kconfig
... ... @@ -395,6 +395,16 @@
395 395 To compile this driver as a module, choose M here: the
396 396 module will be called sh_keysc.
397 397  
  398 +config KEYBOARD_STMPE
  399 + tristate "STMPE keypad support"
  400 + depends on MFD_STMPE
  401 + help
  402 + Say Y here if you want to use the keypad controller on STMPE I/O
  403 + expanders.
  404 +
  405 + To compile this driver as a module, choose M here: the module will be
  406 + called stmpe-keypad.
  407 +
398 408 config KEYBOARD_DAVINCI
399 409 tristate "TI DaVinci Key Scan"
400 410 depends on ARCH_DAVINCI_DM365
drivers/input/keyboard/Makefile
... ... @@ -35,6 +35,7 @@
35 35 obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o
36 36 obj-$(CONFIG_KEYBOARD_SAMSUNG) += samsung-keypad.o
37 37 obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o
  38 +obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o
38 39 obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
39 40 obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o
40 41 obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o
drivers/input/keyboard/stmpe-keypad.c
  1 +/*
  2 + * Copyright (C) ST-Ericsson SA 2010
  3 + *
  4 + * License Terms: GNU General Public License, version 2
  5 + * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
  6 + */
  7 +
  8 +#include <linux/module.h>
  9 +#include <linux/init.h>
  10 +#include <linux/slab.h>
  11 +#include <linux/input.h>
  12 +#include <linux/interrupt.h>
  13 +#include <linux/platform_device.h>
  14 +#include <linux/input/matrix_keypad.h>
  15 +#include <linux/mfd/stmpe.h>
  16 +
  17 +/* These are at the same addresses in all STMPE variants */
  18 +#define STMPE_KPC_COL 0x60
  19 +#define STMPE_KPC_ROW_MSB 0x61
  20 +#define STMPE_KPC_ROW_LSB 0x62
  21 +#define STMPE_KPC_CTRL_MSB 0x63
  22 +#define STMPE_KPC_CTRL_LSB 0x64
  23 +#define STMPE_KPC_COMBI_KEY_0 0x65
  24 +#define STMPE_KPC_COMBI_KEY_1 0x66
  25 +#define STMPE_KPC_COMBI_KEY_2 0x67
  26 +#define STMPE_KPC_DATA_BYTE0 0x68
  27 +#define STMPE_KPC_DATA_BYTE1 0x69
  28 +#define STMPE_KPC_DATA_BYTE2 0x6a
  29 +#define STMPE_KPC_DATA_BYTE3 0x6b
  30 +#define STMPE_KPC_DATA_BYTE4 0x6c
  31 +
  32 +#define STMPE_KPC_CTRL_LSB_SCAN (0x1 << 0)
  33 +#define STMPE_KPC_CTRL_LSB_DEBOUNCE (0x7f << 1)
  34 +#define STMPE_KPC_CTRL_MSB_SCAN_COUNT (0xf << 4)
  35 +
  36 +#define STMPE_KPC_ROW_MSB_ROWS 0xff
  37 +
  38 +#define STMPE_KPC_DATA_UP (0x1 << 7)
  39 +#define STMPE_KPC_DATA_ROW (0xf << 3)
  40 +#define STMPE_KPC_DATA_COL (0x7 << 0)
  41 +#define STMPE_KPC_DATA_NOKEY_MASK 0x78
  42 +
  43 +#define STMPE_KEYPAD_MAX_DEBOUNCE 127
  44 +#define STMPE_KEYPAD_MAX_SCAN_COUNT 15
  45 +
  46 +#define STMPE_KEYPAD_MAX_ROWS 8
  47 +#define STMPE_KEYPAD_MAX_COLS 8
  48 +#define STMPE_KEYPAD_ROW_SHIFT 3
  49 +#define STMPE_KEYPAD_KEYMAP_SIZE \
  50 + (STMPE_KEYPAD_MAX_ROWS * STMPE_KEYPAD_MAX_COLS)
  51 +
  52 +/**
  53 + * struct stmpe_keypad_variant - model-specific attributes
  54 + * @auto_increment: whether the KPC_DATA_BYTE register address
  55 + * auto-increments on multiple read
  56 + * @num_data: number of data bytes
  57 + * @num_normal_data: number of normal keys' data bytes
  58 + * @max_cols: maximum number of columns supported
  59 + * @max_rows: maximum number of rows supported
  60 + * @col_gpios: bitmask of gpios which can be used for columns
  61 + * @row_gpios: bitmask of gpios which can be used for rows
  62 + */
  63 +struct stmpe_keypad_variant {
  64 + bool auto_increment;
  65 + int num_data;
  66 + int num_normal_data;
  67 + int max_cols;
  68 + int max_rows;
  69 + unsigned int col_gpios;
  70 + unsigned int row_gpios;
  71 +};
  72 +
  73 +static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
  74 + [STMPE1601] = {
  75 + .auto_increment = true,
  76 + .num_data = 5,
  77 + .num_normal_data = 3,
  78 + .max_cols = 8,
  79 + .max_rows = 8,
  80 + .col_gpios = 0x000ff, /* GPIO 0 - 7 */
  81 + .row_gpios = 0x0ff00, /* GPIO 8 - 15 */
  82 + },
  83 + [STMPE2401] = {
  84 + .auto_increment = false,
  85 + .num_data = 3,
  86 + .num_normal_data = 2,
  87 + .max_cols = 8,
  88 + .max_rows = 12,
  89 + .col_gpios = 0x0000ff, /* GPIO 0 - 7*/
  90 + .row_gpios = 0x1fef00, /* GPIO 8-14, 16-20 */
  91 + },
  92 + [STMPE2403] = {
  93 + .auto_increment = true,
  94 + .num_data = 5,
  95 + .num_normal_data = 3,
  96 + .max_cols = 8,
  97 + .max_rows = 12,
  98 + .col_gpios = 0x0000ff, /* GPIO 0 - 7*/
  99 + .row_gpios = 0x1fef00, /* GPIO 8-14, 16-20 */
  100 + },
  101 +};
  102 +
  103 +struct stmpe_keypad {
  104 + struct stmpe *stmpe;
  105 + struct input_dev *input;
  106 + const struct stmpe_keypad_variant *variant;
  107 + const struct stmpe_keypad_platform_data *plat;
  108 +
  109 + unsigned int rows;
  110 + unsigned int cols;
  111 +
  112 + unsigned short keymap[STMPE_KEYPAD_KEYMAP_SIZE];
  113 +};
  114 +
  115 +static int stmpe_keypad_read_data(struct stmpe_keypad *keypad, u8 *data)
  116 +{
  117 + const struct stmpe_keypad_variant *variant = keypad->variant;
  118 + struct stmpe *stmpe = keypad->stmpe;
  119 + int ret;
  120 + int i;
  121 +
  122 + if (variant->auto_increment)
  123 + return stmpe_block_read(stmpe, STMPE_KPC_DATA_BYTE0,
  124 + variant->num_data, data);
  125 +
  126 + for (i = 0; i < variant->num_data; i++) {
  127 + ret = stmpe_reg_read(stmpe, STMPE_KPC_DATA_BYTE0 + i);
  128 + if (ret < 0)
  129 + return ret;
  130 +
  131 + data[i] = ret;
  132 + }
  133 +
  134 + return 0;
  135 +}
  136 +
  137 +static irqreturn_t stmpe_keypad_irq(int irq, void *dev)
  138 +{
  139 + struct stmpe_keypad *keypad = dev;
  140 + struct input_dev *input = keypad->input;
  141 + const struct stmpe_keypad_variant *variant = keypad->variant;
  142 + u8 fifo[variant->num_data];
  143 + int ret;
  144 + int i;
  145 +
  146 + ret = stmpe_keypad_read_data(keypad, fifo);
  147 + if (ret < 0)
  148 + return IRQ_NONE;
  149 +
  150 + for (i = 0; i < variant->num_normal_data; i++) {
  151 + u8 data = fifo[i];
  152 + int row = (data & STMPE_KPC_DATA_ROW) >> 3;
  153 + int col = data & STMPE_KPC_DATA_COL;
  154 + int code = MATRIX_SCAN_CODE(row, col, STMPE_KEYPAD_ROW_SHIFT);
  155 + bool up = data & STMPE_KPC_DATA_UP;
  156 +
  157 + if ((data & STMPE_KPC_DATA_NOKEY_MASK)
  158 + == STMPE_KPC_DATA_NOKEY_MASK)
  159 + continue;
  160 +
  161 + input_event(input, EV_MSC, MSC_SCAN, code);
  162 + input_report_key(input, keypad->keymap[code], !up);
  163 + input_sync(input);
  164 + }
  165 +
  166 + return IRQ_HANDLED;
  167 +}
  168 +
  169 +static int __devinit stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad)
  170 +{
  171 + const struct stmpe_keypad_variant *variant = keypad->variant;
  172 + unsigned int col_gpios = variant->col_gpios;
  173 + unsigned int row_gpios = variant->row_gpios;
  174 + struct stmpe *stmpe = keypad->stmpe;
  175 + unsigned int pins = 0;
  176 + int i;
  177 +
  178 + /*
  179 + * Figure out which pins need to be set to the keypad alternate
  180 + * function.
  181 + *
  182 + * {cols,rows}_gpios are bitmasks of which pins on the chip can be used
  183 + * for the keypad.
  184 + *
  185 + * keypad->{cols,rows} are a bitmask of which pins (of the ones useable
  186 + * for the keypad) are used on the board.
  187 + */
  188 +
  189 + for (i = 0; i < variant->max_cols; i++) {
  190 + int num = __ffs(col_gpios);
  191 +
  192 + if (keypad->cols & (1 << i))
  193 + pins |= 1 << num;
  194 +
  195 + col_gpios &= ~(1 << num);
  196 + }
  197 +
  198 + for (i = 0; i < variant->max_rows; i++) {
  199 + int num = __ffs(row_gpios);
  200 +
  201 + if (keypad->rows & (1 << i))
  202 + pins |= 1 << num;
  203 +
  204 + row_gpios &= ~(1 << num);
  205 + }
  206 +
  207 + return stmpe_set_altfunc(stmpe, pins, STMPE_BLOCK_KEYPAD);
  208 +}
  209 +
  210 +static int __devinit stmpe_keypad_chip_init(struct stmpe_keypad *keypad)
  211 +{
  212 + const struct stmpe_keypad_platform_data *plat = keypad->plat;
  213 + const struct stmpe_keypad_variant *variant = keypad->variant;
  214 + struct stmpe *stmpe = keypad->stmpe;
  215 + int ret;
  216 +
  217 + if (plat->debounce_ms > STMPE_KEYPAD_MAX_DEBOUNCE)
  218 + return -EINVAL;
  219 +
  220 + if (plat->scan_count > STMPE_KEYPAD_MAX_SCAN_COUNT)
  221 + return -EINVAL;
  222 +
  223 + ret = stmpe_enable(stmpe, STMPE_BLOCK_KEYPAD);
  224 + if (ret < 0)
  225 + return ret;
  226 +
  227 + ret = stmpe_keypad_altfunc_init(keypad);
  228 + if (ret < 0)
  229 + return ret;
  230 +
  231 + ret = stmpe_reg_write(stmpe, STMPE_KPC_COL, keypad->cols);
  232 + if (ret < 0)
  233 + return ret;
  234 +
  235 + ret = stmpe_reg_write(stmpe, STMPE_KPC_ROW_LSB, keypad->rows);
  236 + if (ret < 0)
  237 + return ret;
  238 +
  239 + if (variant->max_rows > 8) {
  240 + ret = stmpe_set_bits(stmpe, STMPE_KPC_ROW_MSB,
  241 + STMPE_KPC_ROW_MSB_ROWS,
  242 + keypad->rows >> 8);
  243 + if (ret < 0)
  244 + return ret;
  245 + }
  246 +
  247 + ret = stmpe_set_bits(stmpe, STMPE_KPC_CTRL_MSB,
  248 + STMPE_KPC_CTRL_MSB_SCAN_COUNT,
  249 + plat->scan_count << 4);
  250 + if (ret < 0)
  251 + return ret;
  252 +
  253 + return stmpe_set_bits(stmpe, STMPE_KPC_CTRL_LSB,
  254 + STMPE_KPC_CTRL_LSB_SCAN |
  255 + STMPE_KPC_CTRL_LSB_DEBOUNCE,
  256 + STMPE_KPC_CTRL_LSB_SCAN |
  257 + (plat->debounce_ms << 1));
  258 +}
  259 +
  260 +static int __devinit stmpe_keypad_probe(struct platform_device *pdev)
  261 +{
  262 + struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent);
  263 + struct stmpe_keypad_platform_data *plat;
  264 + struct stmpe_keypad *keypad;
  265 + struct input_dev *input;
  266 + int ret;
  267 + int irq;
  268 + int i;
  269 +
  270 + plat = stmpe->pdata->keypad;
  271 + if (!plat)
  272 + return -ENODEV;
  273 +
  274 + irq = platform_get_irq(pdev, 0);
  275 + if (irq < 0)
  276 + return irq;
  277 +
  278 + keypad = kzalloc(sizeof(struct stmpe_keypad), GFP_KERNEL);
  279 + if (!keypad)
  280 + return -ENOMEM;
  281 +
  282 + input = input_allocate_device();
  283 + if (!input) {
  284 + ret = -ENOMEM;
  285 + goto out_freekeypad;
  286 + }
  287 +
  288 + input->name = "STMPE keypad";
  289 + input->id.bustype = BUS_I2C;
  290 + input->dev.parent = &pdev->dev;
  291 +
  292 + input_set_capability(input, EV_MSC, MSC_SCAN);
  293 +
  294 + __set_bit(EV_KEY, input->evbit);
  295 + if (!plat->no_autorepeat)
  296 + __set_bit(EV_REP, input->evbit);
  297 +
  298 + input->keycode = keypad->keymap;
  299 + input->keycodesize = sizeof(keypad->keymap[0]);
  300 + input->keycodemax = ARRAY_SIZE(keypad->keymap);
  301 +
  302 + matrix_keypad_build_keymap(plat->keymap_data, STMPE_KEYPAD_ROW_SHIFT,
  303 + input->keycode, input->keybit);
  304 +
  305 + for (i = 0; i < plat->keymap_data->keymap_size; i++) {
  306 + unsigned int key = plat->keymap_data->keymap[i];
  307 +
  308 + keypad->cols |= 1 << KEY_COL(key);
  309 + keypad->rows |= 1 << KEY_ROW(key);
  310 + }
  311 +
  312 + keypad->stmpe = stmpe;
  313 + keypad->plat = plat;
  314 + keypad->input = input;
  315 + keypad->variant = &stmpe_keypad_variants[stmpe->partnum];
  316 +
  317 + ret = stmpe_keypad_chip_init(keypad);
  318 + if (ret < 0)
  319 + goto out_freeinput;
  320 +
  321 + ret = input_register_device(input);
  322 + if (ret) {
  323 + dev_err(&pdev->dev,
  324 + "unable to register input device: %d\n", ret);
  325 + goto out_freeinput;
  326 + }
  327 +
  328 + ret = request_threaded_irq(irq, NULL, stmpe_keypad_irq, IRQF_ONESHOT,
  329 + "stmpe-keypad", keypad);
  330 + if (ret) {
  331 + dev_err(&pdev->dev, "unable to get irq: %d\n", ret);
  332 + goto out_unregisterinput;
  333 + }
  334 +
  335 + platform_set_drvdata(pdev, keypad);
  336 +
  337 + return 0;
  338 +
  339 +out_unregisterinput:
  340 + input_unregister_device(input);
  341 + input = NULL;
  342 +out_freeinput:
  343 + input_free_device(input);
  344 +out_freekeypad:
  345 + kfree(keypad);
  346 + return ret;
  347 +}
  348 +
  349 +static int __devexit stmpe_keypad_remove(struct platform_device *pdev)
  350 +{
  351 + struct stmpe_keypad *keypad = platform_get_drvdata(pdev);
  352 + struct stmpe *stmpe = keypad->stmpe;
  353 + int irq = platform_get_irq(pdev, 0);
  354 +
  355 + stmpe_disable(stmpe, STMPE_BLOCK_KEYPAD);
  356 +
  357 + free_irq(irq, keypad);
  358 + input_unregister_device(keypad->input);
  359 + platform_set_drvdata(pdev, NULL);
  360 + kfree(keypad);
  361 +
  362 + return 0;
  363 +}
  364 +
  365 +static struct platform_driver stmpe_keypad_driver = {
  366 + .driver.name = "stmpe-keypad",
  367 + .driver.owner = THIS_MODULE,
  368 + .probe = stmpe_keypad_probe,
  369 + .remove = __devexit_p(stmpe_keypad_remove),
  370 +};
  371 +
  372 +static int __init stmpe_keypad_init(void)
  373 +{
  374 + return platform_driver_register(&stmpe_keypad_driver);
  375 +}
  376 +module_init(stmpe_keypad_init);
  377 +
  378 +static void __exit stmpe_keypad_exit(void)
  379 +{
  380 + platform_driver_unregister(&stmpe_keypad_driver);
  381 +}
  382 +module_exit(stmpe_keypad_exit);
  383 +
  384 +MODULE_LICENSE("GPL v2");
  385 +MODULE_DESCRIPTION("STMPExxxx keypad driver");
  386 +MODULE_AUTHOR("Rabin Vincent <rabin.vincent@stericsson.com>");