/* LED blink tool (C) 2002-11-11 Georg Lukas <georg@boerde.de>
 * 
 * WARNING: This is only a quick hack. YOU GET NO WARRANTY!!
 *
 * Ok, this little tool has three modes of operation:
 *
 * $ led	- resets the LED to permanent orange
 * $ led X Y	- sets LED mode to X and register to Y (if you have fun
 * 		  experimenting with the possibilities on a low level...)
 * $ led xxxx	- each x can be:
 * 			g = green
 * 			o = orange
 * 			r = red
 * 			everything else = off
 * 		  this allows to specify a sequence of four colors which are
 * 		  displayed in a loop. try "blink rogo" for weird traffic
 * 		  lights ;-)
 *
 * 		  					Georg
 * */

#include <fcntl.h>
#include "i2c-dev.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "xbox.h"

int fd;
char *fname;
char *devfsname = "/dev/i2c/0";
char *nondevfsname = "/dev/i2c-0";

void checkPIC() {
	if ((fd = open(devfsname, O_RDWR)) < 0) {
		if ((fd=open(nondevfsname,O_RDWR))<0) {
			fprintf(stderr, "Error - failed to open EITHER /dev/i2c/0 or /dev/i2c-0\n    - you must be root and have the correct i2c modules loaded.\n");
			exit(1);
		} else {
			fname = malloc (strlen(nondevfsname));
			strncpy (fname, nondevfsname, strlen(nondevfsname));
		}
	} else {
		fname = malloc (strlen(devfsname));
		strncpy (fname, devfsname, strlen(devfsname));
	}
}

int main(int argc, char *argv[]) {
	char *x;
	int mode, reg, r, g;

	checkPIC();

	if ((argc==2) && (strlen(argv[1])==4)) {
		mode = 1;
		x = argv[1];
		r = g = 0;
		while (*x) {
			r *= 2;
			g *= 2;
			switch (*x) {
			case 'r' : r++; break;
			case 'g' : g++; break;
			case 'o' : r++; g++; break;
			}
			x++;
		}
		reg = ((r<<4) & 0xF0) + (g & 0xF);
	} else if (argc > 2) {
		mode = atoi(argv[1]);
		reg = atoi(argv[2]);
	} else {
		mode = 1;
		reg = 0xff;
	}
	if ((fd = open(fname, O_RDWR)) < 0) {
		fprintf(stderr, "Error in open(%s, O_RDWR): %s\n", fname, strerror(errno));
		return 1;
	}

	if (ioctl(fd,I2C_SLAVE_FORCE,PIC_ADDRESS) < 0) {
		fprintf(stderr,"Error: Could not set address to %d: %s\n",PIC_ADDRESS,strerror(errno));
		return 2;
	}

	i2c_smbus_write_byte_data(fd,LED_MODE,mode);
	i2c_smbus_write_byte_data(fd,LED_REGISTER,reg);

	close(fd);

	return 0;
}
