/*
 kw-gpio - program to access GPIO state of kirkwood SoCs from userspace

 Copyright (c) Adam Baker, 2014
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:

 1. Redistributions of source code must retain the above copyright notice,
    this list of conditions and the following disclaimer.

 2. Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.
*/

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

#define KW_REGS_BASE 0xf1010000
#define KW_MPP_OFFSET  0x00000
#define KW_GPIO_OFFSET 0x00100
#define KW_NUM_PINS  50

int main(int argc,char *argv[])
{
    int fd=open("/dev/mem",O_RDWR);
    if (fd < 0)
    {
        perror("/dev/mem");
        exit(1);
    }
    uint32_t *regs=mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE,
                        MAP_SHARED, fd, KW_REGS_BASE);
    if (regs == MAP_FAILED)
    {
        perror("mmap");
        exit(1);
    }
    uint32_t *mpp=regs + KW_MPP_OFFSET / sizeof (uint32_t);
    uint32_t *gpio=regs + KW_GPIO_OFFSET/ sizeof (uint32_t);
    int pin;
    printf("pagesize is 0x%x\n",getpagesize());
    printf("regs mapped at %p\n", regs);
    printf("MPP mapped at %p\n", mpp);
    printf("GPIO mapped at %p\n", gpio);
    for(pin = 0; pin < KW_NUM_PINS; pin++)
    {
        int offset=0;
        if (pin >= 32)
            offset = 16;
        printf("pin=%02d, mode=%x, dir=%d, dout=%d, act=%d, din=%d\n", pin,
               mpp[pin/8] >> ((pin % 8)*4) & 0xf,
               gpio[offset + 1] >> (pin % 32) & 1,
               gpio[offset + 0] >> (pin % 32) & 1,
               gpio[offset + 3] >> (pin % 32) & 1,
               gpio[offset + 4] >> (pin % 32) & 1);
    }
    close(fd);

    return 0;
}
