Changing pin mode by writing in Pinmux register

Hello

In AM335x (TRM) I have read that every pin has 8 different modes,each pin has specific register like (conf_gpmc_ad0) that you can change the pin mux mode from [0:7] . There are specific offsets for the pins from the base address ((0x44E1_0000) region name (Control Module))
I am able to read these registers correctly but my problem is in changing the value of these registers.
I used (“chmod 777 pinmode”) to change the permissions. but the problem of writing is still remain

The following is the C code I have used.

`

#define CONTROLMODST 0x44E10000
#define CONTROLMODED 0x44E11FFF
#define CONTROLMODSIZE (CONTROLMODED - CONTROLMODST)
#define PINREGOFF 0x808
#define SYSBOOT 0x40
#define REV 0x00

#define MODE0 0x0
#define MODE1 0x1
#define MODE2 0x2
#define MODE3 0x3
#define MODE4 0x4
#define MODE5 0x5
#define MODE6 0x6
#define MODE7 0x7

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
volatile void *start_addr = NULL;
volatile unsigned int *pinreg =NULL;
volatile unsigned int *sysboot =NULL;
volatile unsigned int *rev =NULL;
unsigned int reg;

int fd = open("/dev/mem", O_RDWR);

printf(“Mapping %X - %X (size: %X)\n”, CONTROLMODST, CONTROLMODED, CONTROLMODSIZE );
start_addr = mmap(0, CONTROLMODSIZE, PROT_READ | PROT_WRITE,MAP_SHARED, fd, CONTROLMODST);

pinreg=start_addr+PINREGOFF;
sysboot=start_addr+SYSBOOT;

rev=start_addr+REV;
if(start_addr == MAP_FAILED) {
printf(“Unable to map\n”);
exit(1);
}

printf(“Mux mapped to %p\n”, start_addr);
printf(“Pinreg mapped to %p\n”, pinreg);
// printf(“Sysboot mapped to %p\n”, sysboot);
// printf(“Rev mapped to %p\n”, rev);
reg=*pinreg;
printf(“reg before changing %p\n”, reg);
reg=reg|(reg+(1<<1));

*pinreg=reg;
// printf(“reg after changing %p\n”, pinreg);
printf(“reg after changing %p\n”, *pinreg);
// reg=*sysboot;
// printf(“reg before changing %p\n”, reg);
// reg=*rev;
// printf(“reg before changing %p\n”, reg);
}

`

The pinmux registers are protected by the Linux kernel and cannot be
written to by normal user code. You either need to properly configure
the registers using device-tree bindings or circumvent the
restrictions (ie: by doing something like directly writing the pinmux
register with the PRU, which has direct hardware access and doesn't go
through the ARM side page map tables).

Note there is a "bone-pinmux-helper" driver which was written to allow
easy user-mode changing of the pinmux registers via sysfs. See the
universal overlay (and the accompanying config-pin script) for an
example of usage:

https://github.com/cdsteinkuehler/beaglebone-universal-io

The pinmux registers are protected by the Linux kernel and cannot be
written to by normal user code.

That’s not entirely correct. The pad contol registers in the Control Modul are protected. But rather than by the Linux kernel, they’re protected by hardware (the CPU). You cannot write access them by the PRUSS. Only supervisor access by the host CPU can change the values.

I used (“chmod 777 pinmode”) to change the permissions. but the problem of writing is still remain

To adapt pinmuxing, your code has to run under root privilegues. Usually pinmuxing doesn’t change at run time. So you can execute such code in the boot sequence.

BR