From patchwork Tue Apr 9 08:35:20 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Nicolas Graux X-Patchwork-Id: 15989 Return-Path: X-Original-To: linaro@staging.patches.linaro.org Delivered-To: linaro@staging.patches.linaro.org Received: from mail-lb0-f200.google.com (mail-lb0-f200.google.com [209.85.217.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 5C0BF23970 for ; Tue, 9 Apr 2013 08:37:21 +0000 (UTC) Received: by mail-lb0-f200.google.com with SMTP id t12sf9620633lbi.3 for ; Tue, 09 Apr 2013 01:37:04 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:x-beenthere:x-received:received-spf:x-received :x-forwarded-to:x-forwarded-for:delivered-to:x-received:received-spf :from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :mime-version:x-gm-message-state:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :x-google-group-id:list-post:list-help:list-archive:list-unsubscribe :content-type; bh=R0wEY3nwyuV9IBW3ZQyO15YEJuMIj84zHcDFUKcQt/c=; b=oIv1QsQeobMyfmbEFcIIvsUTuTVjOwmarPXA+ExC8qHgUnwbgaSiVPZ7TLnooFiih2 +4SfzSgRFms4Qm5KNAqs73Fxk5hHKOZY+gAhnGgccfzHMOCznWFBLXQ0sqtsGWg3t4KH jnT1ZoJhQ/qwEAkZ7e+6IbgZU6wGjyjBGy2OWxMUePSiUInxpe8YBsj2FE7yIOncUnCj neKBQ7+WdeIhLnIv8le7USesDjDZtnr9i8lv3p+viz9KSus5aHd5dT2Wc6vyZ1L739N9 wla/O+rZsQOOwv+22PMcQbL89nzi1hCE5poaPotMB05F4ij2HFrMu00MMdcy6Olv3MO4 y3Pw== X-Received: by 10.180.106.232 with SMTP id gx8mr3294435wib.2.1365496623735; Tue, 09 Apr 2013 01:37:03 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.180.198.112 with SMTP id jb16ls1191026wic.2.canary; Tue, 09 Apr 2013 01:37:03 -0700 (PDT) X-Received: by 10.180.85.103 with SMTP id g7mr17948309wiz.23.1365496623585; Tue, 09 Apr 2013 01:37:03 -0700 (PDT) Received: from mail-ve0-f181.google.com (mail-ve0-f181.google.com [209.85.128.181]) by mx.google.com with ESMTPS id bg8si6029446wib.24.2013.04.09.01.37.02 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 09 Apr 2013 01:37:03 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.128.181 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.181; Received: by mail-ve0-f181.google.com with SMTP id pa12so6227565veb.12 for ; Tue, 09 Apr 2013 01:37:02 -0700 (PDT) X-Received: by 10.52.93.20 with SMTP id cq20mr15814045vdb.38.1365496621935; Tue, 09 Apr 2013 01:37:01 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.58.85.136 with SMTP id h8csp51681vez; Tue, 9 Apr 2013 01:37:00 -0700 (PDT) X-Received: by 10.14.210.132 with SMTP id u4mr46817104eeo.19.1365496620374; Tue, 09 Apr 2013 01:37:00 -0700 (PDT) Received: from eu1sys200aog112.obsmtp.com (eu1sys200aog112.obsmtp.com [207.126.144.133]) by mx.google.com with SMTP id 4si35746454eee.109.2013.04.09.01.36.56 (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 09 Apr 2013 01:37:00 -0700 (PDT) Received-SPF: neutral (google.com: 207.126.144.133 is neither permitted nor denied by best guess record for domain of jean-nicolas.graux@stericsson.com) client-ip=207.126.144.133; Received: from beta.dmz-eu.st.com ([164.129.1.35]) (using TLSv1) by eu1sys200aob112.postini.com ([207.126.147.11]) with SMTP ID DSNKUWPTKFgXOdVhTew+qNQSjs7JL/9re/jk@postini.com; Tue, 09 Apr 2013 08:37:00 UTC Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 717F71B7; Tue, 9 Apr 2013 08:36:53 +0000 (GMT) Received: from relay1.stm.gmessaging.net (unknown [10.230.100.17]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id C37CC488D; Tue, 9 Apr 2013 08:36:52 +0000 (GMT) Received: from exdcvycastm003.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm003", Issuer "exdcvycastm003" (not verified)) by relay1.stm.gmessaging.net (Postfix) with ESMTPS id 92EB624C07C; Tue, 9 Apr 2013 10:36:47 +0200 (CEST) Received: from lmenx30b.lme.st.com (10.230.100.153) by smtp.stericsson.com (10.230.100.1) with Microsoft SMTP Server (TLS) id 8.3.279.5; Tue, 9 Apr 2013 10:36:52 +0200 From: Jean-Nicolas Graux To: Samuel Ortiz , Cc: Lee Jones , Jean-Nicolas Graux Subject: [PATCH 2/3] input: keyboard: support stmpe1801 18 bits enhanced port expander Date: Tue, 9 Apr 2013 10:35:20 +0200 Message-ID: <1365496521-16880-2-git-send-email-jean-nicolas.graux@stericsson.com> X-Mailer: git-send-email 1.7.10 In-Reply-To: <1365496521-16880-1-git-send-email-jean-nicolas.graux@stericsson.com> References: <1365496521-16880-1-git-send-email-jean-nicolas.graux@stericsson.com> MIME-Version: 1.0 X-Gm-Message-State: ALoCoQlOGqKTaNwM+IZLvNusjzrghOnzr4mblKYfcobFQB2JwAceXjKMaFIyghfK8ozKDVapPUOG X-Original-Sender: patch@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.128.181 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Provides support for 1801 variant of stmpe gpio port expanders. This chip has 18 gpios configurable as GPI, GPO, keypad matrix, special key or dedicated key function. Note that special/dedicated key function is not supported yet. Signed-off-by: Jean-Nicolas Graux --- drivers/input/keyboard/stmpe-keypad.c | 267 ++++++++++++++++++++++++++------- 1 file changed, 211 insertions(+), 56 deletions(-) diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c index 5cbec56..fb973c8 100644 --- a/drivers/input/keyboard/stmpe-keypad.c +++ b/drivers/input/keyboard/stmpe-keypad.c @@ -14,40 +14,107 @@ #include #include -/* These are at the same addresses in all STMPE variants */ -#define STMPE_KPC_COL 0x60 -#define STMPE_KPC_ROW_MSB 0x61 -#define STMPE_KPC_ROW_LSB 0x62 -#define STMPE_KPC_CTRL_MSB 0x63 -#define STMPE_KPC_CTRL_LSB 0x64 -#define STMPE_KPC_COMBI_KEY_0 0x65 -#define STMPE_KPC_COMBI_KEY_1 0x66 -#define STMPE_KPC_COMBI_KEY_2 0x67 -#define STMPE_KPC_DATA_BYTE0 0x68 -#define STMPE_KPC_DATA_BYTE1 0x69 -#define STMPE_KPC_DATA_BYTE2 0x6a -#define STMPE_KPC_DATA_BYTE3 0x6b -#define STMPE_KPC_DATA_BYTE4 0x6c +/* These are at the same addresses in most of STMPE variants */ +#define STMPE_REG_KPC_COL 0x60 +#define STMPE_REG_KPC_ROW_MSB 0x61 +#define STMPE_REG_KPC_ROW_LSB 0x62 +#define STMPE_REG_KPC_CTRL_MSB 0x63 +#define STMPE_REG_KPC_CTRL_LSB 0x64 +#define STMPE_REG_KPC_COMBI_KEY_0 0x65 +#define STMPE_REG_KPC_COMBI_KEY_1 0x66 +#define STMPE_REG_KPC_COMBI_KEY_2 0x67 +#define STMPE_REG_KPC_DATA_BYTE0 0x68 +#define STMPE_REG_KPC_DATA_BYTE1 0x69 +#define STMPE_REG_KPC_DATA_BYTE2 0x6a +#define STMPE_REG_KPC_DATA_BYTE3 0x6b +#define STMPE_REG_KPC_DATA_BYTE4 0x6c #define STMPE_KPC_CTRL_LSB_SCAN (0x1 << 0) #define STMPE_KPC_CTRL_LSB_DEBOUNCE (0x7f << 1) #define STMPE_KPC_CTRL_MSB_SCAN_COUNT (0xf << 4) +/* STMPE1801 */ +#define STMPE1801_REG_KPC_ROW 0x30 +#define STMPE1801_REG_KPC_COL_LOW 0x31 +#define STMPE1801_REG_KPC_COL_HIGH 0x32 +#define STMPE1801_REG_KPC_CTRL_LOW 0x33 +#define STMPE1801_REG_KPC_CTRL_MID 0x34 +#define STMPE1801_REG_KPC_CTRL_HIGH 0x35 +#define STMPE1801_REG_KPC_CMD 0x36 +#define STMPE1801_REG_KPC_COMBI_KEY_0 0x37 +#define STMPE1801_REG_KPC_COMBI_KEY_1 0x38 +#define STMPE1801_REG_KPC_COMBI_KEY_2 0x39 +#define STMPE1801_REG_KPC_DATA_BYTE0 0x3a +#define STMPE1801_REG_KPC_DATA_BYTE1 0x3b +#define STMPE1801_REG_KPC_DATA_BYTE2 0x3c +#define STMPE1801_REG_KPC_DATA_BYTE3 0x3d +#define STMPE1801_REG_KPC_DATA_BYTE4 0x3e + +#define STMPE1801_MSK_KPC_SCAN_COUNT (0xf << 4) +#define STMPE1801_MSK_KPC_DEBOUNCE (0x3f << 2) +#define STMPE1801_MSK_KPC_CMD_SCAN (0x1 << 0) + #define STMPE_KPC_ROW_MSB_ROWS 0xff #define STMPE_KPC_DATA_UP (0x1 << 7) -#define STMPE_KPC_DATA_ROW (0xf << 3) -#define STMPE_KPC_DATA_COL (0x7 << 0) + #define STMPE_KPC_DATA_NOKEY_MASK 0x78 #define STMPE_KEYPAD_MAX_DEBOUNCE 127 #define STMPE_KEYPAD_MAX_SCAN_COUNT 15 -#define STMPE_KEYPAD_MAX_ROWS 8 -#define STMPE_KEYPAD_MAX_COLS 8 -#define STMPE_KEYPAD_ROW_SHIFT 3 -#define STMPE_KEYPAD_KEYMAP_SIZE \ - (STMPE_KEYPAD_MAX_ROWS * STMPE_KEYPAD_MAX_COLS) +enum { + STMPE_IDX_KPC_COL_LSB, + STMPE_IDX_KPC_COL_MSB, + STMPE_IDX_KPC_ROW_LSB, + STMPE_IDX_KPC_ROW_MSB, + STMPE_IDX_KPC_CTRL_LSB, + STMPE_IDX_KPC_CTRL_MID, + STMPE_IDX_KPC_CTRL_MSB, + STMPE_IDX_KPC_CMD, + STMPE_IDX_KPC_COMBI_KEY_0, + STMPE_IDX_KPC_COMBI_KEY_1, + STMPE_IDX_KPC_COMBI_KEY_2, + STMPE_IDX_KPC_DATA_BYTE0, + STMPE_IDX_KPC_DATA_BYTE1, + STMPE_IDX_KPC_DATA_BYTE2, + STMPE_IDX_KPC_DATA_BYTE3, + STMPE_IDX_KPC_DATA_BYTE4, +}; + +static const u8 stmpe_default_regs[] = { + [STMPE_IDX_KPC_COL_LSB] = STMPE_REG_KPC_COL, + [STMPE_IDX_KPC_ROW_LSB] = STMPE_REG_KPC_ROW_LSB, + [STMPE_IDX_KPC_ROW_MSB] = STMPE_REG_KPC_ROW_MSB, + [STMPE_IDX_KPC_CTRL_LSB] = STMPE_REG_KPC_CTRL_LSB, + [STMPE_IDX_KPC_CTRL_MSB] = STMPE_REG_KPC_CTRL_MSB, + [STMPE_IDX_KPC_COMBI_KEY_0] = STMPE_REG_KPC_COMBI_KEY_0, + [STMPE_IDX_KPC_COMBI_KEY_1] = STMPE_REG_KPC_COMBI_KEY_1, + [STMPE_IDX_KPC_COMBI_KEY_2] = STMPE_REG_KPC_COMBI_KEY_2, + [STMPE_IDX_KPC_DATA_BYTE0] = STMPE_REG_KPC_DATA_BYTE0, + [STMPE_IDX_KPC_DATA_BYTE1] = STMPE_REG_KPC_DATA_BYTE1, + [STMPE_IDX_KPC_DATA_BYTE2] = STMPE_REG_KPC_DATA_BYTE2, + [STMPE_IDX_KPC_DATA_BYTE3] = STMPE_REG_KPC_DATA_BYTE3, + [STMPE_IDX_KPC_DATA_BYTE4] = STMPE_REG_KPC_DATA_BYTE4, +}; + +static const u8 stmpe_1801_regs[] = { + [STMPE_IDX_KPC_COL_LSB] = STMPE1801_REG_KPC_COL_LOW, + [STMPE_IDX_KPC_COL_MSB] = STMPE1801_REG_KPC_COL_HIGH, + [STMPE_IDX_KPC_ROW_LSB] = STMPE1801_REG_KPC_ROW, + [STMPE_IDX_KPC_CTRL_LSB] = STMPE1801_REG_KPC_CTRL_LOW, + [STMPE_IDX_KPC_CTRL_MID] = STMPE1801_REG_KPC_CTRL_MID, + [STMPE_IDX_KPC_CTRL_MSB] = STMPE1801_REG_KPC_CTRL_HIGH, + [STMPE_IDX_KPC_CMD] = STMPE1801_REG_KPC_CMD, + [STMPE_IDX_KPC_COMBI_KEY_0] = STMPE1801_REG_KPC_COMBI_KEY_0, + [STMPE_IDX_KPC_COMBI_KEY_1] = STMPE1801_REG_KPC_COMBI_KEY_1, + [STMPE_IDX_KPC_COMBI_KEY_2] = STMPE1801_REG_KPC_COMBI_KEY_2, + [STMPE_IDX_KPC_DATA_BYTE0] = STMPE1801_REG_KPC_DATA_BYTE0, + [STMPE_IDX_KPC_DATA_BYTE1] = STMPE1801_REG_KPC_DATA_BYTE1, + [STMPE_IDX_KPC_DATA_BYTE2] = STMPE1801_REG_KPC_DATA_BYTE2, + [STMPE_IDX_KPC_DATA_BYTE3] = STMPE1801_REG_KPC_DATA_BYTE3, + [STMPE_IDX_KPC_DATA_BYTE4] = STMPE1801_REG_KPC_DATA_BYTE4, +}; /** * struct stmpe_keypad_variant - model-specific attributes @@ -57,6 +124,10 @@ * @num_normal_data: number of normal keys' data bytes * @max_cols: maximum number of columns supported * @max_rows: maximum number of rows supported + * @row_mask: mask used to get row number in KPC_DATA_BYTEx registers + * @col_mask: mask used to get column number in KPC_DATA_BYTEx registers + * @row_shift: shift used to get row number in KPC_DATA_BYTEx registers + * @col_shift: shift used to get column number in KPC_DATA_BYTEx registers * @col_gpios: bitmask of gpios which can be used for columns * @row_gpios: bitmask of gpios which can be used for rows */ @@ -66,8 +137,13 @@ struct stmpe_keypad_variant { int num_normal_data; int max_cols; int max_rows; + unsigned int row_mask; + unsigned int col_mask; + unsigned char row_shift; + unsigned char col_shift; unsigned int col_gpios; unsigned int row_gpios; + const u8 *regs; }; static const struct stmpe_keypad_variant stmpe_keypad_variants[] = { @@ -77,8 +153,27 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = { .num_normal_data = 3, .max_cols = 8, .max_rows = 8, + .row_mask = (0xf << 3), + .row_shift = 3, + .col_mask = (0x7 << 0), + .col_shift = 0, .col_gpios = 0x000ff, /* GPIO 0 - 7 */ .row_gpios = 0x0ff00, /* GPIO 8 - 15 */ + .regs = stmpe_default_regs, + }, + [STMPE1801] = { + .auto_increment = true, + .num_data = 5, + .num_normal_data = 3, + .max_cols = 10, + .max_rows = 8, + .row_mask = (0x7 << 0), + .row_shift = 0, + .col_mask = (0xf << 3), + .col_shift = 3, + .col_gpios = 0x3ff00, /* GPIO 8 - 17 */ + .row_gpios = 0x000ff, /* GPIO 0 - 7 */ + .regs = stmpe_1801_regs, }, [STMPE2401] = { .auto_increment = false, @@ -86,8 +181,13 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = { .num_normal_data = 2, .max_cols = 8, .max_rows = 12, + .row_mask = (0xf << 3), + .row_shift = 3, + .col_mask = (0x7 << 0), + .col_shift = 0, .col_gpios = 0x0000ff, /* GPIO 0 - 7*/ .row_gpios = 0x1fef00, /* GPIO 8-14, 16-20 */ + .regs = stmpe_default_regs, }, [STMPE2403] = { .auto_increment = true, @@ -95,8 +195,13 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = { .num_normal_data = 3, .max_cols = 8, .max_rows = 12, + .row_mask = (0xf << 3), + .row_shift = 3, + .col_mask = (0x7 << 0), + .col_shift = 0, .col_gpios = 0x0000ff, /* GPIO 0 - 7*/ .row_gpios = 0x1fef00, /* GPIO 8-14, 16-20 */ + .regs = stmpe_default_regs, }, }; @@ -108,8 +213,8 @@ struct stmpe_keypad { unsigned int rows; unsigned int cols; - - unsigned short keymap[STMPE_KEYPAD_KEYMAP_SIZE]; + unsigned char scan_code_row_shift; + unsigned short *keymap; }; static int stmpe_keypad_read_data(struct stmpe_keypad *keypad, u8 *data) @@ -120,11 +225,13 @@ static int stmpe_keypad_read_data(struct stmpe_keypad *keypad, u8 *data) int i; if (variant->auto_increment) - return stmpe_block_read(stmpe, STMPE_KPC_DATA_BYTE0, - variant->num_data, data); + return stmpe_block_read(stmpe, + variant->regs[STMPE_IDX_KPC_DATA_BYTE0], + variant->num_data, data); for (i = 0; i < variant->num_data; i++) { - ret = stmpe_reg_read(stmpe, STMPE_KPC_DATA_BYTE0 + i); + ret = stmpe_reg_read(stmpe, + variant->regs[STMPE_IDX_KPC_DATA_BYTE0] + i); if (ret < 0) return ret; @@ -149,9 +256,10 @@ static irqreturn_t stmpe_keypad_irq(int irq, void *dev) for (i = 0; i < variant->num_normal_data; i++) { u8 data = fifo[i]; - int row = (data & STMPE_KPC_DATA_ROW) >> 3; - int col = data & STMPE_KPC_DATA_COL; - int code = MATRIX_SCAN_CODE(row, col, STMPE_KEYPAD_ROW_SHIFT); + int row = (data & variant->row_mask) >> variant->row_shift; + int col = (data & variant->col_mask) >> variant->col_shift; + int code = MATRIX_SCAN_CODE(row, col, + keypad->scan_code_row_shift); bool up = data & STMPE_KPC_DATA_UP; if ((data & STMPE_KPC_DATA_NOKEY_MASK) @@ -228,43 +336,79 @@ static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad) if (ret < 0) return ret; - ret = stmpe_reg_write(stmpe, STMPE_KPC_COL, keypad->cols); + ret = stmpe_reg_write(stmpe, variant->regs[STMPE_IDX_KPC_COL_LSB], + keypad->cols); if (ret < 0) return ret; - ret = stmpe_reg_write(stmpe, STMPE_KPC_ROW_LSB, keypad->rows); + if (stmpe->partnum == STMPE1801 && variant->max_cols > 8) { + ret = stmpe_set_bits(stmpe, + variant->regs[STMPE_IDX_KPC_COL_MSB], + 0x3, + keypad->cols >> 8); + if (ret < 0) + return ret; + } + + ret = stmpe_reg_write(stmpe, variant->regs[STMPE_IDX_KPC_ROW_LSB], + keypad->rows); if (ret < 0) return ret; if (variant->max_rows > 8) { - ret = stmpe_set_bits(stmpe, STMPE_KPC_ROW_MSB, - STMPE_KPC_ROW_MSB_ROWS, - keypad->rows >> 8); + ret = stmpe_set_bits(stmpe, + variant->regs[STMPE_IDX_KPC_ROW_MSB], + STMPE_KPC_ROW_MSB_ROWS, + keypad->rows >> 8); if (ret < 0) return ret; } - ret = stmpe_set_bits(stmpe, STMPE_KPC_CTRL_MSB, - STMPE_KPC_CTRL_MSB_SCAN_COUNT, - plat->scan_count << 4); - if (ret < 0) - return ret; + if (stmpe->partnum == STMPE1801) { + ret = stmpe_set_bits(stmpe, + variant->regs[STMPE_IDX_KPC_CTRL_LSB], + STMPE1801_MSK_KPC_SCAN_COUNT, + plat->scan_count << 4); + if (ret < 0) + return ret; + + ret = stmpe_set_bits(stmpe, + variant->regs[STMPE_IDX_KPC_CTRL_MID], + STMPE1801_MSK_KPC_DEBOUNCE, + (plat->debounce_ms << 1)); + if (ret < 0) + return ret; + + return stmpe_set_bits(stmpe, + variant->regs[STMPE_IDX_KPC_CMD], + STMPE1801_MSK_KPC_CMD_SCAN, + STMPE1801_MSK_KPC_CMD_SCAN); + } else { + ret = stmpe_set_bits(stmpe, + variant->regs[STMPE_IDX_KPC_CTRL_MSB], + STMPE_KPC_CTRL_MSB_SCAN_COUNT, + plat->scan_count << 4); + if (ret < 0) + return ret; + + return stmpe_set_bits(stmpe, + variant->regs[STMPE_IDX_KPC_CTRL_LSB], + STMPE_KPC_CTRL_LSB_SCAN | + STMPE_KPC_CTRL_LSB_DEBOUNCE, + STMPE_KPC_CTRL_LSB_SCAN | + (plat->debounce_ms << 1)); + } - return stmpe_set_bits(stmpe, STMPE_KPC_CTRL_LSB, - STMPE_KPC_CTRL_LSB_SCAN | - STMPE_KPC_CTRL_LSB_DEBOUNCE, - STMPE_KPC_CTRL_LSB_SCAN | - (plat->debounce_ms << 1)); } static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad) { int row, col; - for (row = 0; row < STMPE_KEYPAD_MAX_ROWS; row++) { - for (col = 0; col < STMPE_KEYPAD_MAX_COLS; col++) { + for (row = 0; row < keypad->variant->max_rows; row++) { + for (col = 0; col < keypad->variant->max_cols; col++) { int code = MATRIX_SCAN_CODE(row, col, - STMPE_KEYPAD_ROW_SHIFT); + keypad->scan_code_row_shift); if (keypad->keymap[code] != KEY_RESERVED) { keypad->rows |= 1 << row; keypad->cols |= 1 << col; @@ -335,23 +479,34 @@ static int stmpe_keypad_probe(struct platform_device *pdev) input->id.bustype = BUS_I2C; input->dev.parent = &pdev->dev; - error = matrix_keypad_build_keymap(plat->keymap_data, NULL, - STMPE_KEYPAD_MAX_ROWS, - STMPE_KEYPAD_MAX_COLS, - keypad->keymap, input); - if (error) - return error; - input_set_capability(input, EV_MSC, MSC_SCAN); if (!plat->no_autorepeat) __set_bit(EV_REP, input->evbit); - stmpe_keypad_fill_used_pins(keypad); - keypad->stmpe = stmpe; keypad->plat = plat; keypad->input = input; keypad->variant = &stmpe_keypad_variants[stmpe->partnum]; + keypad->keymap = devm_kzalloc(&pdev->dev, + sizeof(keypad->keymap) * keypad->variant->max_rows * + keypad->variant->max_cols, GFP_KERNEL); + if (!keypad->keymap) + return -ENOMEM; + + error = matrix_keypad_build_keymap(plat->keymap_data, NULL, + keypad->variant->max_rows, + keypad->variant->max_cols, + keypad->keymap, input); + if (error) + return error; + + /* + * compute keypad->scan_code_row_shift by figuring out + * how many bits are needed to encode keypad->variant->max_cols + */ + keypad->scan_code_row_shift = + get_count_order(keypad->variant->max_cols); + stmpe_keypad_fill_used_pins(keypad); error = stmpe_keypad_chip_init(keypad); if (error < 0)