All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sergey Larin <cerg2010cerg2010@mail.ru>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>,
	Maxime Coquelin <mcoquelin.stm32@gmail.com>,
	Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: linux-input@vger.kernel.org,
	linux-stm32@st-md-mailman.stormreply.com,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org,
	Sergey Larin <cerg2010cerg2010@mail.ru>
Subject: [PATCH] Input: stmpe-keypad - add STMPE1801 support
Date: Fri, 18 Jun 2021 17:51:49 +0300	[thread overview]
Message-ID: <20210618145149.10136-1-cerg2010cerg2010@mail.ru> (raw)

This chip variant differs from others - it has different register
map and swapped rows/columns.

Signed-off-by: Sergey Larin <cerg2010cerg2010@mail.ru>
---
 drivers/input/keyboard/stmpe-keypad.c | 108 ++++++++++++++++++++------
 1 file changed, 85 insertions(+), 23 deletions(-)

diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c
index 7bf97285e30c..ed74578927a3 100644
--- a/drivers/input/keyboard/stmpe-keypad.c
+++ b/drivers/input/keyboard/stmpe-keypad.c
@@ -13,7 +13,7 @@
 #include <linux/input/matrix_keypad.h>
 #include <linux/mfd/stmpe.h>
 
-/* These are at the same addresses in all STMPE variants */
+/* These are at the same addresses in all STMPE variants, except 1801 */
 #define STMPE_KPC_COL			0x60
 #define STMPE_KPC_ROW_MSB		0x61
 #define STMPE_KPC_ROW_LSB		0x62
@@ -42,14 +42,15 @@
 #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_MAX_ROWS		10
+#define STMPE_KEYPAD_MAX_COLS		12
 #define STMPE_KEYPAD_ROW_SHIFT		3
 #define STMPE_KEYPAD_KEYMAP_MAX_SIZE \
 	(STMPE_KEYPAD_MAX_ROWS * STMPE_KEYPAD_MAX_COLS)
 
 
 #define STMPE1601_NUM_DATA	5
+#define STMPE1801_NUM_DATA	5
 #define STMPE2401_NUM_DATA	3
 #define STMPE2403_NUM_DATA	5
 
@@ -67,6 +68,12 @@
  * @max_rows: maximum number of rows supported
  * @col_gpios: bitmask of gpios which can be used for columns
  * @row_gpios: bitmask of gpios which can be used for rows
+ * @col_regs: registers for setting column pins
+ * @row_regs: registers for setting row pins
+ * @data_regs: registers for reading key data
+ * @ctrl_msb_reg: register for setting scan count
+ * @ctrl_lsb_reg: register for setting debounce time
+ * @cmd_reg: register for toggling scan mode
  */
 struct stmpe_keypad_variant {
 	bool		auto_increment;
@@ -77,6 +84,18 @@ struct stmpe_keypad_variant {
 	int		max_rows;
 	unsigned int	col_gpios;
 	unsigned int	row_gpios;
+
+#define MAX_COL_REGS 3
+#define MAX_ROW_REGS 3
+#define MAX_DATA_REGS 5
+
+	u8 col_regs[MAX_COL_REGS];
+	u8 row_regs[MAX_ROW_REGS];
+	u8 data_regs[MAX_DATA_REGS];
+	u8 ctrl_msb_reg;
+	u8 ctrl_lsb_reg;
+	u8 cmd_reg;
+	bool read_inverted;
 };
 
 static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
@@ -88,6 +107,29 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
 		.max_rows		= 8,
 		.col_gpios		= 0x000ff,	/* GPIO 0 - 7 */
 		.row_gpios		= 0x0ff00,	/* GPIO 8 - 15 */
+		.col_regs		= { 0x60 },
+		.row_regs		= { 0x62, 0x61 },
+		.data_regs		= { 0x68, 0x69, 0x6a, 0x6b, 0x6c },
+		.ctrl_msb_reg		= 0x63,
+		.ctrl_lsb_reg		= 0x64,
+		.cmd_reg		= 0x64,
+		.read_inverted		= 0,
+	},
+	[STMPE1801] = {
+		.auto_increment		= true,
+		.num_data		= STMPE1801_NUM_DATA,
+		.num_normal_data	= 3,
+		.max_cols		= 10,
+		.max_rows		= 8,
+		.col_gpios		= 0x3ff00,	/* GPIO 8 - 17 */
+		.row_gpios		= 0x000ff,	/* GPIO 0 - 7 */
+		.col_regs		= { 0x31, 0x32 },
+		.row_regs		= { 0x30 },
+		.data_regs		= { 0x3a, 0x3b, 0x3c, 0x3d, 0x3e },
+		.ctrl_msb_reg		= 0x33,
+		.ctrl_lsb_reg		= 0x34,
+		.cmd_reg		= 0x36,
+		.read_inverted		= 1,
 	},
 	[STMPE2401] = {
 		.auto_increment		= false,
@@ -98,6 +140,13 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
 		.max_rows		= 12,
 		.col_gpios		= 0x0000ff,	/* GPIO 0 - 7*/
 		.row_gpios		= 0x1f7f00,	/* GPIO 8-14, 16-20 */
+		.col_regs		= { 0x60 },
+		.row_regs		= { 0x62, 0x61 },
+		.data_regs		= { 0x68, 0x69, 0x6a, 0x6b, 0x6c },
+		.ctrl_msb_reg		= 0x63,
+		.ctrl_lsb_reg		= 0x64,
+		.cmd_reg		= 0x64,
+		.read_inverted		= 0,
 	},
 	[STMPE2403] = {
 		.auto_increment		= true,
@@ -108,6 +157,13 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
 		.max_rows		= 12,
 		.col_gpios		= 0x0000ff,	/* GPIO 0 - 7*/
 		.row_gpios		= 0x1fef00,	/* GPIO 8-14, 16-20 */
+		.col_regs		= { 0x60 },
+		.row_regs		= { 0x62, 0x61 },
+		.data_regs		= { 0x68, 0x69, 0x6a, 0x6b, 0x6c },
+		.ctrl_msb_reg		= 0x63,
+		.ctrl_lsb_reg		= 0x64,
+		.cmd_reg		= 0x64,
+		.read_inverted		= 0,
 	},
 };
 
@@ -145,11 +201,11 @@ 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,
+		return stmpe_block_read(stmpe, variant->data_regs[0],
 					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->data_regs[i]);
 		if (ret < 0)
 			return ret;
 
@@ -176,7 +232,9 @@ static irqreturn_t stmpe_keypad_irq(int irq, void *dev)
 		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 code = variant->read_inverted ?
+			  MATRIX_SCAN_CODE(col, row, STMPE_KEYPAD_ROW_SHIFT)
+			: MATRIX_SCAN_CODE(row, col, STMPE_KEYPAD_ROW_SHIFT);
 		bool up = data & STMPE_KPC_DATA_UP;
 
 		if ((data & STMPE_KPC_DATA_NOKEY_MASK)
@@ -265,7 +323,7 @@ static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad)
 {
 	const struct stmpe_keypad_variant *variant = keypad->variant;
 	struct stmpe *stmpe = keypad->stmpe;
-	int ret;
+	int ret, val, i;
 
 	if (keypad->debounce_ms > STMPE_KEYPAD_MAX_DEBOUNCE)
 		return -EINVAL;
@@ -281,33 +339,37 @@ 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);
-	if (ret < 0)
-		return ret;
-
-	ret = stmpe_reg_write(stmpe, STMPE_KPC_ROW_LSB, keypad->rows);
-	if (ret < 0)
-		return ret;
+	val = keypad->cols;
+	i = 0;
+	do {
+		ret = stmpe_reg_write(stmpe, variant->col_regs[i++], val & 0xff);
+		if (ret < 0)
+			return ret;
+	} while ((val >>= 8) != 0);
 
-	if (variant->max_rows > 8) {
-		ret = stmpe_set_bits(stmpe, STMPE_KPC_ROW_MSB,
-				     STMPE_KPC_ROW_MSB_ROWS,
-				     keypad->rows >> 8);
+	val = keypad->rows;
+	i = 0;
+	do {
+		ret = stmpe_reg_write(stmpe, variant->row_regs[i++], val & 0xff);
 		if (ret < 0)
 			return ret;
-	}
+	} while ((val >>= 8) != 0);
 
-	ret = stmpe_set_bits(stmpe, STMPE_KPC_CTRL_MSB,
+	ret = stmpe_set_bits(stmpe, variant->ctrl_msb_reg,
 			     STMPE_KPC_CTRL_MSB_SCAN_COUNT,
 			     keypad->scan_count << 4);
 	if (ret < 0)
 		return ret;
 
-	return stmpe_set_bits(stmpe, STMPE_KPC_CTRL_LSB,
-			      STMPE_KPC_CTRL_LSB_SCAN |
+	ret = stmpe_set_bits(stmpe, variant->ctrl_lsb_reg,
 			      STMPE_KPC_CTRL_LSB_DEBOUNCE,
-			      STMPE_KPC_CTRL_LSB_SCAN |
 			      (keypad->debounce_ms << 1));
+	if (ret < 0)
+		return ret;
+
+	return stmpe_set_bits(stmpe, variant->cmd_reg,
+			      STMPE_KPC_CTRL_LSB_SCAN,
+			      STMPE_KPC_CTRL_LSB_SCAN);
 }
 
 static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad,
-- 
2.32.0


WARNING: multiple messages have this Message-ID (diff)
From: Sergey Larin <cerg2010cerg2010@mail.ru>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>,
	Maxime Coquelin <mcoquelin.stm32@gmail.com>,
	Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: linux-input@vger.kernel.org,
	linux-stm32@st-md-mailman.stormreply.com,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org,
	Sergey Larin <cerg2010cerg2010@mail.ru>
Subject: [PATCH] Input: stmpe-keypad - add STMPE1801 support
Date: Fri, 18 Jun 2021 17:51:49 +0300	[thread overview]
Message-ID: <20210618145149.10136-1-cerg2010cerg2010@mail.ru> (raw)

This chip variant differs from others - it has different register
map and swapped rows/columns.

Signed-off-by: Sergey Larin <cerg2010cerg2010@mail.ru>
---
 drivers/input/keyboard/stmpe-keypad.c | 108 ++++++++++++++++++++------
 1 file changed, 85 insertions(+), 23 deletions(-)

diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c
index 7bf97285e30c..ed74578927a3 100644
--- a/drivers/input/keyboard/stmpe-keypad.c
+++ b/drivers/input/keyboard/stmpe-keypad.c
@@ -13,7 +13,7 @@
 #include <linux/input/matrix_keypad.h>
 #include <linux/mfd/stmpe.h>
 
-/* These are at the same addresses in all STMPE variants */
+/* These are at the same addresses in all STMPE variants, except 1801 */
 #define STMPE_KPC_COL			0x60
 #define STMPE_KPC_ROW_MSB		0x61
 #define STMPE_KPC_ROW_LSB		0x62
@@ -42,14 +42,15 @@
 #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_MAX_ROWS		10
+#define STMPE_KEYPAD_MAX_COLS		12
 #define STMPE_KEYPAD_ROW_SHIFT		3
 #define STMPE_KEYPAD_KEYMAP_MAX_SIZE \
 	(STMPE_KEYPAD_MAX_ROWS * STMPE_KEYPAD_MAX_COLS)
 
 
 #define STMPE1601_NUM_DATA	5
+#define STMPE1801_NUM_DATA	5
 #define STMPE2401_NUM_DATA	3
 #define STMPE2403_NUM_DATA	5
 
@@ -67,6 +68,12 @@
  * @max_rows: maximum number of rows supported
  * @col_gpios: bitmask of gpios which can be used for columns
  * @row_gpios: bitmask of gpios which can be used for rows
+ * @col_regs: registers for setting column pins
+ * @row_regs: registers for setting row pins
+ * @data_regs: registers for reading key data
+ * @ctrl_msb_reg: register for setting scan count
+ * @ctrl_lsb_reg: register for setting debounce time
+ * @cmd_reg: register for toggling scan mode
  */
 struct stmpe_keypad_variant {
 	bool		auto_increment;
@@ -77,6 +84,18 @@ struct stmpe_keypad_variant {
 	int		max_rows;
 	unsigned int	col_gpios;
 	unsigned int	row_gpios;
+
+#define MAX_COL_REGS 3
+#define MAX_ROW_REGS 3
+#define MAX_DATA_REGS 5
+
+	u8 col_regs[MAX_COL_REGS];
+	u8 row_regs[MAX_ROW_REGS];
+	u8 data_regs[MAX_DATA_REGS];
+	u8 ctrl_msb_reg;
+	u8 ctrl_lsb_reg;
+	u8 cmd_reg;
+	bool read_inverted;
 };
 
 static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
@@ -88,6 +107,29 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
 		.max_rows		= 8,
 		.col_gpios		= 0x000ff,	/* GPIO 0 - 7 */
 		.row_gpios		= 0x0ff00,	/* GPIO 8 - 15 */
+		.col_regs		= { 0x60 },
+		.row_regs		= { 0x62, 0x61 },
+		.data_regs		= { 0x68, 0x69, 0x6a, 0x6b, 0x6c },
+		.ctrl_msb_reg		= 0x63,
+		.ctrl_lsb_reg		= 0x64,
+		.cmd_reg		= 0x64,
+		.read_inverted		= 0,
+	},
+	[STMPE1801] = {
+		.auto_increment		= true,
+		.num_data		= STMPE1801_NUM_DATA,
+		.num_normal_data	= 3,
+		.max_cols		= 10,
+		.max_rows		= 8,
+		.col_gpios		= 0x3ff00,	/* GPIO 8 - 17 */
+		.row_gpios		= 0x000ff,	/* GPIO 0 - 7 */
+		.col_regs		= { 0x31, 0x32 },
+		.row_regs		= { 0x30 },
+		.data_regs		= { 0x3a, 0x3b, 0x3c, 0x3d, 0x3e },
+		.ctrl_msb_reg		= 0x33,
+		.ctrl_lsb_reg		= 0x34,
+		.cmd_reg		= 0x36,
+		.read_inverted		= 1,
 	},
 	[STMPE2401] = {
 		.auto_increment		= false,
@@ -98,6 +140,13 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
 		.max_rows		= 12,
 		.col_gpios		= 0x0000ff,	/* GPIO 0 - 7*/
 		.row_gpios		= 0x1f7f00,	/* GPIO 8-14, 16-20 */
+		.col_regs		= { 0x60 },
+		.row_regs		= { 0x62, 0x61 },
+		.data_regs		= { 0x68, 0x69, 0x6a, 0x6b, 0x6c },
+		.ctrl_msb_reg		= 0x63,
+		.ctrl_lsb_reg		= 0x64,
+		.cmd_reg		= 0x64,
+		.read_inverted		= 0,
 	},
 	[STMPE2403] = {
 		.auto_increment		= true,
@@ -108,6 +157,13 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
 		.max_rows		= 12,
 		.col_gpios		= 0x0000ff,	/* GPIO 0 - 7*/
 		.row_gpios		= 0x1fef00,	/* GPIO 8-14, 16-20 */
+		.col_regs		= { 0x60 },
+		.row_regs		= { 0x62, 0x61 },
+		.data_regs		= { 0x68, 0x69, 0x6a, 0x6b, 0x6c },
+		.ctrl_msb_reg		= 0x63,
+		.ctrl_lsb_reg		= 0x64,
+		.cmd_reg		= 0x64,
+		.read_inverted		= 0,
 	},
 };
 
@@ -145,11 +201,11 @@ 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,
+		return stmpe_block_read(stmpe, variant->data_regs[0],
 					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->data_regs[i]);
 		if (ret < 0)
 			return ret;
 
@@ -176,7 +232,9 @@ static irqreturn_t stmpe_keypad_irq(int irq, void *dev)
 		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 code = variant->read_inverted ?
+			  MATRIX_SCAN_CODE(col, row, STMPE_KEYPAD_ROW_SHIFT)
+			: MATRIX_SCAN_CODE(row, col, STMPE_KEYPAD_ROW_SHIFT);
 		bool up = data & STMPE_KPC_DATA_UP;
 
 		if ((data & STMPE_KPC_DATA_NOKEY_MASK)
@@ -265,7 +323,7 @@ static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad)
 {
 	const struct stmpe_keypad_variant *variant = keypad->variant;
 	struct stmpe *stmpe = keypad->stmpe;
-	int ret;
+	int ret, val, i;
 
 	if (keypad->debounce_ms > STMPE_KEYPAD_MAX_DEBOUNCE)
 		return -EINVAL;
@@ -281,33 +339,37 @@ 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);
-	if (ret < 0)
-		return ret;
-
-	ret = stmpe_reg_write(stmpe, STMPE_KPC_ROW_LSB, keypad->rows);
-	if (ret < 0)
-		return ret;
+	val = keypad->cols;
+	i = 0;
+	do {
+		ret = stmpe_reg_write(stmpe, variant->col_regs[i++], val & 0xff);
+		if (ret < 0)
+			return ret;
+	} while ((val >>= 8) != 0);
 
-	if (variant->max_rows > 8) {
-		ret = stmpe_set_bits(stmpe, STMPE_KPC_ROW_MSB,
-				     STMPE_KPC_ROW_MSB_ROWS,
-				     keypad->rows >> 8);
+	val = keypad->rows;
+	i = 0;
+	do {
+		ret = stmpe_reg_write(stmpe, variant->row_regs[i++], val & 0xff);
 		if (ret < 0)
 			return ret;
-	}
+	} while ((val >>= 8) != 0);
 
-	ret = stmpe_set_bits(stmpe, STMPE_KPC_CTRL_MSB,
+	ret = stmpe_set_bits(stmpe, variant->ctrl_msb_reg,
 			     STMPE_KPC_CTRL_MSB_SCAN_COUNT,
 			     keypad->scan_count << 4);
 	if (ret < 0)
 		return ret;
 
-	return stmpe_set_bits(stmpe, STMPE_KPC_CTRL_LSB,
-			      STMPE_KPC_CTRL_LSB_SCAN |
+	ret = stmpe_set_bits(stmpe, variant->ctrl_lsb_reg,
 			      STMPE_KPC_CTRL_LSB_DEBOUNCE,
-			      STMPE_KPC_CTRL_LSB_SCAN |
 			      (keypad->debounce_ms << 1));
+	if (ret < 0)
+		return ret;
+
+	return stmpe_set_bits(stmpe, variant->cmd_reg,
+			      STMPE_KPC_CTRL_LSB_SCAN,
+			      STMPE_KPC_CTRL_LSB_SCAN);
 }
 
 static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad,
-- 
2.32.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

             reply	other threads:[~2021-06-18 14:52 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-18 14:51 Sergey Larin [this message]
2021-06-18 14:51 ` [PATCH] Input: stmpe-keypad - add STMPE1801 support Sergey Larin
2021-06-21  5:30 ` Dmitry Torokhov
2021-06-21  5:30   ` Dmitry Torokhov
2021-06-23  0:05   ` Sergey Larin
2021-06-23  0:05     ` Sergey Larin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210618145149.10136-1-cerg2010cerg2010@mail.ru \
    --to=cerg2010cerg2010@mail.ru \
    --cc=alexandre.torgue@foss.st.com \
    --cc=dmitry.torokhov@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-stm32@st-md-mailman.stormreply.com \
    --cc=mcoquelin.stm32@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.