Configuration of a single GPIO Input pin

Hi,

does somebody know how to configure a GPIO pin (MUXMODE, Pullup/Pulldown etc.) which is not used by a driver?
My problem is:

I can set/read the status of GPIO input with gpioset/gpioget but I can’t set its Pullup or Pulldown configuration.
I found such a configuration at the device tree, but this does not seem to work with “simple GPIO pins”.

Example: A pin configuration at the device like this:

i2c4_pins_default: i2c4_pins_default {
pinctrl-single,pins = <
0x40 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a0.i2c4_scl /
0x44 (PIN_INPUT_PULLUP | MUX_MODE7) /
gpmc_a1.i2c4_sda */

;
};

is ignored, when the status of the according i2c4 interface is set to “disabled”.

thanks,
Joerg

A pin configuration at the device [..] is ignored, when the status
[..] is set to "disabled".

Correct, since status="disabled" means no device gets created for that
DT node, hence no pinmux ever gets requested for it.

            0x40 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a0.i2c4_scl */
            0x44 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a1.i2c4_sda */

Note btw that gpio is mode 14 on the am57xx, not mode 7.

The correct solution is to create a pinmux node for it (it's not
appropriate to mess with a random pinmux node you found) and find or
create some device to attach it to.

An obvious choice for gpios is to create a gpio-helper device, which
also lets you name and initialize your gpios (direction etc):

#include <dt-bindings/gpio/gpio.h>

/ {
  gpio-demo {
    compatible = "gpio-of-helper";

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

    P16.36 {
      gpio = <&gpio7 3 GPIO_ACTIVE_HIGH>;
      input;
      dir-changeable;
    };

    P16.43 {
      gpio = <&gpio7 4 GPIO_ACTIVE_HIGH>;
      input;
      dir-changeable;
    };
  };
};

&dra7_pmx_core {
  gpio_demo_pins: gpio-demo {
    pinctrl-single,pins = <
      (4 * 16) (PIN_INPUT_PULLUP | MUX_MODE14) // P16.36 / gpio7.3
      (4 * 17) (PIN_INPUT_PULLUP | MUX_MODE14) // P16.43 / gpio7.4
    >;
  };
};

You can give the nodes any name you want as long as they don't conflict
with a existing nodes. The gpio names show up in the 'label' attribute
in sysfs, hence you can use an udev rule to make nice symlinks:

SUBSYSTEM=="subsystem", KERNEL=="gpio", ACTION=="add", \
  RUN+="/bin/mkdir -p /dev/gpio"

SUBSYSTEM=="gpio", ACTION=="add", TEST=="value", ATTR{label}!="sysfs", \
  RUN+="/bin/chgrp -R gpio '/sys%p'", \
  RUN+="/bin/chmod -R g=u '/sys%p'", \
  RUN+="/bin/ln -sT '/sys/class/gpio/%k' /dev/gpio/%s{label}"

The combination of this dt snippet and this udev rule yields:

@bbx15:~$ ls -l /dev/gpio/*/value
-rw-rw-r-- 1 root gpio 4096 Oct 15 09:24 /dev/gpio/P16.36/value
-rw-rw-r-- 1 root gpio 4096 Oct 15 09:24 /dev/gpio/P16.43/value

Matthijs

I should probably remind you that TI recommends only doing pinmux in
u-boot, which performs pinmux and iodelay configuration while all SoC
pins are isolated. Changing pinmux or iodelay at any other time may
result in glitches on the pins (erratum i869).

If you don't care and don't want to put your own pinmux in u-boot, you
may at the very least want to consider preventing u-boot from applying
the pin configuration that's intended for the am572x-evm LCD board
(which I'm assuming you don't have). You can find an u-boot version
patched to remove pinmux for the expansion header pins in the
patch/ti2017.01/x15-pinmux branch of
https://github.com/dutchanddutch/u-boot

Matthijs

Thanks a lot for your ultrafast answer!

0x40 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a0.i2c4_scl /
0x44 (PIN_INPUT_PULLUP | MUX_MODE7) /
gpmc_a1.i2c4_sda */

Note btw that gpio is mode 14 on the am57xx, not mode 7.

I know, was just an example…

An obvious choice for gpios is to create a gpio-helper device, which
also lets you name and initialize your gpios (direction etc):

While testing with your solutiond I have to recognize that in my environment (builroot and Mainline kernel with TI-Patches) there is no gpio-of-helper :frowning:

Now I try to merge the gpio-of-helper.c into my kernel and test again.

Joerg

in my environment (builroot and Mainline kernel with TI-Patches)

You probably simply mean TI's kernel tree?

there is no gpio-of-helper :frowning:

Ah, yeah afaik mainline doesn't have any real way to declare gpios in
DT (for use by userspace), and same. You could of course still stick
your pinmux onto a random device (or do it in u-boot) and manually
export the gpios, but as the example in my email shows, life is much
nicer with gpio-of-helper and the gpiolib-sysfs patches that are in
the beaglebone linux trees.

Now I try to merge the gpio-of-helper.c into my kernel and test again.

Also be sure to pick up the gpiolib-sysfs.c patches.

In other words, if you're using 4.14-ti then you need the
drivers/gpio/* parts of this big patch:
https://raw.githubusercontent.com/RobertCNelson/ti-linux-kernel-dev/ti-linux-4.14.y/patches/drivers/ti/gpio/0001-BeagleBone-pinmux-helper.patch

If you're using 4.9-ti then from
https://github.com/RobertCNelson/ti-linux-kernel-dev/tree/ti-linux-4.9.y/patches/drivers/ti/gpio
you need these patches I think:
0004-gpio-Introduce-GPIO-OF-helper.patch
0005-Add-dir-changeable-property-to-gpio-of-helper.patch
0012-Remove-CONFIG_EXPERIMENTAL-dependency-on-CONFIG_GPIO.patch
0014-gpio-of-helper-idr_alloc.patch
0015-gpio-of-helper-avoid-pointless-redundancy-in-DT.patch
0016-gpio-of-helper-reduce-kernel-log-noise.patch
0017-gpio-of-helper-pass-of_gpio_flags-to-request.patch
0018-gpio-show-label-in-sysfs.patch
0019-gpio-always-show-direction-in-sysfs.patch

The rest of the patches seem to be for the bone-pinmux-helper, which
is unrelated and not something you need.

Matthijs

Hi Matthijs,

thanks for your hints. I finally managed to configure the pinmux at the u-boot level. But first I had to find out which part of u-boot is used by SPL and which later in the u-boot.

(U-boot source architecture is not completely straightforward to understand)

Joerg