Re: [PATCH V3 2/2] drivers: input: keyboard: add mtk keypad driver

Started by Dmitry Torokhov on Jan 22, 2020

open the first message on its own page

Message details and related content
Hi Fendping,

On Tue, Jan 14, 2020 at 08:27:41PM +0800, fengping.yu wrote:
quoted hunk
Signed-off-by: fengping.yu <redacted>

Add matrix keypad driver for MTK SoC.

---
 arch/arm64/configs/defconfig     |   1 +
 drivers/input/keyboard/Kconfig   |   8 +
 drivers/input/keyboard/Makefile  |   1 +
 drivers/input/keyboard/mtk-kpd.c | 280 +++++++++++++++++++++++++++++++
 4 files changed, 290 insertions(+)
 create mode 100644 drivers/input/keyboard/mtk-kpd.c
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 8e05c39eab08..62bed77ec127 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -315,6 +315,7 @@ CONFIG_KEYBOARD_ADC=m
 CONFIG_KEYBOARD_GPIO=y
 CONFIG_KEYBOARD_SNVS_PWRKEY=m
 CONFIG_KEYBOARD_CROS_EC=y
+CONFIG_KEYBOARD_MTK=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=m
 CONFIG_INPUT_MISC=y
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 8911bc2ec42a..01747a97536b 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -775,4 +775,12 @@ config KEYBOARD_MTK_PMIC
 	  To compile this driver as a module, choose M here: the
 	  module will be called pmic-keys.
 
+config KEYBOARD_MTK
+	tristate "MediaTek Keypad Support"
+	help
+	  Say Y here if you want to use the keypad.
+	  If unuse, say N.
+	  To compile this driver as a module, choose M here: the
+	  module will be called mtk-kpd.
+
 endif
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 9510325c0c5d..daa654bcce6e 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_KEYBOARD_MATRIX)		+= matrix_keypad.o
 obj-$(CONFIG_KEYBOARD_MAX7359)		+= max7359_keypad.o
 obj-$(CONFIG_KEYBOARD_MCS)		+= mcs_touchkey.o
 obj-$(CONFIG_KEYBOARD_MPR121)		+= mpr121_touchkey.o
+obj-$(CONFIG_KEYBOARD_MTK) 		+= mtk-kpd.o
 obj-$(CONFIG_KEYBOARD_MTK_PMIC) 	+= mtk-pmic-keys.o
 obj-$(CONFIG_KEYBOARD_NEWTON)		+= newtonkbd.o
 obj-$(CONFIG_KEYBOARD_NOMADIK)		+= nomadik-ske-keypad.o
diff --git a/drivers/input/keyboard/mtk-kpd.c b/drivers/input/keyboard/mtk-kpd.c
new file mode 100644
index 000000000000..e36461c9dd89
--- /dev/null
+++ b/drivers/input/keyboard/mtk-kpd.c
@@ -0,0 +1,280 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 MediaTek Inc.
+ * Author Terry Chang <terry.chang@mediatek.com>
+ */
+#include <linux/clk.h>
+#include <linux/fs.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define KPD_NAME	"mtk-kpd"
+
+#define KP_STA				0x0000
+#define KP_MEM1				0x0004
+#define KP_MEM2				0x0008
+#define KP_MEM3				0x000c
+#define KP_MEM4				0x0010
+#define KP_MEM5				0x0014
+#define KP_DEBOUNCE			0x0018
+#define KP_SEL				0x0020
+#define KP_EN				0x0024
+
+#define KP_COL0_SEL		BIT(10)
+#define KP_COL1_SEL		BIT(11)
+#define KP_COL2_SEL		BIT(12)
+
+#define KPD_DEBOUNCE_MASK	GENMASK_ULL(13, 0)
+
+#define KPD_NUM_MEMS	5
+#define KPD_MEM5_BITS	8
+#define KPD_NUM_KEYS	72	/* 4 * 16 + KPD_MEM5_BITS */
+
+struct mtk_keypad {
+	struct input_dev *input_dev;
+	struct clk *clk;
+	void __iomem *base;
+	unsigned int irqnr;
+	bool wakeup;
+	u32 key_debounce;
+	u32 n_rows;
+	u32 n_cols;
+	u32 keymap_state[KPD_NUM_MEMS];
	DECLARE_BITMAP(keymap_state, KPD_NUM_KEYS);
quoted hunk
+};
+
+static void kpd_get_keymap_state(void __iomem *kp_base, u32 state[])
+{
+	memset_io(state, 0xff, KPD_NUM_MEMS);
+	memcpy_fromio(state, kp_base, KPD_NUM_MEMS);
+}
+
+static irqreturn_t kpd_irq_handler(int irq, void *dev_id)
+{
+	/* use _nosync to avoid deadlock */
+	struct mtk_keypad *keypad = dev_id;
+	unsigned short *keycode = keypad->input_dev->keycode;
+	u32 new_state[KPD_NUM_MEMS], mask;
	DECLARE_BITMAP(new_state, KPD_NUM_KEYS);
	DECLARE_BITMAP(changed_state, KPD_NUM_KEYS);
quoted hunk
+	unsigned long change = 0;
+	int bit_nr;
+	int pressed;
+	u32 row_shift = get_count_order(keypad->n_cols);
+	unsigned short code;
+	int i;
+
+	disable_irq_nosync(keypad->irqnr);
Not needed.

+
+	kpd_get_keymap_state(keypad->base, new_state);
	bitmap_xor(changed_state, keypad->keymap_state, new_state,
		   KPD_NUM_KEYS);

	for_each_set_bit(bit_nr, changed_state, KPD_NUM_KEYS) {
		pressed = test_bit(new_state, bit_nr);

		...
	}
quoted hunk
+
+	for (i = 0; i < KPD_NUM_MEMS; i++) {
+		change = new_state[i] ^ keypad->keymap_state[i];
+		if (!change)
+			continue;
+
+		for_each_set_bit(bit_nr, &change, 32) {
+			mask = 1 << bit_nr;
+			pressed = (new_state[i] & mask) == 0U;
+			dev_dbg(&keypad->input_dev->dev,
+				"%s", pressed ? "pressed" : "released");
+
+			code = keycode[MATRIX_SCAN_CODE(i, bit_nr, row_shift)];
+
+			input_report_key(keypad->input_dev, code, pressed);
+			input_sync(keypad->input_dev);
+
+			dev_dbg(&keypad->input_dev->dev,
+				"report Linux keycode = %d\n", code);
+		}
+	}
+
+	memcpy(keypad->keymap_state, new_state, sizeof(new_state));
	bitmap_copy(keypad->keymap_state, new_state, KPD_NUM_KEYS);
+
+	enable_irq(keypad->irqnr);
Not needed.
quoted hunk
+
+	return IRQ_HANDLED;
+}
+
+static int kpd_get_dts_info(struct mtk_keypad *keypad)
+{
+	int ret;
+	struct device *dev = keypad->input_dev->dev.parent;
+	struct device_node *node = dev->of_node;
+
+	ret = matrix_keypad_parse_properties(dev, &keypad->n_rows,
+					     &keypad->n_cols);
+
+	if (ret) {
+		dev_err(dev, "failed to parse keypad params.\n");
+		return ret;
+	}
+
+	ret = of_property_read_u32(node, "mediatek,debounce-us",
+				   &keypad->key_debounce);
Please use device_property_read_*() APIs instead of of_ ones.

Thanks.

-- 
Dmitry
Keyboard shortcuts
hback out one level
jnext message in thread / next series-diff position
kprevious message in thread / previous series-diff position
ldrill in
Escclose help / fold thread tree
?toggle this help