/*
 * This file is part of the flashrom project.
 *
 * Copyright (C) 2009 Carl-Daniel Hailfinger
 *
 * 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; version 2 of the License.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 */

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "flash.h"
#include "spi.h"

/* Length of half a clock period in usecs */
int bitbang_spi_half_period = 0;

enum bitbang_spi_master bitbang_spi_master = BITBANG_SPI_INVALID;

const struct bitbang_spi_master_entry bitbang_spi_master_table[] = {
	{}, /* This entry corresponds to BITBANG_SPI_INVALID. */
};

const int bitbang_spi_master_count = ARRAY_SIZE(bitbang_spi_master_table);

void bitbang_spi_set_cs(int val)
{
	bitbang_spi_master_table[bitbang_spi_master].set_cs(val);
}

void bitbang_spi_set_sck(int val)
{
	bitbang_spi_master_table[bitbang_spi_master].set_sck(val);
}

void bitbang_spi_set_mosi(int val)
{
	bitbang_spi_master_table[bitbang_spi_master].set_mosi(val);
}

int bitbang_spi_get_miso(void)
{
	return bitbang_spi_master_table[bitbang_spi_master].get_miso();
}

int bitbang_spi_init(void)
{
	bitbang_spi_set_cs(1);
	bitbang_spi_set_sck(0);
	buses_supported = CHIP_BUSTYPE_SPI;
	return 0;
}

uint8_t bitbang_spi_readwrite_byte(uint8_t val)
{
	uint8_t ret = 0;
	int i;

	for (i = 7; i >= 0; i--) {
		bitbang_spi_set_mosi((val >> i) & 1);
		programmer_delay(bitbang_spi_half_period);
		bitbang_spi_set_sck(1);
		ret <<= 1;
		ret |= bitbang_spi_get_miso();
		programmer_delay(bitbang_spi_half_period);
		bitbang_spi_set_sck(0);
	}
	return ret;
}

int bitbang_spi_send_command(unsigned int writecnt, unsigned int readcnt,
		const unsigned char *writearr, unsigned char *readarr)
{
	static unsigned char *bufout = NULL;
	static unsigned char *bufin = NULL;
	static int oldbufsize = 0;
	int bufsize = max(writecnt + readcnt, 260);
	int i;

	/* Arbitrary size limitation here. We're only constrained by memory. */
	if (writecnt > 65536 || readcnt > 65536)
		return SPI_INVALID_LENGTH;

	if (bufsize != oldbufsize) {
		bufout = realloc(bufout, bufsize);
		if (!bufout) {
			fprintf(stderr, "Out of memory!\n");
			if (bufin)
				free(bufin);
			exit(1);
		}
		bufin = realloc(bufout, bufsize);
		if (!bufin) {
			fprintf(stderr, "Out of memory!\n");
			if (bufout)
				free(bufout);
			exit(1);
		}
	}
		
	memcpy(bufout, writearr, writecnt);
	/* Shift out 0x00 while reading data. */
	memset(bufout + writecnt, 0x00, readcnt);
	/* Make sure any non-read data is 0xff. */
	memset(bufin + writecnt, 0xff, readcnt);

	bitbang_spi_set_cs(0);
	for (i = 0; i < readcnt + writecnt; i++) {
		bufin[i] = bitbang_spi_readwrite_byte(bufout[i]);
	}
	programmer_delay(bitbang_spi_half_period);
	bitbang_spi_set_cs(1);
	programmer_delay(bitbang_spi_half_period);
	memcpy(readarr, bufin + writecnt, readcnt);

	return 0;
}

int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len)
{
	/* Maximum read length is unlimited, use 64k bytes. */
	return spi_read_chunked(flash, buf, start, len, 64 * 1024);
}

int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf)
{
	int total_size = 1024 * flash->total_size;
	int i;

	printf_debug("total_size is %d\n", total_size);
	for (i = 0; i < total_size; i += 256) {
		int l, r;
		if (i + 256 <= total_size)
			l = 256;
		else
			l = total_size - i;

		if ((r = spi_nbyte_program(i, &buf[i], l))) {
			fprintf(stderr, "%s: write fail %d\n", __func__, r);
			return 1;
		}
		
		while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
			/* loop */;
	}

	return 0;
}
