[PATCH] pinctrl: sunxi: set minimal debounce on input-debounce 0

From: Andreas Feldner
Date: Sat Feb 11 2023 - 13:09:04 EST


sunxi-h3-h5 based boards have no support for switching
off IRQ debouncing filter. This would be the expected
behaviour of value 0 for the general pinctl parameter
input-debounce.
The current driver implementation ignores value 0
for input-debounce, leaving the chip's default. This
default, however, is not minimal, but equivalent to
value 31 (microseconds).

This patch does not ignore value 0 but instead makes
sure the corresponding IRQ debounce filter is set
to the shortest time selectable, i. e. the fast
oscillator with a divider of 1 == (2 ^ 0).

The current default behaviour is explicitly ensured
by including input-debounce=<31 31> in the relevant
part of the devicetree.

Fixes: 7c926492d38a ("pinctrl: sunxi: Add support for interrupt debouncing")

Signed-off-by: Andreas Feldner <pelzi@xxxxxxxxxxxxxxx>
---
 arch/arm/boot/dts/sunxi-h3-h5.dtsi    |  1 +
 drivers/pinctrl/sunxi/pinctrl-sunxi.c | 40 +++++++++++++++------------
 2 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 686193bd6bd9..e9ed4948134d 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -410,6 +410,7 @@ pio: pinctrl@1c20800 {
             #gpio-cells = <3>;
             interrupt-controller;
             #interrupt-cells = <3>;
+            input-debounce = <31 31>;

             csi_pins: csi-pins {
                 pins = "PE0", "PE2", "PE3", "PE4", "PE5",
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
index f35179eceb4e..6798c8f4067e 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -1444,29 +1444,35 @@ static int sunxi_pinctrl_setup_debounce(struct sunxi_pinctrl *pctl,
         if (ret)
             return ret;

-        if (!debounce)
-            continue;
-
-        debounce_freq = DIV_ROUND_CLOSEST(USEC_PER_SEC, debounce);
-        losc_div = sunxi_pinctrl_get_debounce_div(losc,
-                              debounce_freq,
-                              &losc_diff);
-
-        hosc_div = sunxi_pinctrl_get_debounce_div(hosc,
-                              debounce_freq,
-                              &hosc_diff);
-
-        if (hosc_diff < losc_diff) {
-            div = hosc_div;
-            src = 1;
+        if (debounce) {
+            debounce_freq = DIV_ROUND_CLOSEST(USEC_PER_SEC, debounce);
+            losc_div = sunxi_pinctrl_get_debounce_div(losc,
+                                  debounce_freq,
+                                  &losc_diff);
+
+            hosc_div = sunxi_pinctrl_get_debounce_div(hosc,
+                                  debounce_freq,
+                                  &hosc_diff);
+
+            if (hosc_diff < losc_diff) {
+                div = hosc_div;
+                src = 1;
+            } else {
+                div = losc_div;
+                src = 0;
+            }
         } else {
-            div = losc_div;
-            src = 0;
+            /* lowest time as best approximation to "off" */
+            div = 0;
+            src = 1;
         }

         writel(src | div << 4,
                pctl->membase +
                sunxi_irq_debounce_reg_from_bank(pctl->desc, i));
+
+        pr_info("Debounce filter for IRQ bank %d configured to %d us (reg %x)\n",
+            i, debounce, src | div << 4);
     }

     return 0;
--
2.30.2