All of lore.kernel.org
 help / color / mirror / Atom feed
From: AnilKumar Ch <anilkumar@ti.com>
To: dmitry.torokhov@gmail.com, grant.likely@secretlab.ca
Cc: rob.herring@calxeda.com, dgdunix@gmail.com,
	linux-input@vger.kernel.org, devicetree-discuss@lists.ozlabs.org,
	AnilKumar Ch <anilkumar@ti.com>
Subject: [PATCH v4] Input: matrix-keypad - Add device tree support
Date: Wed, 7 Nov 2012 15:02:05 +0530	[thread overview]
Message-ID: <1352280725-452-1-git-send-email-anilkumar@ti.com> (raw)

Add device tree support to matrix keypad driver and usage details
are added to device tree documentation. Driver was tested on AM335x
EVM.

Signed-off-by: AnilKumar Ch <anilkumar@ti.com>
---
This patch was tested on AM335x-EVM and based on linux-next, cleanly
applies on top of input/next

Changes from v3:
	- Incorporated Stephen Warren's review comments on v3
	  * Added description to clustered-irq-flags binding

Changes from v2:
	- Incorporated Stephen Warren's review comments on v2
	  * Renamed the bindings file to gpio-matrix-keypad.txt
	  * Added description to clustered-irq binding

Changes from v1:
	- Incorporated Rob's review comments on v1
	  * Changed matix-keypad compatible to gpio-matrix-keypad
	  * Removed unnecessary props (num of gpios)
	  * Used of_match_ptr()
	- Removed first patch based on Dmitry's comments on v1

 .../bindings/input/gpio-matrix-keypad.txt          |   52 ++++++++++
 drivers/input/keyboard/matrix_keypad.c             |  107 +++++++++++++++++++-
 2 files changed, 158 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt

diff --git a/Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt b/Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt
new file mode 100644
index 0000000..1acdfc4
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt
@@ -0,0 +1,52 @@
+* GPIO driven matrix keypad device tree bindings
+
+GPIO driven matrix keypad is used to interface a SoC with a matrix keypad.
+The matrix keypad supports multiple row and column lines, a key can be
+placed at each intersection of a unique row and a unique column. The matrix
+keypad can sense a key-press and key-release by means of GPIO lines and
+report the event using GPIO interrupts to the cpu.
+
+Required Properties:
+- compatible:		Should be "gpio-matrix-keypad"
+- row-gpios:		List of gpios used as row lines. The gpio specifier
+			for this property depends on the gpio controller to
+			which these row lines are connected.
+- col-gpios:		List of gpios used as column lines. The gpio specifier
+			for this property depends on the gpio controller to
+			which these column lines are connected.
+- linux,keymap:		The definition can be found at
+			bindings/input/matrix-keymap.txt
+
+Optional Properties:
+- linux,no-autorepeat:	do no enable autorepeat feature.
+- linux,wakeup:		use any event on keypad as wakeup event.
+- debounce-delay-ms:	debounce interval in milliseconds
+- col-scan-delay-us:	delay, measured in microseconds, that is needed
+			before we can scan keypad after activating column gpio
+- clustered-irq:	have clustered irq number, that is needed if the irq
+			is a combined irq source for the whole matrix keypad.
+			This is useful if rows and columns of the keypad are
+			connected to a GPIO expander.
+- clustered-irq-flags:	clustered irq flags to specify the interrupt line
+			behaviour among IRQF_TRIGGER_*
+
+Example:
+	matrix-keypad {
+		compatible = "gpio-matrix-keypad";
+		debounce-delay-ms = <5>;
+		col-scan-delay-us = <2>;
+
+		row-gpios = <&gpio2 25 0
+			     &gpio2 26 0
+			     &gpio2 27 0>;
+
+		col-gpios = <&gpio2 21 0
+			     &gpio2 22 0>;
+
+		linux,keymap = <0x0000008B
+				0x0100009E
+				0x02000069
+				0x0001006A
+				0x0101001C
+				0x0201006C>;
+	};
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index 18b7237..960e9b05 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -23,6 +23,9 @@
 #include <linux/gpio.h>
 #include <linux/input/matrix_keypad.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
 
 struct matrix_keypad {
 	const struct matrix_keypad_platform_data *pdata;
@@ -394,6 +397,96 @@ static void matrix_keypad_free_gpio(struct matrix_keypad *keypad)
 		gpio_free(pdata->col_gpios[i]);
 }
 
+#ifdef CONFIG_OF
+static
+struct matrix_keypad_platform_data *matrix_keypad_parse_dt(struct device *dev)
+{
+	struct matrix_keypad_platform_data *pdata;
+	struct matrix_keymap_data *keymap_data;
+	struct device_node *np = dev->of_node;
+	unsigned int *row_gpios;
+	unsigned int *col_gpios;
+	struct property *prop;
+	int key_count = 0, length, row, col;
+	uint32_t *keymap;
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(dev, "could not allocate memory for platform data\n");
+		return NULL;
+	}
+
+	pdata->num_row_gpios = of_gpio_named_count(np, "row-gpios");
+	pdata->num_col_gpios = of_gpio_named_count(np, "col-gpios");
+	if (!pdata->num_row_gpios || !pdata->num_col_gpios) {
+		dev_err(dev, "number of keypad rows/columns not specified\n");
+		return NULL;
+	}
+
+	keymap_data = devm_kzalloc(dev, sizeof(*keymap_data), GFP_KERNEL);
+	if (!keymap_data) {
+		dev_err(dev, "could not allocate memory for keymap data\n");
+		return NULL;
+	}
+	pdata->keymap_data = keymap_data;
+
+	prop = of_find_property(np, "linux,keymap", &length);
+	if (!prop)
+		return NULL;
+
+	key_count = length / sizeof(u32);
+	keymap_data->keymap_size = key_count;
+	keymap = devm_kzalloc(dev, sizeof(uint32_t) * key_count, GFP_KERNEL);
+	if (!keymap) {
+		dev_err(dev, "could not allocate memory for keymap\n");
+		return NULL;
+	}
+	keymap_data->keymap = keymap;
+
+	of_property_read_u32_array(np, "linux,keymap", keymap, key_count);
+
+	if (of_get_property(np, "linux,no-autorepeat", NULL))
+		pdata->no_autorepeat = true;
+	if (of_get_property(np, "linux,wakeup", NULL))
+		pdata->wakeup = true;
+	if (of_get_property(np, "gpio-activelow", NULL))
+		pdata->active_low = true;
+
+	of_property_read_u32(np, "debounce-delay-ms", &pdata->debounce_ms);
+	of_property_read_u32(np, "col-scan-delay-us",
+						&pdata->col_scan_delay_us);
+	of_property_read_u32(np, "clustered-irq", &pdata->clustered_irq);
+	of_property_read_u32(np, "clustered-irq-flags",
+						&pdata->clustered_irq_flags);
+
+	row_gpios = devm_kzalloc(dev, sizeof(unsigned int) *
+					pdata->num_row_gpios, GFP_KERNEL);
+	col_gpios = devm_kzalloc(dev, sizeof(unsigned int) *
+					pdata->num_col_gpios, GFP_KERNEL);
+	if (!row_gpios || !col_gpios) {
+		dev_err(dev, "could not allocate memory for gpios\n");
+		return NULL;
+	}
+
+	for (row = 0; row < pdata->num_row_gpios; row++)
+		row_gpios[row] = of_get_named_gpio(np, "row-gpios", row);
+
+	for (col = 0; col < pdata->num_col_gpios; col++)
+		col_gpios[col] = of_get_named_gpio(np, "col-gpios", col);
+
+	pdata->row_gpios = row_gpios;
+	pdata->col_gpios = col_gpios;
+
+	return pdata;
+}
+#else
+static
+struct matrix_keypad_platform_data *matrix_keypad_parse_dt(struct device *dev)
+{
+	return NULL;
+}
+#endif
+
 static int __devinit matrix_keypad_probe(struct platform_device *pdev)
 {
 	const struct matrix_keypad_platform_data *pdata;
@@ -404,7 +497,10 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev)
 	size_t keymap_size;
 	int err;
 
-	pdata = pdev->dev.platform_data;
+	if (pdev->dev.of_node)
+		pdata = matrix_keypad_parse_dt(&pdev->dev);
+	else
+		pdata = pdev->dev.platform_data;
 	if (!pdata) {
 		dev_err(&pdev->dev, "no platform data defined\n");
 		return -EINVAL;
@@ -488,6 +584,14 @@ static int __devexit matrix_keypad_remove(struct platform_device *pdev)
 	return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id matrix_keypad_dt_match[] = {
+	{ .compatible = "gpio-matrix-keypad" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, matrix_keypad_dt_match);
+#endif
+
 static struct platform_driver matrix_keypad_driver = {
 	.probe		= matrix_keypad_probe,
 	.remove		= __devexit_p(matrix_keypad_remove),
@@ -495,6 +599,7 @@ static struct platform_driver matrix_keypad_driver = {
 		.name	= "matrix-keypad",
 		.owner	= THIS_MODULE,
 		.pm	= &matrix_keypad_pm_ops,
+		.of_match_table = of_match_ptr(matrix_keypad_dt_match),
 	},
 };
 module_platform_driver(matrix_keypad_driver);
-- 
1.7.9.5


             reply	other threads:[~2012-11-07  9:32 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-11-07  9:32 AnilKumar Ch [this message]
2012-11-07  9:38 ` [PATCH v4] Input: matrix-keypad - Add device tree support AnilKumar, Chimata
2012-11-07 16:57   ` Stephen Warren
2012-11-08  5:23     ` AnilKumar, Chimata
2012-11-08 16:55 ` Stephen Warren
2012-11-09 11:07   ` AnilKumar, Chimata
2012-11-09 17:19     ` Stephen Warren

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=1352280725-452-1-git-send-email-anilkumar@ti.com \
    --to=anilkumar@ti.com \
    --cc=devicetree-discuss@lists.ozlabs.org \
    --cc=dgdunix@gmail.com \
    --cc=dmitry.torokhov@gmail.com \
    --cc=grant.likely@secretlab.ca \
    --cc=linux-input@vger.kernel.org \
    --cc=rob.herring@calxeda.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.