linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Gerhard Sittig <gsi@denx.de>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>,
	linux-input@vger.kernel.org, devicetree-discuss@lists.ozlabs.org,
	linux-arm-kernel@lists.infradead.org,
	Chao Xie <xiechao.mail@gmail.com>
Cc: Arnd Bergmann <arnd@arndb.de>, Sekhar Nori <nsekhar@ti.com>,
	Tony Lindgren <tony@atomide.com>,
	Marek Vasut <marek.vasut@gmail.com>,
	Eric Miao <eric.y.miao@gmail.com>,
	Haojian Zhuang <haojian.zhuang@gmail.com>,
	Ralf Baechle <ralf@linux-mips.org>,
	Anatolij Gustschin <agust@denx.de>, Detlev Zundel <dzu@denx.de>,
	Gerhard Sittig <gsi@denx.de>
Subject: [PATCH v1 09/12] input: matrix-keypad: add binary column encoding
Date: Fri, 21 Jun 2013 20:09:55 +0200	[thread overview]
Message-ID: <1371838198-7327-10-git-send-email-gsi@denx.de> (raw)
In-Reply-To: <1371838198-7327-1-git-send-email-gsi@denx.de>

introduce support to optionally run a binary column address bit pattern
on column GPIO pins in contrast to the formerly assumed one-out-of-N approach

Signed-off-by: Gerhard Sittig <gsi@denx.de>
---
 .../bindings/input/gpio-matrix-keypad.txt          |   46 ++++++++++++++++++--
 drivers/input/keyboard/matrix_keypad.c             |   39 ++++++++++++++++-
 include/linux/input/matrix_keypad.h                |    3 ++
 3 files changed, 83 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt b/Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt
index f72d262..75e9e28 100644
--- a/Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt
+++ b/Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt
@@ -57,6 +57,18 @@ information can override the keypad matrix dimension data, e.g. when not
 all of the potentially available physical connections are used to create
 the logical keypad matrix.
 
+The driver assumes that each row and column line of the keypad matrix is
+connected to a specific GPIO pin.  Alternatively column addresses can get
+encoded in binary form to reduce the number of GPIO pins involved, at the
+cost of adding an external decoder which translates the binary pattern of N
+GPIO coloumn pins into one of 2**N column lines of the matrix.  A mere
+circuit of two inverting open collector drivers in series connected to one
+output pin is a special case of this generic decoder approach.  Such a
+decoder may be desirable since it's cheap and protects the SoC from damage
+by unwanted interaction of signals when any combination of multiple keys
+gets pressed, regardless of the software's operating the column GPIO pins.
+The row GPIO pins won't interfere either since they all are inputs.
+
 Required Properties:
 - compatible:		Should be "gpio-matrix-keypad"
 - row-gpios:		List of gpios used as row lines. The gpio specifier
@@ -96,16 +108,21 @@ Optional Properties:
 			behaviour is to actively drive low signals and
 			be passive otherwise (emulates an open collector
 			output driver)
+- col-gpios-binary:	boolean, switches from the 'one GPIO pin for each
+			column' approach to the 'n GPIO pins to address
+			2**n columns' approach (binary encoding of column
+			addresses in contrast to a one-out-of-many pattern
+			for the column GPIO pins)
 - keypad,num-rows:	number of rows in the keypad matrix, overrides the
 			value which gets derived from the number of row
 			GPIO pins, useful when not all lines are in use for
 			interconnects
 - keypad,num-columns:	number of columns in the keypad matrix, overrides
 			the value which gets derived from the number of
-			column GPIO pins, useful when not all lines are in
-			use for interconnects
+			column GPIO pins and their optional encoding, useful
+			when not all lines are in use for interconnects
 
-Example:
+Examples:
 	matrix-keypad {
 		compatible = "gpio-matrix-keypad";
 		debounce-delay-ms = <5>;
@@ -125,3 +142,26 @@ Example:
 				0x0101001C
 				0x0201006C>;
 	};
+
+	matrix_keypad {
+		compatible = "gpio-matrix-keypad";
+		debounce-delay-ms = <5>;
+		col-scan-delay-us = <1>;
+		col-switch-delay-ms = <20>;
+
+		col-gpios-binary;
+		col-gpios-pushpull;
+		col-gpios = <&gpio_pic 1 0>;
+
+		row-gpios-activelow;
+		row-gpios = <&gpio_pic 2 0
+			     &gpio_pic 3 0
+			     &gpio_pic 4 0>;
+
+		linux,keymap = <0x0000006e
+				0x01000067
+				0x02000066
+				0x00010069
+				0x0101006c
+				0x0201006a>;
+	}
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index 30b7faf..c015f0d 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -47,7 +47,9 @@ struct matrix_keypad {
 /*
  * this routine controls a physical column pin which the keypad matrix
  * is connected to, and takes care of the pin's polarity as well as its
- * mode of operation (fully driven push/pull, or emulated open drain)
+ * mode of operation (fully driven push/pull, or emulated open drain),
+ * optional encoding of column address information is taken care of by
+ * the caller
  *
  * former comment before introduction of optional push/pull behaviour:
  * <cite>
@@ -88,13 +90,30 @@ static void __activate_col_pin(const struct matrix_keypad_platform_data *pdata,
  * makes sure that the "scan delay" is applied upon activation of the
  * column (the delay between activating the column and reading rows)
  *
+ * optional encoding of logical column address information and its
+ * mapping to column GPIO pin levels is taken care of as well
+ *
  * the caller ensures that this routine need not de-activate other
  * columns when dealing with the column specified for the invocation
  */
 static void activate_col(const struct matrix_keypad_platform_data *pdata,
 			 int col, bool on)
 {
-	__activate_col_pin(pdata, col, on);
+	int bit, lvl;
+
+	if (!pdata->col_gpios_binary_encoded) {
+		/* one-out-of-N approach, just setup the one pin */
+		__activate_col_pin(pdata, col, on);
+	} else if (on) {
+		/* setup the address bit pattern on all column pins */
+		for (bit = 0; bit < pdata->num_col_gpios; bit++) {
+			lvl = (col & (1 << bit)) ? 1 : 0;
+			__activate_col_pin(pdata, bit, lvl);
+		}
+	} else {
+		/* binary column encoding has no concept of "deselection" */
+		/* EMPTY */
+	}
 
 	if (on && pdata->col_scan_delay_us)
 		udelay(pdata->col_scan_delay_us);
@@ -105,12 +124,20 @@ static void activate_col(const struct matrix_keypad_platform_data *pdata,
  * matrix, or re-activates all columns at the same time after the scan
  * is complete, to make changes in the key press state trigger the
  * condition to re-scan the matrix
+ *
+ * this routine does not apply to the "binary encoded column addresses"
+ * approach, which has no concept of de-selecting columns, and cannot
+ * select multiple columns at the same time; the periodic column switch
+ * work routine takes care of detecting status changes in this mode
  */
 static void activate_all_cols(const struct matrix_keypad_platform_data *pdata,
 			      bool on)
 {
 	int col;
 
+	if (pdata->col_gpios_binary_encoded)
+		return;
+
 	for (col = 0; col < pdata->num_matrix_cols; col++)
 		__activate_col_pin(pdata, col, on);
 }
@@ -623,6 +650,8 @@ matrix_keypad_parse_dt(struct device *dev)
 	}
 	if (of_get_property(np, "col-gpios-pushpull", NULL))
 		pdata->col_gpios_push_pull = true;
+	if (of_get_property(np, "col-gpios-binary", NULL))
+		pdata->col_gpios_binary_encoded = true;
 
 	/* get delay and interval timing specs */
 	of_property_read_u32(np, "debounce-delay-ms", &pdata->debounce_ms);
@@ -630,6 +659,10 @@ matrix_keypad_parse_dt(struct device *dev)
 			     &pdata->col_scan_delay_us);
 	of_property_read_u32(np, "col-switch-delay-ms",
 			     &pdata->col_switch_delay_ms);
+	if (pdata->col_gpios_binary_encoded && !pdata->col_switch_delay_ms) {
+		dev_err(dev, "binary mode needs a column switch delay\n");
+		return ERR_PTR(-EINVAL);
+	}
 
 	/* get the individual row and column GPIO pins */
 	gpios = devm_kzalloc(dev,
@@ -658,6 +691,8 @@ matrix_keypad_parse_dt(struct device *dev)
 	 */
 	pdata->num_matrix_rows = pdata->num_row_gpios;
 	pdata->num_matrix_cols = pdata->num_col_gpios;
+	if (pdata->col_gpios_binary_encoded)
+		pdata->num_matrix_cols = 1 << pdata->num_col_gpios;
 	err = matrix_keypad_parse_of_params(dev,
 					    &pdata->num_matrix_rows,
 					    &pdata->num_matrix_cols);
diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h
index 1398d23..82db84a 100644
--- a/include/linux/input/matrix_keypad.h
+++ b/include/linux/input/matrix_keypad.h
@@ -55,6 +55,8 @@ struct matrix_keymap_data {
  * @col_gpios_active_low: polarity of column gpio pins
  * @col_gpios_push_pull: whether column gpio pins emulate open drain
  *	behaviour or fully drive pin levels to either direction
+ * @col_gpios_binary_encoded: whether column gpio pins carry 1-of-N or
+ *	binary encoded column address information
  * @wakeup: controls whether the device should be set up as wakeup
  *	source
  * @no_autorepeat: disable key autorepeat
@@ -89,6 +91,7 @@ struct matrix_keypad_platform_data {
 	bool		row_gpios_active_low;
 	bool		col_gpios_active_low;
 	bool		col_gpios_push_pull;
+	bool		col_gpios_binary_encoded;
 	bool		wakeup;
 	bool		no_autorepeat;
 };
-- 
1.7.10.4


  parent reply	other threads:[~2013-06-21 18:10 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-21 18:09 [PATCH v1 00/12] input: keypad-matrix: doc update, hw separation, polling, binary columns Gerhard Sittig
2013-06-21 18:09 ` [PATCH v1 01/12] input: matrix-keypad: update devicetree binding doc Gerhard Sittig
2013-06-21 21:31   ` Stephen Warren
2013-06-22  9:23     ` Gerhard Sittig
2013-06-24 22:00       ` Stephen Warren
2013-06-28  8:24         ` Gerhard Sittig
2013-06-28 14:50           ` Stephen Warren
2013-06-30 11:04             ` Gerhard Sittig
2013-06-21 18:09 ` [PATCH v1 02/12] input: matrix-keymap: func call coding style nit Gerhard Sittig
2013-06-22  2:18   ` Marek Vasut
2013-06-22  8:22     ` Gerhard Sittig
2013-06-22 13:23       ` Marek Vasut
2013-06-21 18:09 ` [PATCH v1 03/12] input: matrix-keypad: rename variables and funcs Gerhard Sittig
2013-06-21 18:09 ` [PATCH v1 04/12] input: matrix-keypad: push/pull, separate polarity Gerhard Sittig
2013-06-21 21:34   ` Stephen Warren
2013-06-22  9:36     ` Gerhard Sittig
2013-06-24 23:14       ` Stephen Warren
2013-06-28  8:33         ` Gerhard Sittig
2013-06-28 15:01           ` Stephen Warren
2013-06-30 11:43             ` Gerhard Sittig
2013-06-21 18:09 ` [PATCH v1 05/12] input: matrix-keypad: update comments, diagnostics Gerhard Sittig
2013-06-22  2:23   ` Marek Vasut
2013-06-21 18:09 ` [PATCH v1 06/12] input: keypad-matrix: refactor matrix scan logic Gerhard Sittig
2013-06-21 18:09 ` [PATCH v1 07/12] input: keypad-matrix: introduce polling support Gerhard Sittig
2013-06-21 21:38   ` Stephen Warren
2013-06-22  9:50     ` Gerhard Sittig
2013-06-24 23:18       ` Stephen Warren
2013-06-21 18:09 ` [PATCH v1 08/12] input: keypad-matrix: tell GPIO pins from matrix lines Gerhard Sittig
2013-06-21 21:41   ` Stephen Warren
2013-06-22 10:00     ` Gerhard Sittig
2013-06-24 23:26       ` Stephen Warren
2013-06-28  7:52         ` Gerhard Sittig
2013-06-28 14:35           ` Stephen Warren
2013-06-28 18:25             ` Dmitry Torokhov
2013-06-30 12:03               ` Gerhard Sittig
2013-06-21 18:09 ` Gerhard Sittig [this message]
2013-06-21 21:58   ` [PATCH v1 09/12] input: matrix-keypad: add binary column encoding Stephen Warren
2013-06-21 18:09 ` [PATCH v1 10/12] input: keypad_matrix: use usleep_range() for scan delay Gerhard Sittig
2013-06-21 22:00   ` Stephen Warren
2013-06-22 10:17     ` Gerhard Sittig
2013-06-24 23:27       ` Stephen Warren
2013-06-21 18:09 ` [PATCH v1 11/12] input: keypad-matrix: AC14xx device tree update Gerhard Sittig
2013-06-21 18:09 ` [PATCH v1 12/12] input: matrix-keypad: add diagnostics in probe() Gerhard Sittig
2013-06-22  2:28   ` Marek Vasut
2013-06-22  8:30     ` Gerhard Sittig

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=1371838198-7327-10-git-send-email-gsi@denx.de \
    --to=gsi@denx.de \
    --cc=agust@denx.de \
    --cc=arnd@arndb.de \
    --cc=devicetree-discuss@lists.ozlabs.org \
    --cc=dmitry.torokhov@gmail.com \
    --cc=dzu@denx.de \
    --cc=eric.y.miao@gmail.com \
    --cc=haojian.zhuang@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-input@vger.kernel.org \
    --cc=marek.vasut@gmail.com \
    --cc=nsekhar@ti.com \
    --cc=ralf@linux-mips.org \
    --cc=tony@atomide.com \
    --cc=xiechao.mail@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).