//FRAM
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <errno.h>
#include <string.h>
 
#define VERSION "1.0 20150907"
#define FAILURE     -1
#define NOERROR      0
#define NOOPEN       1
#define NOFILE       2
#define NODEVICE     3 
#define NORIGHTARG   4

#define DIRECTION_OUT 1
#define DIRECTION_IN  0
#define GPIO_EE_WP 64

int gpio_direction_status(int gpio, unsigned char *direction)
{
	FILE *fp;
	char dir[4];
	char gpio_dir[36];
	struct stat st;

	sprintf(gpio_dir, "/sys/class/gpio/gpio%d/direction", gpio);

	if(!stat(gpio_dir, &st))
	{
		fp = fopen(gpio_dir, "r");     /* open file pointer */

		if (!fp)
			return NOOPEN;

		fscanf(fp, "%s", dir);

		fclose(fp);
	}
	else
	{
		return NOFILE;
	}

	if(!strcmp(dir, "out"))
		*direction = DIRECTION_OUT;
	else
		*direction = DIRECTION_IN;

	return NOERROR;
}

int gpio_direction_set(int gpio, unsigned char direction)
{
	FILE *fp;
	char cmd[64];
	char gpio_dir[36];
	struct stat st;
	unsigned char now_direction = 0;
	int result = 0;

	result = gpio_direction_status(gpio, &now_direction);

	if(result)
	{
		return result;
	}
	else
	{
		if(now_direction == direction)
			return NOERROR;
	}

	sprintf(gpio_dir, "/sys/class/gpio/gpio%d/direction", gpio);

	if(!stat(gpio_dir, &st))
	{
		fp = fopen(gpio_dir,"w");     /* open file pointer */

		if (!fp)
			return NOOPEN;

		if(direction == 1)
		{
			fprintf(fp,"out");
		}
		else if(direction == 0)
		{
			fprintf(fp,"in");
		}
		else
		{
			fclose(fp);
			return NORIGHTARG;
		}

		fclose(fp);
	}
	else
	{
		return NOFILE;
	}

	return NOERROR;
}

int gpio_value_out(int gpio, unsigned char value)
{
	FILE *fp;
	char gpio_value[36];
	struct stat st;

	sprintf(gpio_value, "/sys/class/gpio/gpio%d/value", gpio);

	if(!stat(gpio_value, &st))
	{
		fp = fopen(gpio_value,"w");     /* open file pointer */

		if (!fp)
			return NOOPEN;

		if(value == 0 || value == 1)
		{
			fprintf(fp, "%d", value);
		}
		else
		{
			fclose(fp);
			return NORIGHTARG;
		}

		fclose(fp);
	}
	else
	{
		return NOFILE;
	}
	
	return NOERROR;
}

int gpio_value_in(int gpio, unsigned char *value)
{
	FILE *fp;
	char gpio_value[36];
	struct stat st;
	unsigned char val = 0;

	sprintf(gpio_value, "/sys/class/gpio/gpio%d/value", gpio);

	if(!stat(gpio_value, &st))
	{
		fp = fopen(gpio_value,"r");     /* open file pointer */

		if (!fp)
			return NOOPEN;

		fscanf(fp, "%d", &val);

		fclose(fp);
	}
	else
	{
		return NOFILE;
	}

	*value = val;

	return NOERROR;
}

int eeprom_init(void)
{
	char chip[16];
	FILE *fp;
	struct stat st;
	char gpio2_0[32] = "/sys/class/gpio/gpio64/value";
	int result = 0;

	memset(&st, 0, sizeof(struct stat));

	if(stat(gpio2_0, &st))
		system("echo 64 > /sys/class/gpio/export");	

	result = gpio_direction_set(GPIO_EE_WP, DIRECTION_OUT);

  if(result)
    return result;

	result = gpio_value_out(GPIO_EE_WP, 0);	//Disable WP

	if(result)
		return result;

	return NOERROR;
}

int eeprom_fini(void)
{
	int result = 0;

	result = gpio_value_out(GPIO_EE_WP, 1); //Enable WP

	if(result)
		return result;

	return NOERROR;
}

int main(int argc, char **argv)
{
	int i;
	unsigned char buffer[128];
 	int fd;
	char *delim = ":";
	char * pch;
	int rs = 0;

	rs = eeprom_init();	

	if(rs)
		return FAILURE;

#if 1 
	/* write default EEPROM(0~63) bytes */
	fd = open("/sys/bus/i2c/devices/1-0050/eeprom", O_RDWR);

	if (fd < 0) 
	{
		printf("open i2c device failure!");
		return FAILURE;
	}

	for(i = 0; i < 100; i++)
	{
		buffer[i] = i;
	}
	
	write(fd, &buffer, 100);

	close(fd);
#endif

#if 1
	/* read default EEPROM(0~63) bytes */
	fd = open("/sys/bus/i2c/devices/1-0050/eeprom", O_RDWR);

	if (fd < 0) 
	{
		printf("open i2c device failure!");
		return FAILURE;
	}

	memset(buffer,0xff,sizeof(buffer));
	read(fd, &buffer, 100);

	for(i = 0; i < 100; i++)
	{
		printf("%d - 0x%02x = %d\n", i, buffer[i], buffer[i]);
	}

	close(fd);
#endif

	rs = eeprom_fini();	

	if(rs)
		return FAILURE;
	
	return NOERROR;
}
