/* Driver for ATMEL DataFlash support
 * Author : Hamid Ikdoumi (Atmel)
 *
 * 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 <config.h>
#include <common.h>

#ifdef CONFIG_HAS_DATAFLASH
#include <dataflash.h>

/*
 * spi.c API
 */
extern unsigned int AT91F_SpiWrite(AT91PS_DataflashDesc pDesc);
extern void AT91F_SpiEnable(int cs);

#define AT91C_TIMEOUT_WRDY			200000

/*----------------------------------------------------------------------*/
/* \fn    AT91F_DataFlashSendCommand					*/
/* \brief Generic function to send a command to the dataflash		*/
/*----------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashSendCommand(AT91PS_DataFlash pDataFlash,
						 unsigned char OpCode,
						 unsigned int CmdSize,
						 unsigned int DataflashAddress)
{
	unsigned int adr;

	if ((pDataFlash->pDataFlashDesc->state) != IDLE)
		return DATAFLASH_BUSY;

	/* process the address to obtain page address and byte address */
	adr = ((DataflashAddress / (pDataFlash->pDevice->pages_size)) <<
		pDataFlash->pDevice->page_offset) +
			(DataflashAddress % (pDataFlash->pDevice->pages_size));

	/* fill the command buffer */
	pDataFlash->pDataFlashDesc->command[0] = OpCode;
	if (pDataFlash->pDevice->pages_number >= 16384) {
		pDataFlash->pDataFlashDesc->command[1] =
			(unsigned char)((adr & 0x0F000000) >> 24);
		pDataFlash->pDataFlashDesc->command[2] =
			(unsigned char)((adr & 0x00FF0000) >> 16);
		pDataFlash->pDataFlashDesc->command[3] =
			(unsigned char)((adr & 0x0000FF00) >> 8);
		pDataFlash->pDataFlashDesc->command[4] =
			(unsigned char)(adr & 0x000000FF);
	} else {
		pDataFlash->pDataFlashDesc->command[1] =
			(unsigned char)((adr & 0x00FF0000) >> 16);
		pDataFlash->pDataFlashDesc->command[2] =
			(unsigned char)((adr & 0x0000FF00) >> 8);
		pDataFlash->pDataFlashDesc->command[3] =
			(unsigned char)(adr & 0x000000FF);
		pDataFlash->pDataFlashDesc->command[4] = 0;
	}
	pDataFlash->pDataFlashDesc->command[5] = 0;
	pDataFlash->pDataFlashDesc->command[6] = 0;
	pDataFlash->pDataFlashDesc->command[7] = 0;

	/* Initialize the SpiData structure for the spi write fuction */
	pDataFlash->pDataFlashDesc->tx_cmd_pt =
		pDataFlash->pDataFlashDesc->command;
	pDataFlash->pDataFlashDesc->tx_cmd_size = CmdSize;
	pDataFlash->pDataFlashDesc->rx_cmd_pt =
		pDataFlash->pDataFlashDesc->command;
	pDataFlash->pDataFlashDesc->rx_cmd_size = CmdSize;

	/* send the command and read the data */
	return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
}

/*----------------------------------------------------------------------*/
/* \fn    AT91F_DataFlashGetStatus					*/
/* \brief Read the status register of the dataflash			*/
/*----------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc)
{
	AT91S_DataFlashStatus status;

	/* if a transfert is in progress ==> return 0 */
	if ((pDesc->state) != IDLE)
		return DATAFLASH_BUSY;

	/* first send the read status command (D7H) */
	pDesc->command[0] = DB_STATUS;
	pDesc->command[1] = 0;

	pDesc->DataFlash_state = GET_STATUS;
	pDesc->tx_data_size = 0;	/* Transmit the command */
	/* and receive response */
	pDesc->tx_cmd_pt = pDesc->command;
	pDesc->rx_cmd_pt = pDesc->command;
	pDesc->rx_cmd_size = 2;
	pDesc->tx_cmd_size = 2;
	status = AT91F_SpiWrite(pDesc);

	pDesc->DataFlash_state = *((unsigned char *)(pDesc->rx_cmd_pt) + 1);

	return status;
}

/*----------------------------------------------------------------------*/
/* \fn    AT91F_DataFlashWaitReady					*/
/* \brief wait for dataflash ready (bit7 of the status register == 1)	*/
/*----------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashWaitReady(AT91PS_DataflashDesc
						pDataFlashDesc,
						unsigned int timeout)
{
	pDataFlashDesc->DataFlash_state = IDLE;

	do {
		AT91F_DataFlashGetStatus(pDataFlashDesc);
		timeout--;
	} while (((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) &&
		 (timeout > 0));

	if ((pDataFlashDesc->DataFlash_state & 0x80) != 0x80)
		return DATAFLASH_ERROR;

	return DATAFLASH_OK;
}

/*--------------------------------------------------------------------------*/
/* Function Name       : AT91F_DataFlashContinuousRead 			    */
/* Object              : Continuous stream Read 			    */
/* Input Parameters    : DataFlash Service				    */
/*						: <src> = dataflash address */
/*                     : <*dataBuffer> = data buffer pointer		    */
/*                     : <sizeToRead> = data buffer size		    */
/* Return value		: State of the dataflash			    */
/*--------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashContinuousRead(
				AT91PS_DataFlash pDataFlash,
				int src,
				unsigned char *dataBuffer,
				int sizeToRead)
{
	AT91S_DataFlashStatus status;
	/* Test the size to read in the device */
	if ((src + sizeToRead) >
			(pDataFlash->pDevice->pages_size *
				(pDataFlash->pDevice->pages_number)))
		return DATAFLASH_MEMORY_OVERFLOW;

	pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
	pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead;
	pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
	pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead;

	status = AT91F_DataFlashSendCommand(
			pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src);
	/* Send the command to the dataflash */
	return (status);
}

/*---------------------------------------------------------------------------*/
/* Function Name       : AT91F_DataFlashPagePgmBuf			     */
/* Object              : Main memory page program thru buffer 1 or buffer 2  */
/* Input Parameters    : DataFlash Service				     */
/*						: <*src> = Source buffer     */
/*                     : <dest> = dataflash destination address		     */
/*                     : <SizeToWrite> = data buffer size		     */
/* Return value		: State of the dataflash			     */
/*---------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashPagePgmBuf(AT91PS_DataFlash pDataFlash,
						unsigned char *src,
						unsigned int dest,
						unsigned int SizeToWrite)
{
	int cmdsize;
	pDataFlash->pDataFlashDesc->tx_data_pt = src;
	pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite;
	pDataFlash->pDataFlashDesc->rx_data_pt = src;
	pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;

	cmdsize = 4;
	/* Send the command to the dataflash */
	if (pDataFlash->pDevice->pages_number >= 16384)
		cmdsize = 5;
	return (AT91F_DataFlashSendCommand(
			pDataFlash, DB_PAGE_PGM_BUF1, cmdsize, dest));
}

/*---------------------------------------------------------------------------*/
/* Function Name       : AT91F_MainMemoryToBufferTransfert		     */
/* Object              : Read a page in the SRAM Buffer 1 or 2		     */
/* Input Parameters    : DataFlash Service				     */
/*                     : Page concerned					     */
/*                     : 						     */
/* Return value		: State of the dataflash			     */
/*---------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfert(
					AT91PS_DataFlash
					pDataFlash,
					unsigned char
					BufferCommand,
					unsigned int page)
{
	int cmdsize;
	/* Test if the buffer command is legal */
	if ((BufferCommand != DB_PAGE_2_BUF1_TRF) &&
			(BufferCommand != DB_PAGE_2_BUF2_TRF)) {
		return DATAFLASH_BAD_COMMAND;
	}

	/* no data to transmit or receive */
	pDataFlash->pDataFlashDesc->tx_data_size = 0;
	cmdsize = 4;
	if (pDataFlash->pDevice->pages_number >= 16384)
		cmdsize = 5;
	return (AT91F_DataFlashSendCommand(
			pDataFlash, BufferCommand, cmdsize,
			page * pDataFlash->pDevice->pages_size));
}

/*-------------------------------------------------------------------------- */
/* Function Name       : AT91F_DataFlashWriteBuffer			     */
/* Object              : Write data to the internal sram buffer 1 or 2	     */
/* Input Parameters    : DataFlash Service				     */
/*			: <BufferCommand> = command to write buffer1 or 2    */
/*                     : <*dataBuffer> = data buffer to write		     */
/*                     : <bufferAddress> = address in the internal buffer    */
/*                     : <SizeToWrite> = data buffer size		     */
/* Return value		: State of the dataflash			     */
/*---------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer(
					AT91PS_DataFlash pDataFlash,
					unsigned char BufferCommand,
					unsigned char *dataBuffer,
					unsigned int bufferAddress,
					int SizeToWrite)
{
	int cmdsize;
	/* Test if the buffer command is legal */
	if ((BufferCommand != DB_BUF1_WRITE) &&
			(BufferCommand != DB_BUF2_WRITE)) {
		return DATAFLASH_BAD_COMMAND;
	}

	/* buffer address must be lower than page size */
	if (bufferAddress > pDataFlash->pDevice->pages_size)
		return DATAFLASH_BAD_ADDRESS;

	if ((pDataFlash->pDataFlashDesc->state) != IDLE)
		return DATAFLASH_BUSY;

	/* Send first Write Command */
	pDataFlash->pDataFlashDesc->command[0] = BufferCommand;
	pDataFlash->pDataFlashDesc->command[1] = 0;
	if (pDataFlash->pDevice->pages_number >= 16384) {
		pDataFlash->pDataFlashDesc->command[2] = 0;
		pDataFlash->pDataFlashDesc->command[3] =
			(unsigned char)(((unsigned int)(bufferAddress &
							pDataFlash->pDevice->
							byte_mask)) >> 8);
		pDataFlash->pDataFlashDesc->command[4] =
			(unsigned char)((unsigned int)bufferAddress & 0x00FF);
		cmdsize = 5;
	} else {
		pDataFlash->pDataFlashDesc->command[2] =
			(unsigned char)(((unsigned int)(bufferAddress &
							pDataFlash->pDevice->
							byte_mask)) >> 8);
		pDataFlash->pDataFlashDesc->command[3] =
			(unsigned char)((unsigned int)bufferAddress & 0x00FF);
		pDataFlash->pDataFlashDesc->command[4] = 0;
		cmdsize = 4;
	}

	pDataFlash->pDataFlashDesc->tx_cmd_pt =
		pDataFlash->pDataFlashDesc->command;
	pDataFlash->pDataFlashDesc->tx_cmd_size = cmdsize;
	pDataFlash->pDataFlashDesc->rx_cmd_pt =
		pDataFlash->pDataFlashDesc->command;
	pDataFlash->pDataFlashDesc->rx_cmd_size = cmdsize;

	pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
	pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
	pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;
	pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite;

	return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
}

/*---------------------------------------------------------------------------*/
/* Function Name       : AT91F_PageErase                                     */
/* Object              : Erase a page 					     */
/* Input Parameters    : DataFlash Service				     */
/*                     : Page concerned					     */
/*                     : 						     */
/* Return value		: State of the dataflash			     */
/*---------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_PageErase(
					AT91PS_DataFlash pDataFlash,
					unsigned int page)
{
	int cmdsize;
	/* Test if the buffer command is legal */
	/* no data to transmit or receive */
	pDataFlash->pDataFlashDesc->tx_data_size = 0;

	cmdsize = 4;
	if (pDataFlash->pDevice->pages_number >= 16384)
		cmdsize = 5;
	return (AT91F_DataFlashSendCommand(pDataFlash,
				DB_PAGE_ERASE, cmdsize,
				page * pDataFlash->pDevice->pages_size));
}

/*---------------------------------------------------------------------------*/
/* Function Name       : AT91F_BlockErase                                    */
/* Object              : Erase a Block 					     */
/* Input Parameters    : DataFlash Service				     */
/*                     : Page concerned					     */
/*                     : 						     */
/* Return value		: State of the dataflash			     */
/*---------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_BlockErase(
				AT91PS_DataFlash pDataFlash,
				unsigned int block)
{
	int cmdsize;
	/* Test if the buffer command is legal */
	/* no data to transmit or receive */
	pDataFlash->pDataFlashDesc->tx_data_size = 0;
	cmdsize = 4;
	if (pDataFlash->pDevice->pages_number >= 16384)
		cmdsize = 5;
	return (AT91F_DataFlashSendCommand(pDataFlash, DB_BLOCK_ERASE, cmdsize,
					block * 8 *
					pDataFlash->pDevice->pages_size));
}

/*---------------------------------------------------------------------------*/
/* Function Name       : AT91F_WriteBufferToMain			     */
/* Object              : Write buffer to the main memory		     */
/* Input Parameters    : DataFlash Service				     */
/*		: <BufferCommand> = command to send to buffer1 or buffer2    */
/*                     : <dest> = main memory address			     */
/* Return value		: State of the dataflash			     */
/*---------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_WriteBufferToMain(AT91PS_DataFlash pDataFlash,
					unsigned char BufferCommand,
					unsigned int dest)
{
	int cmdsize;
	/* Test if the buffer command is correct */
	if ((BufferCommand != DB_BUF1_PAGE_PGM) &&
			(BufferCommand != DB_BUF1_PAGE_ERASE_PGM) &&
			(BufferCommand != DB_BUF2_PAGE_PGM) &&
			(BufferCommand != DB_BUF2_PAGE_ERASE_PGM))
		return DATAFLASH_BAD_COMMAND;

	/* no data to transmit or receive */
	pDataFlash->pDataFlashDesc->tx_data_size = 0;

	cmdsize = 4;
	if (pDataFlash->pDevice->pages_number >= 16384)
		cmdsize = 5;
	/* Send the command to the dataflash */
	return (AT91F_DataFlashSendCommand(pDataFlash, BufferCommand,
						cmdsize, dest));
}

/*---------------------------------------------------------------------------*/
/* Function Name       : AT91F_PartialPageWrite				     */
/* Object              : Erase partielly a page				     */
/* Input Parameters    : <page> = page number				     */
/*			: <AdrInpage> = adr to begin the fading		     */
/*                     : <length> = Number of bytes to erase		     */
/*---------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_PartialPageWrite(AT91PS_DataFlash pDataFlash,
					unsigned char *src,
					unsigned int dest,
					unsigned int size)
{
	unsigned int page;
	unsigned int AdrInPage;

	page = dest / (pDataFlash->pDevice->pages_size);
	AdrInPage = dest % (pDataFlash->pDevice->pages_size);

	/* Read the contents of the page in the Sram Buffer */
	AT91F_MainMemoryToBufferTransfert(pDataFlash, DB_PAGE_2_BUF1_TRF, page);
	AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
				 AT91C_TIMEOUT_WRDY);
	/*Update the SRAM buffer */
	AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src,
					AdrInPage, size);

	AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
					AT91C_TIMEOUT_WRDY);

	/* Erase page if a 128 Mbits device */
	if (pDataFlash->pDevice->pages_number >= 16384) {
		AT91F_PageErase(pDataFlash, page);
		/* Rewrite the modified Sram Buffer in the main memory */
		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
					 AT91C_TIMEOUT_WRDY);
	}

	/* Rewrite the modified Sram Buffer in the main memory */
	return (AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM,
					(page *
					 pDataFlash->pDevice->pages_size)));
}

/*---------------------------------------------------------------------------*/
/* Function Name       : AT91F_DataFlashWrite				     */
/* Object              :						     */
/* Input Parameters    : <*src> = Source buffer				     */
/*                     : <dest> = dataflash adress			     */
/*                     : <size> = data buffer size			     */
/*---------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashWrite(AT91PS_DataFlash pDataFlash,
						unsigned char *src,
						int dest, int size)
{
	unsigned int length;
	unsigned int page;
	unsigned int status;

	AT91F_SpiEnable(pDataFlash->pDevice->cs);

	if ((dest + size) > (pDataFlash->pDevice->pages_size *
			(pDataFlash->pDevice->pages_number)))
		return DATAFLASH_MEMORY_OVERFLOW;

	/* If destination does not fit a page start address */
	if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size))) != 0) {
		length =
			pDataFlash->pDevice->pages_size -
			(dest % ((unsigned int)(pDataFlash->pDevice->pages_size)));

		if (size < length)
			length = size;

		if (!AT91F_PartialPageWrite(pDataFlash, src, dest, length))
			return DATAFLASH_ERROR;

		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
					 AT91C_TIMEOUT_WRDY);

		/* Update size, source and destination pointers */
		size -= length;
		dest += length;
		src += length;
	}

	while ((size - pDataFlash->pDevice->pages_size) >= 0) {
		/* program dataflash page */
		page = (unsigned int)dest / (pDataFlash->pDevice->pages_size);

		status = AT91F_DataFlashWriteBuffer(pDataFlash,
					DB_BUF1_WRITE, src, 0,
					pDataFlash->pDevice->
					pages_size);
		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
					 AT91C_TIMEOUT_WRDY);

		status = AT91F_PageErase(pDataFlash, page);
		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
					 AT91C_TIMEOUT_WRDY);
		if (!status)
			return DATAFLASH_ERROR;

		status = AT91F_WriteBufferToMain(pDataFlash,
					 DB_BUF1_PAGE_PGM, dest);
		if (!status)
			return DATAFLASH_ERROR;

		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
					 AT91C_TIMEOUT_WRDY);

		/* Update size, source and destination pointers */
		size -= pDataFlash->pDevice->pages_size;
		dest += pDataFlash->pDevice->pages_size;
		src += pDataFlash->pDevice->pages_size;
	}

	/* If still some bytes to read */
	if (size > 0) {
		/* program dataflash page */
		if (!AT91F_PartialPageWrite(pDataFlash, src, dest, size))
			return DATAFLASH_ERROR;

		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
					 AT91C_TIMEOUT_WRDY);
	}
	return DATAFLASH_OK;
}

/*---------------------------------------------------------------------------*/
/* Function Name       : AT91F_DataFlashRead 				     */
/* Object              : Read a block in dataflash			     */
/* Input Parameters    : 						     */
/* Return value		: 						     */
/*---------------------------------------------------------------------------*/
int AT91F_DataFlashRead(AT91PS_DataFlash pDataFlash,
			unsigned long addr, unsigned long size, char *buffer)
{
	unsigned long SizeToRead;

	AT91F_SpiEnable(pDataFlash->pDevice->cs);

	if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
					AT91C_TIMEOUT_WRDY) != DATAFLASH_OK)
		return -1;

	while (size) {
		SizeToRead = (size < 0x8000) ? size : 0x8000;

		if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
					AT91C_TIMEOUT_WRDY) !=
						DATAFLASH_OK)
			return -1;

		if (AT91F_DataFlashContinuousRead(pDataFlash, addr,
						(uchar *) buffer,
						SizeToRead) != DATAFLASH_OK)
			return -1;

		size -= SizeToRead;
		addr += SizeToRead;
		buffer += SizeToRead;
	}

	return DATAFLASH_OK;
}

/*---------------------------------------------------------------------------*/
/* Function Name       : AT91F_DataflashProbe 				     */
/* Object              : 						     */
/* Input Parameters    : 						     */
/* Return value	       : Dataflash status register			     */
/*---------------------------------------------------------------------------*/
int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc)
{
	AT91F_SpiEnable(cs);
	AT91F_DataFlashGetStatus(pDesc);
	return ((pDesc->command[1] == 0xFF) ? 0 : pDesc->command[1] & 0x3C);
}
#endif
