/*
 * Copyright (C) 2009
 * Albin Tonnerre, Free Electrons <albin.tonnerre@free-electrons.com>
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <spi.h>

#define SPI_EEPROM_WREN		0x06
#define SPI_EEPROM_RDSR		0x05
#define SPI_EEPROM_READ		0x03
#define SPI_EEPROM_WRITE	0x02

#ifndef CONFIG_DEFAULT_SPI_BUS
#define CONFIG_DEFAULT_SPI_BUS 0
#endif

#ifndef CONFIG_DEFAULT_SPI_MODE
#define CONFIG_DEFAULT_SPI_MODE SPI_MODE_0
#endif

ssize_t spi_read (uchar *addr, int alen, uchar *buffer, int len)
{
	struct spi_slave *slave;
	u8 cmd = SPI_EEPROM_READ;

	slave = spi_setup_slave(CONFIG_DEFAULT_SPI_BUS, 1, 1000000,
			CONFIG_DEFAULT_SPI_MODE);
	if(!slave)
		return 0;

	spi_claim_bus(slave);

	/* command */
	if(spi_xfer(slave, 8, &cmd, NULL, SPI_XFER_BEGIN))
		return -1;

	/*
	 * if alen == 3, addr[0] is the block number, we never use it here. All we
	 * need are the lower 16 bits
	 */
	if (alen == 3)
		addr++;

	/* address, and data */
	if(spi_xfer(slave, 16, addr, NULL, 0))
		return -1;
	if(spi_xfer(slave, 8 * len, NULL, buffer, SPI_XFER_END))
		return -1;

	spi_release_bus(slave);
	spi_free_slave(slave);
	return len;
}

ssize_t spi_write (uchar *addr, int alen, uchar *buffer, int len)
{
	struct spi_slave *slave;
	char buf[3];
	ulong start;

	slave = spi_setup_slave(CONFIG_DEFAULT_SPI_BUS, 1, 1000000,
			CONFIG_DEFAULT_SPI_MODE);
	if (!slave)
		return 0;

	spi_claim_bus(slave);

	buf[0] = SPI_EEPROM_WREN;
	if(spi_xfer(slave, 8, buf, NULL, SPI_XFER_BEGIN | SPI_XFER_END))
		return -1;

	buf[0] = SPI_EEPROM_WRITE;

	/* As for reading, drop addr[0] if alen is 3 */
	if (alen == 3) {
		alen--;
		addr++;
	}

	memcpy(buf + 1, addr, alen);
	/* command + addr, then data */
	if(spi_xfer(slave, 24, buf, NULL, SPI_XFER_BEGIN))
		return -1;
	if(spi_xfer(slave, len * 8, buffer, NULL, SPI_XFER_END))
		return -1;

	start = get_timer(0);
	do {
		buf[0] = SPI_EEPROM_RDSR;
		buf[1] = 0;
		spi_xfer(slave, 16, buf, buf, SPI_XFER_BEGIN | SPI_XFER_END);

		if (!(buf[1] & 1))
			break;

	} while (get_timer(start) < CONFIG_SYS_SPI_WRITE_TOUT);

	if (buf[1] & 1)
		printf ("*** spi_write: Time out while writing!\n");

	spi_release_bus(slave);
	spi_free_slave(slave);
	return len;
}
