Path: blob/master/drivers/input/keyboard/stmpe-keypad.c
15109 views
/*1* Copyright (C) ST-Ericsson SA 20102*3* License Terms: GNU General Public License, version 24* Author: Rabin Vincent <[email protected]> for ST-Ericsson5*/67#include <linux/module.h>8#include <linux/init.h>9#include <linux/slab.h>10#include <linux/input.h>11#include <linux/interrupt.h>12#include <linux/platform_device.h>13#include <linux/input/matrix_keypad.h>14#include <linux/mfd/stmpe.h>1516/* These are at the same addresses in all STMPE variants */17#define STMPE_KPC_COL 0x6018#define STMPE_KPC_ROW_MSB 0x6119#define STMPE_KPC_ROW_LSB 0x6220#define STMPE_KPC_CTRL_MSB 0x6321#define STMPE_KPC_CTRL_LSB 0x6422#define STMPE_KPC_COMBI_KEY_0 0x6523#define STMPE_KPC_COMBI_KEY_1 0x6624#define STMPE_KPC_COMBI_KEY_2 0x6725#define STMPE_KPC_DATA_BYTE0 0x6826#define STMPE_KPC_DATA_BYTE1 0x6927#define STMPE_KPC_DATA_BYTE2 0x6a28#define STMPE_KPC_DATA_BYTE3 0x6b29#define STMPE_KPC_DATA_BYTE4 0x6c3031#define STMPE_KPC_CTRL_LSB_SCAN (0x1 << 0)32#define STMPE_KPC_CTRL_LSB_DEBOUNCE (0x7f << 1)33#define STMPE_KPC_CTRL_MSB_SCAN_COUNT (0xf << 4)3435#define STMPE_KPC_ROW_MSB_ROWS 0xff3637#define STMPE_KPC_DATA_UP (0x1 << 7)38#define STMPE_KPC_DATA_ROW (0xf << 3)39#define STMPE_KPC_DATA_COL (0x7 << 0)40#define STMPE_KPC_DATA_NOKEY_MASK 0x784142#define STMPE_KEYPAD_MAX_DEBOUNCE 12743#define STMPE_KEYPAD_MAX_SCAN_COUNT 154445#define STMPE_KEYPAD_MAX_ROWS 846#define STMPE_KEYPAD_MAX_COLS 847#define STMPE_KEYPAD_ROW_SHIFT 348#define STMPE_KEYPAD_KEYMAP_SIZE \49(STMPE_KEYPAD_MAX_ROWS * STMPE_KEYPAD_MAX_COLS)5051/**52* struct stmpe_keypad_variant - model-specific attributes53* @auto_increment: whether the KPC_DATA_BYTE register address54* auto-increments on multiple read55* @num_data: number of data bytes56* @num_normal_data: number of normal keys' data bytes57* @max_cols: maximum number of columns supported58* @max_rows: maximum number of rows supported59* @col_gpios: bitmask of gpios which can be used for columns60* @row_gpios: bitmask of gpios which can be used for rows61*/62struct stmpe_keypad_variant {63bool auto_increment;64int num_data;65int num_normal_data;66int max_cols;67int max_rows;68unsigned int col_gpios;69unsigned int row_gpios;70};7172static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {73[STMPE1601] = {74.auto_increment = true,75.num_data = 5,76.num_normal_data = 3,77.max_cols = 8,78.max_rows = 8,79.col_gpios = 0x000ff, /* GPIO 0 - 7 */80.row_gpios = 0x0ff00, /* GPIO 8 - 15 */81},82[STMPE2401] = {83.auto_increment = false,84.num_data = 3,85.num_normal_data = 2,86.max_cols = 8,87.max_rows = 12,88.col_gpios = 0x0000ff, /* GPIO 0 - 7*/89.row_gpios = 0x1fef00, /* GPIO 8-14, 16-20 */90},91[STMPE2403] = {92.auto_increment = true,93.num_data = 5,94.num_normal_data = 3,95.max_cols = 8,96.max_rows = 12,97.col_gpios = 0x0000ff, /* GPIO 0 - 7*/98.row_gpios = 0x1fef00, /* GPIO 8-14, 16-20 */99},100};101102struct stmpe_keypad {103struct stmpe *stmpe;104struct input_dev *input;105const struct stmpe_keypad_variant *variant;106const struct stmpe_keypad_platform_data *plat;107108unsigned int rows;109unsigned int cols;110111unsigned short keymap[STMPE_KEYPAD_KEYMAP_SIZE];112};113114static int stmpe_keypad_read_data(struct stmpe_keypad *keypad, u8 *data)115{116const struct stmpe_keypad_variant *variant = keypad->variant;117struct stmpe *stmpe = keypad->stmpe;118int ret;119int i;120121if (variant->auto_increment)122return stmpe_block_read(stmpe, STMPE_KPC_DATA_BYTE0,123variant->num_data, data);124125for (i = 0; i < variant->num_data; i++) {126ret = stmpe_reg_read(stmpe, STMPE_KPC_DATA_BYTE0 + i);127if (ret < 0)128return ret;129130data[i] = ret;131}132133return 0;134}135136static irqreturn_t stmpe_keypad_irq(int irq, void *dev)137{138struct stmpe_keypad *keypad = dev;139struct input_dev *input = keypad->input;140const struct stmpe_keypad_variant *variant = keypad->variant;141u8 fifo[variant->num_data];142int ret;143int i;144145ret = stmpe_keypad_read_data(keypad, fifo);146if (ret < 0)147return IRQ_NONE;148149for (i = 0; i < variant->num_normal_data; i++) {150u8 data = fifo[i];151int row = (data & STMPE_KPC_DATA_ROW) >> 3;152int col = data & STMPE_KPC_DATA_COL;153int code = MATRIX_SCAN_CODE(row, col, STMPE_KEYPAD_ROW_SHIFT);154bool up = data & STMPE_KPC_DATA_UP;155156if ((data & STMPE_KPC_DATA_NOKEY_MASK)157== STMPE_KPC_DATA_NOKEY_MASK)158continue;159160input_event(input, EV_MSC, MSC_SCAN, code);161input_report_key(input, keypad->keymap[code], !up);162input_sync(input);163}164165return IRQ_HANDLED;166}167168static int __devinit stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad)169{170const struct stmpe_keypad_variant *variant = keypad->variant;171unsigned int col_gpios = variant->col_gpios;172unsigned int row_gpios = variant->row_gpios;173struct stmpe *stmpe = keypad->stmpe;174unsigned int pins = 0;175int i;176177/*178* Figure out which pins need to be set to the keypad alternate179* function.180*181* {cols,rows}_gpios are bitmasks of which pins on the chip can be used182* for the keypad.183*184* keypad->{cols,rows} are a bitmask of which pins (of the ones useable185* for the keypad) are used on the board.186*/187188for (i = 0; i < variant->max_cols; i++) {189int num = __ffs(col_gpios);190191if (keypad->cols & (1 << i))192pins |= 1 << num;193194col_gpios &= ~(1 << num);195}196197for (i = 0; i < variant->max_rows; i++) {198int num = __ffs(row_gpios);199200if (keypad->rows & (1 << i))201pins |= 1 << num;202203row_gpios &= ~(1 << num);204}205206return stmpe_set_altfunc(stmpe, pins, STMPE_BLOCK_KEYPAD);207}208209static int __devinit stmpe_keypad_chip_init(struct stmpe_keypad *keypad)210{211const struct stmpe_keypad_platform_data *plat = keypad->plat;212const struct stmpe_keypad_variant *variant = keypad->variant;213struct stmpe *stmpe = keypad->stmpe;214int ret;215216if (plat->debounce_ms > STMPE_KEYPAD_MAX_DEBOUNCE)217return -EINVAL;218219if (plat->scan_count > STMPE_KEYPAD_MAX_SCAN_COUNT)220return -EINVAL;221222ret = stmpe_enable(stmpe, STMPE_BLOCK_KEYPAD);223if (ret < 0)224return ret;225226ret = stmpe_keypad_altfunc_init(keypad);227if (ret < 0)228return ret;229230ret = stmpe_reg_write(stmpe, STMPE_KPC_COL, keypad->cols);231if (ret < 0)232return ret;233234ret = stmpe_reg_write(stmpe, STMPE_KPC_ROW_LSB, keypad->rows);235if (ret < 0)236return ret;237238if (variant->max_rows > 8) {239ret = stmpe_set_bits(stmpe, STMPE_KPC_ROW_MSB,240STMPE_KPC_ROW_MSB_ROWS,241keypad->rows >> 8);242if (ret < 0)243return ret;244}245246ret = stmpe_set_bits(stmpe, STMPE_KPC_CTRL_MSB,247STMPE_KPC_CTRL_MSB_SCAN_COUNT,248plat->scan_count << 4);249if (ret < 0)250return ret;251252return stmpe_set_bits(stmpe, STMPE_KPC_CTRL_LSB,253STMPE_KPC_CTRL_LSB_SCAN |254STMPE_KPC_CTRL_LSB_DEBOUNCE,255STMPE_KPC_CTRL_LSB_SCAN |256(plat->debounce_ms << 1));257}258259static int __devinit stmpe_keypad_probe(struct platform_device *pdev)260{261struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent);262struct stmpe_keypad_platform_data *plat;263struct stmpe_keypad *keypad;264struct input_dev *input;265int ret;266int irq;267int i;268269plat = stmpe->pdata->keypad;270if (!plat)271return -ENODEV;272273irq = platform_get_irq(pdev, 0);274if (irq < 0)275return irq;276277keypad = kzalloc(sizeof(struct stmpe_keypad), GFP_KERNEL);278if (!keypad)279return -ENOMEM;280281input = input_allocate_device();282if (!input) {283ret = -ENOMEM;284goto out_freekeypad;285}286287input->name = "STMPE keypad";288input->id.bustype = BUS_I2C;289input->dev.parent = &pdev->dev;290291input_set_capability(input, EV_MSC, MSC_SCAN);292293__set_bit(EV_KEY, input->evbit);294if (!plat->no_autorepeat)295__set_bit(EV_REP, input->evbit);296297input->keycode = keypad->keymap;298input->keycodesize = sizeof(keypad->keymap[0]);299input->keycodemax = ARRAY_SIZE(keypad->keymap);300301matrix_keypad_build_keymap(plat->keymap_data, STMPE_KEYPAD_ROW_SHIFT,302input->keycode, input->keybit);303304for (i = 0; i < plat->keymap_data->keymap_size; i++) {305unsigned int key = plat->keymap_data->keymap[i];306307keypad->cols |= 1 << KEY_COL(key);308keypad->rows |= 1 << KEY_ROW(key);309}310311keypad->stmpe = stmpe;312keypad->plat = plat;313keypad->input = input;314keypad->variant = &stmpe_keypad_variants[stmpe->partnum];315316ret = stmpe_keypad_chip_init(keypad);317if (ret < 0)318goto out_freeinput;319320ret = input_register_device(input);321if (ret) {322dev_err(&pdev->dev,323"unable to register input device: %d\n", ret);324goto out_freeinput;325}326327ret = request_threaded_irq(irq, NULL, stmpe_keypad_irq, IRQF_ONESHOT,328"stmpe-keypad", keypad);329if (ret) {330dev_err(&pdev->dev, "unable to get irq: %d\n", ret);331goto out_unregisterinput;332}333334platform_set_drvdata(pdev, keypad);335336return 0;337338out_unregisterinput:339input_unregister_device(input);340input = NULL;341out_freeinput:342input_free_device(input);343out_freekeypad:344kfree(keypad);345return ret;346}347348static int __devexit stmpe_keypad_remove(struct platform_device *pdev)349{350struct stmpe_keypad *keypad = platform_get_drvdata(pdev);351struct stmpe *stmpe = keypad->stmpe;352int irq = platform_get_irq(pdev, 0);353354stmpe_disable(stmpe, STMPE_BLOCK_KEYPAD);355356free_irq(irq, keypad);357input_unregister_device(keypad->input);358platform_set_drvdata(pdev, NULL);359kfree(keypad);360361return 0;362}363364static struct platform_driver stmpe_keypad_driver = {365.driver.name = "stmpe-keypad",366.driver.owner = THIS_MODULE,367.probe = stmpe_keypad_probe,368.remove = __devexit_p(stmpe_keypad_remove),369};370371static int __init stmpe_keypad_init(void)372{373return platform_driver_register(&stmpe_keypad_driver);374}375module_init(stmpe_keypad_init);376377static void __exit stmpe_keypad_exit(void)378{379platform_driver_unregister(&stmpe_keypad_driver);380}381module_exit(stmpe_keypad_exit);382383MODULE_LICENSE("GPL v2");384MODULE_DESCRIPTION("STMPExxxx keypad driver");385MODULE_AUTHOR("Rabin Vincent <[email protected]>");386387388