Updating PinMux setting via /dev/mem has no effect

I have attempted to adjust the pinmux settings for a gpio programatically using mmap() and a write out to the appropriate register. This does not throw exception or any other error however no changes are made. Reading the mmap()'ed location returns pretty reasonable and believable results so I know I am hitting the right location.

For example, on my BBB GPIOs 50 and 51 are currently in mux mode 6 (ehrpwm1A_mux1 and ehrpwm1B_mux1) and the pinmux control registers for these are at offsets 0x848 and 0x84c from the 0x44e1000 control register. I can read the memory at these positions just fine and the return values are 0x06 (mux mode 6). Attempting to write a 0x07 to either of these locations to enable mux mode 7 does not error but the value at that memory location remains 0x06.

Is there any reason why this should not work? After all the capemanager and cape universal drivers seem to be able to change these settings at runtime.

I would very much appreciate any advice and insights anybody has into this issue.

Oh yeah, before anybody goes to the trouble of beating me up about it, I am aware that the Device Tree is the recommended way of changing this sort of pinmuxing and for my project I could, and probably will, do it that way. Nevertheless, is there a reason the ocp muxing cannot be adjusted at runtime (as root) by writing to the appropriate GPIO control register location?

Write access to the Control Module pad registers is only possible for the ARM CPU in protected mode. Neither mmaped C code nor the PRUSS can write these registers. That’s hard-coded in the AM33xx logic, no feedback on failure.

BTW: Beside the universal device tree overlay from Charles Steinkuehler I made a similar overlay that is a bit more complete and uses hexadecimal numbers instead of human readable text for the pin modes. For me, that’s easier to handle in source code. The overlay and a tool to create similar overlays with different pin claiming is included in the libpruio package.

You have to be in privileged mode to change pinmux. My approach is creating a kernel module for it like this (https://github.com/chunsj/nxctrl/tree/master/nxpmx)

Or you can use PRU for this, I’ve heard that someone really do this in his library (I cannot remember its name). However to control PRU you might need to be
in privileged mode to enable PRU and others…

Last but most official method is use of device tree and reboot. If your kernel is 3.8.16, you can use device tree overlay.

I hope this can help you.