Input: matrix_keypad - add option to drive inactive columns
authorDavid Rivshin <DRivshin@allworx.com>
Wed, 29 Mar 2017 07:14:16 +0000 (00:14 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Wed, 29 Mar 2017 07:25:01 +0000 (00:25 -0700)
The gpio-matrix-keypad driver normally sets inactive columns as inputs
while scanning. This does not work for all hardware, which may require
the inactive columns to be actively driven in order to overcome any
pull-ups/downs on the columns.

Signed-off-by: David Rivshin <drivshin@allworx.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt
drivers/input/keyboard/matrix_keypad.c
include/linux/input/matrix_keypad.h

index d0ea09ba249fc5ea484625564e81a815abd7f014..570dc10f0cd74b7da9c1ced0c2dfb73e55e452a2 100644 (file)
@@ -24,6 +24,8 @@ Optional Properties:
 - 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
+- drive-inactive-cols: drive inactive columns during scan,
+                       default is to turn inactive columns into inputs.
 
 Example:
        matrix-keypad {
index 18839cd5f76e089dc3da912cad7b7f04f6a302e9..1f316d66e6f71eaa232b295c9ba161be4c6a5a9d 100644 (file)
@@ -42,9 +42,10 @@ struct matrix_keypad {
 };
 
 /*
- * NOTE: normally the GPIO has to be put into HiZ when de-activated to cause
- * minmal side effect when scanning other columns, here it is configured to
- * be input, and it should work on most platforms.
+ * NOTE: If drive_inactive_cols is false, then the GPIO has to be put into
+ * HiZ when de-activated to cause minmal side effect when scanning other
+ * columns. In that case it is configured here to be input, otherwise it is
+ * driven with the inactive value.
  */
 static void __activate_col(const struct matrix_keypad_platform_data *pdata,
                           int col, bool on)
@@ -55,7 +56,8 @@ static void __activate_col(const struct matrix_keypad_platform_data *pdata,
                gpio_direction_output(pdata->col_gpios[col], level_on);
        } else {
                gpio_set_value_cansleep(pdata->col_gpios[col], !level_on);
-               gpio_direction_input(pdata->col_gpios[col]);
+               if (!pdata->drive_inactive_cols)
+                       gpio_direction_input(pdata->col_gpios[col]);
        }
 }
 
@@ -432,6 +434,9 @@ matrix_keypad_parse_dt(struct device *dev)
        if (of_get_property(np, "gpio-activelow", NULL))
                pdata->active_low = true;
 
+       pdata->drive_inactive_cols =
+               of_property_read_bool(np, "drive-inactive-cols");
+
        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);
index 37b04a0fdea4e004a63c053bfb3c90d5de3612f1..6174733a57ebc60b68fe674d1c271bb8af6d9d51 100644 (file)
@@ -49,6 +49,8 @@ struct matrix_keymap_data {
  * @wakeup: controls whether the device should be set up as wakeup
  *     source
  * @no_autorepeat: disable key autorepeat
+ * @drive_inactive_cols: drive inactive columns during scan, rather than
+ *     making them inputs.
  *
  * This structure represents platform-specific data that use used by
  * matrix_keypad driver to perform proper initialization.
@@ -73,6 +75,7 @@ struct matrix_keypad_platform_data {
        bool            active_low;
        bool            wakeup;
        bool            no_autorepeat;
+       bool            drive_inactive_cols;
 };
 
 int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data,