Recommended way to programmatically pinmux ?

Hi,
In the olden days, to configure all the necessary hardware to talk to
a cape, one would write an overlay. These days, the Charles' universal
cape and the config-pin utility make this much easier.

However: both, the overlay config or the universal cape still don't
solve the duplication of configuration: the program that writes to
GPIO pins also knows where that particular pin is (typically by memory
mapping the areas and writing to them directly).

So the typical way to run some hardware now is
  config-pin -f mypinconfig.pins
  ./run-the-program

So we have the configuration in the config-pin script file, which sets
up all the GPIO pins for input, output, pull-up etc. And there is the
program that then _also_ needs to know about the exact same pins.

Ideally, that would only be in one place: the program already knows
that it needs to write to some GPIO pins, and ideally would also be
able set that up to be used as such right there without requiring the
user to first call config-pin. This can make configurations and
installations much more robust.

I see three possibilities

  1) circumvent all that, manually memory map the right places
according to the am335x datasheet and do pin-muxing that way.
     Cons: I think this is discouraged these days as the kernel would
like to know
     what is going on in the hardware configuration department. I also
found that sometimes this is
      not entirely working and requires more work as it is sometimes
needed to manually switch on clock domains etc.

  2) Mimick what config-pin shell-script is doing, essentially writing
things to /sys/devices
    files, e.g. writing the string "gpio" into
/sys/devices/platform/ocp/ocp:P2_07_pinmux/state
      Cons: These names sound sufficiently like they might change in
future versions of the
      kernel, thus requiring to change all programs that initialize
hardware GPIOs.
      There seems to also be some specifics about boards and capemgr
etc. coded in that
      script.

  3) Maybe there is a third option ? Ideally I'd just like a C-library
or well documented
     system calls that allow to do the equivalent to config-pin, but
as a C-function:
               am335x_configure_pin("P1.29", "out");
     or similar. And that library would just be a simple beaglebone
support library that is
     updated whenever a kernel update requires it.

I suspect it would be something like (2), that then also should be
packaged into something like (3). But I don't know. What is the
recommended, future-compatible way to set up GPIO pinmuxing
programmatically these days ? I think I am fine if that is restricted
to kernels 4.1.x onwards.

Thanks,
  Henner.

Hi,
In the olden days, to configure all the necessary hardware to talk to
a cape, one would write an overlay. These days, the Charles' universal
cape and the config-pin utility make this much easier.

However: both, the overlay config or the universal cape still don't
solve the duplication of configuration: the program that writes to
GPIO pins also knows where that particular pin is (typically by memory
mapping the areas and writing to them directly).

So the typical way to run some hardware now is
config-pin -f mypinconfig.pins
./run-the-program

So we have the configuration in the config-pin script file, which sets
up all the GPIO pins for input, output, pull-up etc. And there is the
program that then _also_ needs to know about the exact same pins.

Ideally, that would only be in one place: the program already knows
that it needs to write to some GPIO pins, and ideally would also be
able set that up to be used as such right there without requiring the
user to first call config-pin. This can make configurations and
installations much more robust.

I see three possibilities

1) circumvent all that, manually memory map the right places
according to the am335x datasheet and do pin-muxing that way.
    Cons: I think this is discouraged these days as the kernel would
like to know
    what is going on in the hardware configuration department. I also
found that sometimes this is
     not entirely working and requires more work as it is sometimes
needed to manually switch on clock domains etc.

2) Mimick what config-pin shell-script is doing, essentially writing
things to /sys/devices
   files, e.g. writing the string "gpio" into
/sys/devices/platform/ocp/ocp:P2_07_pinmux/state
     Cons: These names sound sufficiently like they might change in
future versions of the
     kernel, thus requiring to change all programs that initialize
hardware GPIOs.
     There seems to also be some specifics about boards and capemgr
etc. coded in that
     script.

3) Maybe there is a third option ? Ideally I'd just like a C-library
or well documented
    system calls that allow to do the equivalent to config-pin, but
as a C-function:
              am335x_configure_pin("P1.29", "out");
    or similar. And that library would just be a simple beaglebone
support library that is
    updated whenever a kernel update requires it.

I suspect it would be something like (2), that then also should be
packaged into something like (3). But I don't know. What is the
recommended, future-compatible way to set up GPIO pinmuxing
programmatically these days ? I think I am fine if that is restricted
to kernels 4.1.x onwards.

Creating a C library seems pretty reasonable as a measure of future-proofing and encouraging dependencies to be integrated into a single program.

Note that PRU firmware must sometimes reserve pins or peripherals as well and a related approach seems useful. For the bone101 PRU examples, I’ve hacked in some handling of changing the pinmux modes via structures parsed by a loader manager.

You forgot another problem: when setting a GPIO as output it’s not clear which state (high/low) it has in the time between config-pin call and program init.