/*
    This code was original written by Ulrich Radig and modified by
    Embedded Artists AB (www.embeddedartists.com).

    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>
#include <asm/arch/hardware.h>
#include <asm/arch/spi.h>

#define MMC_Enable() PUT32(IO1CLR, 1l << 22)
#define MMC_Disable() PUT32(IO1SET, 1l << 22)
#define mmc_spi_cfg() spi_set_clock(8); spi_set_cfg(0, 1, 0);

static unsigned char Write_Command_MMC (unsigned char *CMD);
static void MMC_Read_Block(unsigned char *CMD, unsigned char *Buffer,
		    unsigned short int Bytes);

/* initialize the hardware */
int mmc_hw_init(void)
{
	unsigned long a;
	unsigned short int Timeout = 0;
	unsigned char b;
	unsigned char CMD[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x95};

	/* set-up GPIO and SPI */
	(*((volatile unsigned long *)PINSEL2)) &= ~(1l << 3); /* clear bit 3 */
	(*((volatile unsigned long *)IO1DIR)) |= (1l << 22); /* set bit 22 (output) */

	MMC_Disable();

	spi_lock();
	spi_set_clock(248);
	spi_set_cfg(0, 1, 0);
	MMC_Enable();

	/* waste some time */
	for(a=0; a < 20000; a++)
		asm("nop");

	/* Put the MMC/SD-card into SPI-mode */
	for (b = 0; b < 10; b++) /* Sends min 74+ clocks to the MMC/SD-card */
		spi_write(0xff);

	/* Sends command CMD0 to MMC/SD-card */
	while (Write_Command_MMC(CMD) != 1) {
		if (Timeout++ > 200) {
			MMC_Disable();
			spi_unlock();
			return(1); /* Abort with command 1 (return 1) */
		}
	}
	/* Sends Command CMD1 an MMC/SD-card */
	Timeout = 0;
	CMD[0] = 0x41;/* Command 1 */
	CMD[5] = 0xFF;

	while (Write_Command_MMC(CMD) != 0) {
		if (Timeout++ > 200) {
			MMC_Disable();
			spi_unlock();
			return (2); /* Abort with command 2 (return 2) */
		}
	}

	MMC_Disable();
	spi_unlock();

	return 0;
}

/* ############################################################################
   Sends a command to the MMC/SD-card
   ######################################################################### */
static unsigned char Write_Command_MMC (unsigned char *CMD)
{
	unsigned char a, tmp = 0xff;
	unsigned short int Timeout = 0;

	MMC_Disable();
	spi_write(0xFF);
	MMC_Enable();

	for (a = 0; a < 0x06; a++)
		spi_write(*CMD++);

	while (tmp == 0xff) {
		tmp = spi_read();
		if (Timeout++ > 5000)
		  break;
	}

	return (tmp);
}

/* ############################################################################
   Routine to read the CID register from the MMC/SD-card (16 bytes)
   ######################################################################### */
void MMC_Read_Block(unsigned char *CMD, unsigned char *Buffer, unsigned short
	int Bytes)
{
	unsigned short int a;

	spi_lock();
	mmc_spi_cfg();
	MMC_Enable();

	if (Write_Command_MMC(CMD) != 0) {
		MMC_Disable();
		spi_unlock();
		return;
	}

	while (spi_read() != 0xfe) {};
	for (a = 0; a < Bytes; a++)
		*Buffer++ = spi_read();

	/* Read the CRC-byte */
	spi_read(); /* CRC - byte is discarded */
	spi_read(); /* CRC - byte is discarded */
	/* set MMC_Chip_Select to high (MMC/SD-card Inaktiv) */
	MMC_Disable();
	spi_unlock();

	return;
}

/* ############################################################################
   Routine to read a block (512 bytes) from the MMC/SD-card
   ######################################################################### */
unsigned char mmc_read_sector (unsigned long addr,unsigned char *Buffer)
{
	/* Command 16 to read aBlocks from the MMC/SD - caed */
	unsigned char CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF};

	/* The address on the MMC/SD-card is in bytes,
	addr is transformed from blocks to bytes and the result is
	placed into the command */

	addr = addr << 9; /* addr = addr * 512 */

	CMD[1] = ((addr & 0xFF000000) >> 24);
	CMD[2] = ((addr & 0x00FF0000) >> 16);
	CMD[3] = ((addr & 0x0000FF00) >> 8 );

	MMC_Read_Block(CMD, Buffer, 512);

	return (0);
}

/* ############################################################################
   Routine to write a block (512 byte) to the MMC/SD-card
   ######################################################################### */
unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer)
{
	unsigned char tmp, a;
	unsigned short int b;
	/* Command 24 to write a block to the MMC/SD - card */
	unsigned char CMD[] = {0x58, 0x00, 0x00, 0x00, 0x00, 0xFF};

	/* The address on the MMC/SD-card is in bytes,
	addr is transformed from blocks to bytes and the result is
	placed into the command */

	addr = addr << 9; /* addr = addr * 512 */

	CMD[1] = ((addr & 0xFF000000) >> 24);
	CMD[2] = ((addr & 0x00FF0000) >> 16);
	CMD[3] = ((addr & 0x0000FF00) >> 8 );

	spi_lock();
	mmc_spi_cfg();
	MMC_Enable();

	/* Send command CMD24 to the MMC/SD-card (Write 1 Block/512 Bytes) */
	tmp = Write_Command_MMC(CMD);
	if (tmp != 0) {
		MMC_Disable();
		spi_unlock();
		return(tmp);
	}

	/* Do a short delay and send a clock-pulse to the MMC/SD-card */
	for (a = 0; a < 100; a++)
		spi_read();

	/* Send a start byte to the MMC/SD-card */
	spi_write(0xFE);

	/* Write the block (512 bytes) to the MMC/SD-card */
	for (b = 0; b < 512; b++)
		spi_write(*Buffer++);

	/* write the CRC-Byte */
	spi_write(0xFF); /* write a dummy CRC */
	spi_write(0xFF); /* CRC code is not used */

	/* Wait for MMC/SD-card busy */
	while (spi_read() != 0xff) {};

	/* set MMC_Chip_Select to high (MMC/SD-card inactive) */
	MMC_Disable();
	spi_unlock();
	return (0);
}

/* #########################################################################
   Routine to read the CSD register from the MMC/SD-card (16 bytes)
   ######################################################################### */
unsigned char mmc_read_csd (unsigned char *Buffer)
{
	/* Command to read the CSD register */
	unsigned char CMD[] = {0x49, 0x00, 0x00, 0x00, 0x00, 0xFF};

	MMC_Read_Block(CMD, Buffer, 16);

	return (0);
}
