/* readAR7gpios
   A simple utility to repeatedly dump the AR7's GPIO input state to the terminal.

   (c) Matt Evans, 1 May 2010

   This file is subject to the terms and conditions of the GNU General
   Public License. 
 */

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


#define AR7_REGS_BASE   0x08610000
#define AR7_REGS_GPIO_OFFSET   0x0900
#define AR7_GPIO_INPUT   0x0
#define AR7_GPIO_OUTPUT (0x4/4)
#define AR7_GPIO_DIR    (0x8/4)  /* 0 output, 1 input */
#define AR7_GPIO_ENABLE (0xc/4)

#define BIT(X) (1<<(X))

volatile unsigned int *regs;
volatile unsigned int *gpio;


int main(void)
{
  int mfd, i;

  if ((mfd = open("/dev/mem", O_RDWR | O_SYNC)) < 0) {
    printf("Can't open /dev/mem! (errno %d)\n", errno);
    return 1;
  }
  
  regs = (volatile unsigned int *)mmap(0, 4096, PROT_READ | PROT_WRITE,
				       MAP_SHARED, mfd, AR7_REGS_BASE);

  if (regs == (void *)MAP_FAILED) {
    printf("Can't mmap! (errno %d)\n", errno);
    return 1;
  }

  printf("Mapped regs 0x%lx at 0x%lx\n", AR7_REGS_BASE, regs);

  gpio = regs + (AR7_REGS_GPIO_OFFSET / sizeof(unsigned int));

  printf("GPIO IN\t\t0x%08lx\n", gpio[AR7_GPIO_INPUT]);
  printf("GPIO OUT\t0x%08lx\n", gpio[AR7_GPIO_OUTPUT]);
  printf("GPIO DIR\t0x%08lx\n", gpio[AR7_GPIO_DIR]);
  printf("GPIO EN\t\t0x%08lx\n", gpio[AR7_GPIO_ENABLE]);
    
  gpio[AR7_GPIO_DIR] = 0xffffffff;
  gpio[AR7_GPIO_ENABLE] = 0xffffffff;

  while(1) {
    int i; 
    unsigned int g = gpio[AR7_GPIO_INPUT];
    for (i = 0; i < 32; i++)
      printf("%2d%c ", i, (g & (1<<i)) ? '*' : '.');
    
    printf("\n");
  };

  return 0;
}
