/*
*
* h3000 on board EEPROM Decode Utility
*
* Copyright 2000 Compaq Computer Corporation.
*
* Use consistent with the GNU GPL is permitted,
* provided that this copyright notice is
* preserved in its entirety in all copies and derived works.
*
* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
* FITNESS FOR ANY PARTICULAR PURPOSE.
*
* Author: Charles Flynn.
*
* WARNING!!: The ioctl() interface will change in near future versions.
*/
                                                                

#include <stdio.h>
#include <fcntl.h>
#include <linux/ioctl.h>
#if 0
#include "h3600_ts.h"           /* IOCTL definitions */
#else
#include <linux/h3600_ts.h>
#endif


/* The ioctl can be called from a ts, tsraw or key file descriptor */
#define DEV_NODE "/dev/h3600_ts"

#define MAX_EEPROM_FIELDS	13
#define SIZEOF_TMPBUF	80		/* dont know what's best size here */

typedef struct {
	char name[32];
	unsigned int len;	/* as a multiple of 16 bit words */
} FIELD;

FIELD fields[MAX_EEPROM_FIELDS] =
{
	{"Version               ",5 },	
	{"Serial Number         ",20},
	{"ModelID               ",10},
	{"Product Revision Level",5},
	{"Product ID            ",1},
	{"Frame rate            ",1},
	{"Page Mode             ",1},
	{"Country ID            ",1},
	{"Colour Display?       ",1},
	{"Size of ROM           ",1},
	{"Size of RAM           ",1},
	{"Num Horizontal Pixels ",1},	/* 13 fields */
	{"Num Vertical Pixels   ",1}
};


main(int argc, char ** argv )
{
	EEPROM_READ er;
	FIELD * pField;
	int fd;
	int err;
	unsigned offset=0;
	unsigned count = 0;
	unsigned short val;
	unsigned i;
	unsigned notString=0;
	unsigned short tmp;
	char tmpbuf[SIZEOF_TMPBUF];

	fd = open(DEV_NODE,O_RDWR);
	if( fd == -1 )
	{
		printf("\nUnable to open %s\n",DEV_NODE);
		exit(0);
	}

	for(i=0; i < MAX_EEPROM_FIELDS; i++)
	{
	    pField = &fields[i];
	    er.len=pField->len;
	    if( i  )
	      offset += fields[i-1].len;

	    er.addr=offset;
	    count=0;

	    if( er.len == 1 )	/* TODO kludge to detect a string */
	    {
		notString=1;
		err = ioctl(fd,READ_EEPROM,(void *)&er);
		if( !err )
		{
		    count=er.len;
		    val=er.buff[0];
		}
	    }
	    else /* fixed length string - keep reading until null bytes*/
	    {
		notString=0;
		/* here we read 2 bytes at each offset */
		er.len=1;
		do
		{
		    err = ioctl(fd,READ_EEPROM,(void *)&er);
		    tmpbuf[count]= (unsigned char)( er.buff[0] >> 8);
#if 0
		    printf(" tmpbuf[%d]=%02x buff=%04x\n", 
			count,tmpbuf[count],er.buff[0]);
#endif
		    ++count;
		    er.addr = offset + count;
		} while( !err && er.buff[0] );

	    }

	    /* Enter here with known word count and data in tmpbuf */

	    if(err)
	    {
		perror("A:bad ioctl\n");
                close(fd);
                exit(1);
	    }

	    /* TODO the following nested IFs need tidy up */
#if 0
	    printf("offset=%d count=%d\n",offset,count);
#endif
	    if( count )		/*for strings count includes the terminator*/
	    {
		    if( notString )
		    {
			printf("[%02d:%02d]%s\t %04x\n",
				count,offset,pField->name,val);
		    }
		    else	/* string */
		    {
		        printf("[%02d:%02d]%s\t %s\n",
				count,offset,pField->name,tmpbuf);
		    }
	    }
	    else
	    {
		printf("ERROR: nothing read\n");
		break;
	    }
	}

	close (fd);
}
