lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1357470900-12619-4-git-send-email-ldewangan@nvidia.com>
Date:	Sun, 6 Jan 2013 16:44:59 +0530
From:	Laxman Dewangan <ldewangan@...dia.com>
To:	<dmitry.torokhov@...il.com>
CC:	<grant.likely@...retlab.ca>, <rob.herring@...xeda.com>,
	<swarren@...dia.com>, <devicetree-discuss@...ts.ozlabs.org>,
	<linux-doc@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
	<linux-input@...r.kernel.org>, <linux-tegra@...r.kernel.org>,
	Laxman Dewangan <ldewangan@...dia.com>
Subject: [PATCH V4 3/4] input: keyboard: tegra: add support for rows/cols configuration from dt

The NVIDIA's Tegra KBC has maximum 24 pins to make matrix keypad.
Any pin can be configured as row or column. The maximum column pin
can be 8 and maximum row pin can be 16.

Remove the assumption that all first 16 pins will be used as row
and remaining as columns and Add the property for configuring pins
to either row or column from DT. Update the devicetree binding
document accordingly.

Signed-off-by: Laxman Dewangan <ldewangan@...dia.com>
---
Changes from V1:
- renames the rows and pins property array.
- nit cleanups.
Changes from V2/V3:
 None

 .../bindings/input/nvidia,tegra20-kbc.txt          |   22 ++++++
 drivers/input/keyboard/tegra-kbc.c                 |   74 +++++++++++++++-----
 2 files changed, 79 insertions(+), 17 deletions(-)

diff --git a/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt b/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt
index 72683be..2995fae 100644
--- a/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt
+++ b/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt
@@ -1,7 +1,18 @@
 * Tegra keyboard controller
+The key controller has maximum 24 pins to make matrix keypad. Any pin
+can be configured as row or column. The maximum column pin can be 8
+and maximum row pins can be 16 for Tegra20/Tegra30.
 
 Required properties:
 - compatible: "nvidia,tegra20-kbc"
+- reg: Register base address of KBC.
+- interrupts: Interrupt number for the KBC.
+- nvidia,kbc-row-pins: The KBC pins which are configured as row. This is an
+  array of pin numbers which is used as rows.
+- nvidia,kbc-col-pins: The KBC pins which are configured as column. This is an
+  array of pin numbers which is used as column.
+- linux,keymap: The keymap for keys as described in the binding document
+  devicetree/bindings/input/matrix-keymap.txt.
 
 Optional properties, in addition to those specified by the shared
 matrix-keyboard bindings:
@@ -19,5 +30,16 @@ Example:
 keyboard: keyboard {
 	compatible = "nvidia,tegra20-kbc";
 	reg = <0x7000e200 0x100>;
+	interrupts = <0 85 0x04>;
 	nvidia,ghost-filter;
+	nvidia,debounce-delay-ms = <640>;
+	nvidia,kbc-row-pins = <0 1 2>;    /* pin 0, 1, 2 as rows */
+	nvidia,kbc-col-pins = <11 12 13>; /* pin 11, 12, 13 as columns */
+	linux,keymap = <0x00000074
+			0x00010067
+			0x00020066
+			0x01010068
+			0x02000069
+			0x02010070
+			0x02020071>;
 };
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c
index f799936..509afd4 100644
--- a/drivers/input/keyboard/tegra-kbc.c
+++ b/drivers/input/keyboard/tegra-kbc.c
@@ -614,13 +614,16 @@ static struct tegra_kbc_platform_data *tegra_kbc_dt_parse_pdata(
 	struct device_node *np = pdev->dev.of_node;
 	u32 prop;
 	int i;
-
-	if (!np)
-		return NULL;
+	u32 num_rows = 0;
+	u32 num_cols = 0;
+	u32 cols_cfg[KBC_MAX_GPIO];
+	u32 rows_cfg[KBC_MAX_GPIO];
+	int proplen;
+	int ret;
 
 	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	if (!of_property_read_u32(np, "nvidia,debounce-delay-ms", &prop))
 		pdata->debounce_cnt = prop;
@@ -634,18 +637,55 @@ static struct tegra_kbc_platform_data *tegra_kbc_dt_parse_pdata(
 	if (of_find_property(np, "nvidia,wakeup-source", NULL))
 		pdata->wakeup = true;
 
-	/*
-	 * All currently known keymaps with device tree support use the same
-	 * pin_cfg, so set it up here.
-	 */
-	for (i = 0; i < KBC_MAX_ROW; i++) {
-		pdata->pin_cfg[i].num = i;
-		pdata->pin_cfg[i].type = PIN_CFG_ROW;
+	if (!of_get_property(np, "nvidia,kbc-row-pins", &proplen)) {
+		dev_err(&pdev->dev, "property nvidia,kbc-row-pins not found\n");
+		return ERR_PTR(-ENOENT);
+	}
+	num_rows = proplen / sizeof(u32);
+
+	if (!of_get_property(np, "nvidia,kbc-col-pins", &proplen)) {
+		dev_err(&pdev->dev, "property nvidia,kbc-col-pins not found\n");
+		return ERR_PTR(-ENOENT);
+	}
+	num_cols = proplen / sizeof(u32);
+
+	if (!of_get_property(np, "linux,keymap", &proplen)) {
+		dev_err(&pdev->dev, "property linux,keymap not found\n");
+		return ERR_PTR(-ENOENT);
+	}
+
+	if (!num_rows || !num_cols || ((num_rows + num_cols) > KBC_MAX_GPIO)) {
+		dev_err(&pdev->dev,
+			"keypad rows/columns not porperly specified\n");
+		return ERR_PTR(-EINVAL);
 	}
 
-	for (i = 0; i < KBC_MAX_COL; i++) {
-		pdata->pin_cfg[KBC_MAX_ROW + i].num = i;
-		pdata->pin_cfg[KBC_MAX_ROW + i].type = PIN_CFG_COL;
+	/* Set all pins as non-configured */
+	for (i = 0; i < KBC_MAX_GPIO; i++)
+		pdata->pin_cfg[i].type = PIN_CFG_IGNORE;
+
+	ret = of_property_read_u32_array(np, "nvidia,kbc-row-pins",
+				rows_cfg, num_rows);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Rows configurations are not proper\n");
+		return ERR_PTR(-ENOENT);
+	}
+
+	ret = of_property_read_u32_array(np, "nvidia,kbc-col-pins",
+				cols_cfg, num_cols);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Cols configurations are not proper\n");
+		return ERR_PTR(-ENOENT);
+	}
+
+	for (i = 0; i < num_rows; i++) {
+		pdata->pin_cfg[rows_cfg[i]].type = PIN_CFG_ROW;
+		pdata->pin_cfg[rows_cfg[i]].num = i;
+	}
+
+	for (i = 0; i < num_cols; i++) {
+		pdata->pin_cfg[cols_cfg[i]].type = PIN_CFG_COL;
+		pdata->pin_cfg[cols_cfg[i]].num = i;
 	}
 
 	return pdata;
@@ -697,12 +737,12 @@ static int tegra_kbc_probe(struct platform_device *pdev)
 	unsigned int debounce_cnt;
 	unsigned int scan_time_rows;
 
-	if (!pdata)
+	if (!pdata && pdev->dev.of_node)
 		pdata = tegra_kbc_dt_parse_pdata(pdev);
 
-	if (!pdata) {
+	if (IS_ERR_OR_NULL(pdata)) {
 		dev_err(&pdev->dev, "Platform data missing\n");
-		return -EINVAL;
+		return pdata ? PTR_ERR(pdata) : -EINVAL;
 	}
 
 	if (!tegra_kbc_check_pin_cfg(pdata, &pdev->dev, &num_rows))
-- 
1.7.1.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ