/* Three-wire (MicroWire) serial eeprom driver (for 93C46 and compatibles) */

#include <common.h>
#include <ssi.h>


#ifdef CONFIG_MW_EEPROM

/*
 * Serial EEPROM opcodes, including start bit
 */
#define EEP_OPC_ERASE	0x7  /* 3-bit opcode */
#define EEP_OPC_WRITE	0x5  /* 3-bit opcode */
#define EEP_OPC_READ	        0x6  /* 3-bit opcode */

#define EEP_OPC_ERASE_ALL	0x12 /* 5-bit opcode */
#define EEP_OPC_ERASE_EN	0x13 /* 5-bit opcode */
#define EEP_OPC_WRITE_ALL	0x11 /* 5-bit opcode */
#define EEP_OPC_ERASE_DIS	0x10 /* 5-bit opcode */

static int addrlen;

static void mw_eeprom_select(int dev)
{
	ssi_set_interface(2048, 0, 0, 0);
	ssi_chip_select(0);
	udelay(1);
	ssi_chip_select(dev);
	udelay(1);
}

static int mw_eeprom_size(int dev)
{
	int x;
	u16 res;
		
	mw_eeprom_select(dev);
	ssi_tx_byte(EEP_OPC_READ);
	
	res = ssi_txrx_byte(0) << 8;
	res |= ssi_rx_byte();
	for (x = 0; x < 16; x++) {
		if (! (res & 0x8000)) {
			break;
		}
		res <<= 1;
	}
	ssi_chip_select(0);
	
	return x;
}

int mw_eeprom_erase_enable(int dev)
{
	mw_eeprom_select(dev);
	ssi_tx_byte(EEP_OPC_ERASE_EN);
	ssi_tx_byte(0);
	udelay(1);
	ssi_chip_select(0);
		
	return 0;
}

int mw_eeprom_erase_disable(int dev)
{	
	mw_eeprom_select(dev);
	ssi_tx_byte(EEP_OPC_ERASE_DIS);
	ssi_tx_byte(0);
	udelay(1);
	ssi_chip_select(0);
		
	return 0;
}


u32 mw_eeprom_read_word(int dev, int addr)
{
	u16 rcv;
	u16 res;
	int bits;
	
	mw_eeprom_select(dev);
	ssi_tx_byte((EEP_OPC_READ << 5) | ((addr >> (addrlen - 5)) & 0x1f));
	rcv = ssi_txrx_byte(addr << (13 - addrlen));
	res = rcv << (16 - addrlen);
	bits = 4 + addrlen;
	
	while (bits>0) {
		rcv = ssi_rx_byte();
		if (bits > 7) {
			res |= rcv << (bits - 8);
		} else {
			res |= rcv >> (8 - bits);
		}
		bits -= 8;
	}
	
	ssi_chip_select(0);
	
	return res;
}

int mw_eeprom_write_word(int dev, int addr, u16 data)
{
	u8 byte1=0;
	u8 byte2=0;
	
	mw_eeprom_erase_enable(dev);
	mw_eeprom_select(dev);
	
	switch (addrlen) {
	 case 6:
		byte1 = EEP_OPC_WRITE >> 2;
		byte2 = (EEP_OPC_WRITE << 6)&0xc0;
		byte2 |= addr;
		break;
	 case 7:
		byte1 = EEP_OPC_WRITE >> 1;
		byte2 = (EEP_OPC_WRITE << 7)&0x80;
		byte2 |= addr;
		break;
	 case 8:
		byte1 = EEP_OPC_WRITE;
		byte2 = addr;
		break;
	 case 9:
		byte1 = EEP_OPC_WRITE << 1;
		byte1 |= addr >> 8;
		byte2 = addr & 0xff;
		break;
	 case 10:
		byte1 = EEP_OPC_WRITE << 2;
		byte1 |= addr >> 8;
		byte2 = addr & 0xff;
		break;
	 default:
		printf("Unsupported number of address bits: %d\n", addrlen);
		return -1;
		
	}
	
	ssi_tx_byte(byte1);
	ssi_tx_byte(byte2);
	ssi_tx_byte(data >> 8);	
	ssi_tx_byte(data & 0xff);
	ssi_chip_select(0);	
	udelay(10000); /* Worst case */
	mw_eeprom_erase_disable(dev);

	return 0;
}


int mw_eeprom_write(int dev, int addr, u8 *buffer, int len)
{
	int done;
	
	done = 0;
	if (addr & 1) {
		u16 temp = mw_eeprom_read_word(dev, addr >> 1);
		temp &= 0xff00;
		temp |= buffer[0];
		
		mw_eeprom_write_word(dev, addr >> 1, temp);
		len--;
		addr++;
		buffer++;
		done++;
	}
	
	while (len <= 2) {
		mw_eeprom_write_word(dev, addr >> 1, *(u16*)buffer);
		len-=2;
		addr+=2;
		buffer+=2;
		done+=2;
	}

	if (len) {
		u16 temp = mw_eeprom_read_word(dev, addr >> 1);
		temp &= 0x00ff;
		temp |= buffer[0] << 8;
		
		mw_eeprom_write_word(dev, addr >> 1, temp);
		len--;
		addr++;
		buffer++;
		done++;
	}

	return done;
}



int mw_eeprom_read(int dev, int addr, u8 *buffer, int len)
{
	int done;
	
	done = 0;
	if (addr & 1) {
		u16 temp = mw_eeprom_read_word(dev, addr >> 1);
		buffer[0]= temp & 0xff;
		
		len--;
		addr++;
		buffer++;
		done++;
	}
	
	while (len <= 2) {
		*(u16*)buffer = mw_eeprom_read_word(dev, addr >> 1);
		len-=2;
		addr+=2;
		buffer+=2;
		done+=2;
	}

	if (len) {
		u16 temp = mw_eeprom_read_word(dev, addr >> 1);
		buffer[0] = temp >> 8;
		
		len--;
		addr++;
		buffer++;
		done++;
	}

	return done;
}

int mw_eeprom_probe(int dev)
{
	addrlen = mw_eeprom_size(dev);
	
	if (addrlen < 6 || addrlen > 10) {
		return -1;
	}
	return 0;
}

#endif
