/* 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
