All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] gpio-omap: handle bias flags
@ 2020-07-09 17:30 Drew Fustini
  0 siblings, 0 replies; only message in thread
From: Drew Fustini @ 2020-07-09 17:30 UTC (permalink / raw
  To: Tony Lindgren, Haojian Zhuang, Linus Walleij, linux-omap,
	linux-gpio
  Cc: Jason Kridner, Robert Nelson

Tony - what do you think of this approach?

I have added this in arch/arm/boot/dts/am335x-pocketbeagle.dts to
describe the pins which will be gpio lines accessed by userspace
through gpiod ioctl() calls:

&am33xx_pinmux {

	pinctrl-names = "default";
	pinctrl-0 =   < &gpio_pins >;

	gpio_pins: pinmux-gpio-pins {
		/* MUX_MODE7 is gpio mode */
		pinctrl-single,pins = <
			/* PIN 95 and PIN 94 */
			AM33XX_PADCONF(AM335X_PIN_UART1_RTSN, PIN_INPUT, MUX_MODE7)
			AM33XX_PADCONF(AM335X_PIN_UART1_CTSN, PIN_INPUT, MUX_MODE7)
			/* PIN 100 */
			AM33XX_PADCONF(AM335X_PIN_MCASP0_ACLKX, PIN_INPUT, MUX_MODE7)
			/* PIN 18 */
			AM33XX_PADCONF(AM335X_PIN_GPMC_A2, PIN_INPUT, MUX_MODE7)
		>;
		pinctrl-single,bias-pullup   = < 8 16  8 24>;
		pinctrl-single,bias-pulldown = < 8  0  8 24>;
	};

The "pinctrl-single,bias-pullup" and "pinctrl-single,bias-pulldown"
pinconf properties are set for the gpio_pins pin group.  The input
value 0x8 causes both to be inactive but still added to the
PIN_MAP_TYPE_CONFIGS_GROUP pinctrl map.  This is necessary for
pcs_pinconf_set() to be able to be able to set the bias config.

For AM335x, the pin conf register has the format [0]:

bit	attribute      value
  6	slew           { 0: fast, 1: slow }
  5     rx_active      { 0: rx disable, 1: rx enabled }
  4     pu_typesel     { 0: pulldown select, 1: pullup select }
  3     puden          { 0: pud enable, 1: disabled }
  2     mode           3 bits to selec mode 0 to 7
  1     mode
  0     mode

Here is how I derived the values:

pinctrl-single,bias-pullup   = <[input] [enabled] [disable] [mask]>;
pinctrl-single,bias-pullup   = <     8        16        8      24 >;

          2^5    2^4    2^3    2^2    2^1    2^0  | 
         0x20   0x10   0x08   0x04   0x02   0x01  |
           32     16      8      4      2      1  | 
-------------------------------------------------------  
input       x      0      1     x      x      x   |   8 
enabled     x      1      0     x      x      x   |  16
disabled    x      0      1     x      x      x   |   8
mask        x      1      1     x      x      x   |  24


pinctrl-single,bias-pulldown = <[input] [enabled] [disable] [mask]>;
pinctrl-single,bias-pulldown = <     8         0        8      24 >;

          2^5    2^4    2^3    2^2    2^1    2^0  | 
         0x20   0x10   0x08   0x04   0x02   0x01  |
           32     16      8      4      2      1  | 
-------------------------------------------------------  
input       x      0      1     x      x      x   |   8 
enabled     x      0      0     x      x      x   |   0 
disabled    x      0      1     x      x      x   |   8
mask        x      1      1     x      x      x   |  24

The pinconf bias properties get applied to the pin group during boot
when pcs_pinconf_group_set() calls pcs_pinconf_set() for each pin. Here
is the output from function_graph tracer:

              pinconf_apply_setting() {
                pcs_pinconf_group_set() {
                  pinctrl_generic_get_group_pins();
                  pcs_pinconf_set() {
                    pcs_get_function() {
                      pinmux_generic_get_function();
                    }
                    pcs_readl();
                    pcs_writel();
                    pcs_readl();
                    pcs_writel();
                  }
                  pcs_pinconf_set() {
                    pcs_get_function() {
                      pinmux_generic_get_function();
                    }
                    pcs_readl();
                    pcs_writel();
                    pcs_readl();
                    pcs_writel();
                  }
                  pcs_pinconf_set() {
                    pcs_get_function() {
                      pinmux_generic_get_function();
                    }
                    pcs_readl();
                    pcs_writel();
                    pcs_readl();
                    pcs_writel();
                  }
                  pcs_pinconf_set() {
                    pcs_get_function() {
                      pinmux_generic_get_function();
                    }
                    pcs_readl();
                    pcs_writel();
                    pcs_readl();
                    pcs_writel();
                  }
                }
              }

After boot, I then use gpiomon utility with bias flags:

	gpiomon -B pull-up 3 14

gpiochip 3 line 14 maps to pin 100 which is AM335X_PIN_MCASP0_ACLKX at
offset 0x990.  For this to succeed, I modified omap_gpio_set_config() in
gpio_omap.c to handle PIN_CONFIG_BIAS_PULL_{UP,DOWN} by calling
gpiochip_generic_config().  Here is output of function_grapher tracer:

             gpio_ioctl() {
               gpiochip_get_desc();
               gpiod_request() {
                 gpiod_request_commit() {
                   gpiochip_line_is_valid();
                   omap_gpio_request() {
                     omap_gpio_runtime_resume() {
                       omap_gpio_unidle() {
                         omap_gpio_restore_context();
                       }
                     }
                     omap_enable_gpio_module();
                   }
                   gpiod_get_direction() {
                     gpiod_to_chip();
                     omap_gpio_get_direction();
                   }
                 }
               }
               gpiod_direction_input() {
                 omap_gpio_input() {
                   omap_set_gpio_direction();
                 }
                 gpio_set_bias() {
                   gpio_set_config() {
                     gpio_do_set_config() {
                       omap_gpio_set_config() {
                         gpiochip_generic_config() {
                           pinctrl_gpio_set_config() {
                             pinctrl_get_device_gpio_range() {
                               pinctrl_match_gpio_range();
                             }
                             pinconf_set_config() {
                               pcs_pinconf_set() {
                                 pcs_get_function() {
                                   pinmux_generic_get_function();
                                 }
                                 pcs_readl();
                                 pcs_pinconf_clear_bias.constprop.0();
                                 pcs_writel();

Thanks,
Drew

[0] http://www.ti.com/lit/ds/symlink/am3358.pdf
---
 drivers/gpio/gpio-omap.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index b8e2ecc3eade..a471a152f318 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -896,12 +896,25 @@ static int omap_gpio_set_config(struct gpio_chip *chip, unsigned offset,
 				unsigned long config)
 {
 	u32 debounce;
+	int ret;
 
-	if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE)
-		return -ENOTSUPP;
+	if ((pinconf_to_config_param(config) == PIN_CONFIG_BIAS_DISABLE) ||
+	    (pinconf_to_config_param(config) == PIN_CONFIG_BIAS_PULL_UP) ||
+	    (pinconf_to_config_param(config) == PIN_CONFIG_BIAS_PULL_DOWN))
+	{
+		ret = gpiochip_generic_config(chip, offset, config);
+	}
+	else if (pinconf_to_config_param(config) == PIN_CONFIG_INPUT_DEBOUNCE)
+	{
+		debounce = pinconf_to_config_argument(config);
+		ret = omap_gpio_debounce(chip, offset, debounce);
+	}
+	else
+	{
+		ret = -ENOTSUPP;
+	}
 
-	debounce = pinconf_to_config_argument(config);
-	return omap_gpio_debounce(chip, offset, debounce);
+	return ret;
 }
 
 static void omap_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-- 
2.25.1

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2020-07-09 17:30 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-07-09 17:30 [RFC] gpio-omap: handle bias flags Drew Fustini

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.