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

#include <common.h>
#include <eeprom.h>
#include <asm/ic/ssi.h>

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