am335xussetpm user space device driver

and c program to test it out

/*
setpm.c
Compile: gcc setpm.c -o setpm
*/

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

#define DEVICE "/dev/am335xussetpm"
#define MEM_START 0x44E10800
#define MEM_END   0x44E109B4

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "setpm: Usage: %s <hex address> <hex value>\n", argv[0]);
        return 1;
    }

    unsigned long addr = strtoul(argv[1], NULL, 16);
    unsigned char value = strtoul(argv[2], NULL, 16) & 0xFF;

    if (addr < MEM_START || addr > MEM_END) {
        fprintf(stderr, "setpm: Error: Address 0x%lx is out of allowed range 0x%lx-0x%lx\n",
                addr, MEM_START, MEM_END);
        return 1;
    }

    unsigned long offset = addr - MEM_START;

    int fd = open(DEVICE, O_RDWR);
    if (fd < 0) { perror("open"); return 1; }

    
    if (pwrite(fd, &value, 1, offset) != 1) {
        perror("setpm: pwrite");
        close(fd);
        return 1;
    }

    printf("setpm: Wrote 0x%02X to address 0x%lx (offset 0x%lx)\n", value, addr, offset);
    close(fd);
    return 0;
}

This is the output showing P8.11 being changed from user space

debian@BeagleBone:~/src/setpm$ pinmux|grep P8.11
gpio0:13 | GPMC_AD13 P8.11         | 0x44e10834 | 0x0834 | 0x37  |    7  | FRXPULLUP
debian@BeagleBone:~/src/setpm$ sudo ./setpm 0x44e10834 0x27
setpm: Wrote 0x27 to address 0x44e10834 (offset 0x34)
debian@BeagleBone:~/src/setpm$ pinmux|grep P8.11
gpio0:13 | GPMC_AD13 P8.11         | 0x44e10834 | 0x0834 | 0x27  |    7  | FRXPULLDN
debian@BeagleBone:~/src/setpm$ sudo ./setpm 0x44e10834 0x37
setpm: Wrote 0x37 to address 0x44e10834 (offset 0x34)
debian@BeagleBone:~/src/setpm$ pinmux|grep P8.11
gpio0:13 | GPMC_AD13 P8.11         | 0x44e10834 | 0x0834 | 0x37  |    7  | FRXPULLUP

Hope this is useful to someone.

2 Likes