/*
 * This file is part of the flashrom project.
 *
 * Copyright (C) 2009 Paul Fox <pgf@laptop.org>
 * 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"

char *ft2232spi_param = NULL;

#if FT2232_SPI_SUPPORT == 1

#include <ftdi.h>

/* the 'H' chips can run internally at either 12Mhz or 60Mhz.
 * the non-H chips can only run at 12Mhz. */
#define CLOCK_5X 1

/* in either case, the divisor is a simple integer clock divider. 
 * if CLOCK_5X is set, this divisor divides 30Mhz, else it
 * divides 6Mhz */
#define DIVIDE_BY 3  // e.g. '3' will give either 10Mhz or 2Mhz spi clock


static struct ftdi_context ftdic_context;

int send_buf(struct ftdi_context *ftdic, const unsigned char *buf, int size)
{
	int r;
	r = ftdi_write_data(ftdic, (unsigned char *) buf, size);
	if (r < 0) {
		fprintf(stderr, "ftdi_write_data: %d, %s\n", r,
				ftdi_get_error_string(ftdic));
		return 1;
	}
	return 0;
}

int get_buf(struct ftdi_context *ftdic, const unsigned char *buf, int size)
{
	int r;
	r = ftdi_read_data(ftdic, (unsigned char *) buf, size);
	if (r < 0) {
		fprintf(stderr, "ftdi_read_data: %d, %s\n", r,
				ftdi_get_error_string(ftdic));
		return 1;
	}
	return 0;
}

int ft2232_spi_init(void)
{
	int f;
	struct ftdi_context *ftdic = &ftdic_context;
	unsigned char buf[512];
	unsigned char port_val = 0;
	char *portpos = NULL;
	int ft2232_type = FTDI_FT4232H;
	enum ftdi_interface ft2232_interface = INTERFACE_B;

	if (ftdi_init(ftdic) < 0) {
		fprintf(stderr, "ftdi_init failed\n");
		return EXIT_FAILURE;
	}

	if (ft2232spi_param && !strlen(ft2232spi_param)) {
		free(ft2232spi_param);
		ft2232spi_param = NULL;
	}
	if (ft2232spi_param) {
		if (strstr(ft2232spi_param, "2232"))
			ft2232_type = FTDI_FT2232H;
		if (strstr(ft2232spi_param, "4232"))
			ft2232_type = FTDI_FT4232H;
		portpos = strstr(ft2232spi_param, "port=");
		if (portpos) {
			portpos += 5;
			switch (toupper(*portpos)) {
			case 'A':
				ft2232_interface = INTERFACE_A;
				break;
			case 'B':
				ft2232_interface = INTERFACE_B;
				break;
			default:
				fprintf(stderr, "Invalid interface specified, "
					"using default.\n");
			}
		}
		free(ft2232spi_param);
	}
	printf_debug("Using device type %s ",
		     (ft2232_type == FTDI_FT2232H) ? "2232H" : "4232H");
	printf_debug("interface %s\n",
		     (ft2232_interface == INTERFACE_A) ? "A" : "B");

	f = ftdi_usb_open(ftdic, 0x0403, ft2232_type);

	if (f < 0 && f != -5) {
		fprintf(stderr, "Unable to open ftdi device: %d (%s)\n", f,
				ftdi_get_error_string(ftdic));
		exit(-1);
	}

	if (ftdi_set_interface(ftdic, ft2232_interface) < 0) {
		fprintf(stderr, "Unable to select interface: %s\n",
				ftdic->error_str);
	}

	if (ftdi_usb_reset(ftdic) < 0) {
		fprintf(stderr, "Unable to reset ftdi device\n");
	}

	if (ftdi_set_latency_timer(ftdic, 2) < 0) {
		fprintf(stderr, "Unable to set latency timer\n");
	}

	if (ftdi_write_data_set_chunksize(ftdic, 512)) {
		fprintf(stderr, "Unable to set chunk size\n");
	}

	if (ftdi_set_bitmode(ftdic, 0x00, 2) < 0) {
		fprintf(stderr, "Unable to set bitmode\n");
	}

#if CLOCK_5X
	printf_debug("Disable divide-by-5 front stage\n");
	buf[0] = 0x8a;		/* disable divide-by-5 */
	if (send_buf(ftdic, buf, 1))
		return -1;
#define MPSSE_CLK 60.0

#else

#define MPSSE_CLK 12.0

#endif
	printf_debug("Set clock divisor\n");
	buf[0] = 0x86;		/* command "set divisor" */
	/* valueL/valueH are (desired_divisor - 1) */
	buf[1] = (DIVIDE_BY-1) & 0xff;
	buf[2] = ((DIVIDE_BY-1) >> 8) & 0xff;
	if (send_buf(ftdic, buf, 3))
		return -1;

	printf("SPI clock is %fMHz\n",
		(double)(MPSSE_CLK / (((DIVIDE_BY-1) + 1) * 2)));

	/* Disconnect TDI/DO to TDO/DI for Loopback */
	printf_debug("No loopback of tdi/do tdo/di\n");
	buf[0] = 0x85;
	if (send_buf(ftdic, buf, 1))
		return -1;

	printf_debug("Set data bits\n");
	/* Set data bits low-byte command:
	 *  value: 0x08  CS=high, DI=low, DO=low, SK=low
	 *    dir: 0x0b  CS=output, DI=input, DO=output, SK=output
	 */
#define CS_BIT 0x08

	buf[0] = SET_BITS_LOW;
	buf[1] = (port_val = CS_BIT);
	buf[2] = 0x0b;
	if (send_buf(ftdic, buf, 3))
		return -1;

	printf_debug("\nft2232 chosen\n");

	buses_supported = CHIP_BUSTYPE_SPI;
	spi_controller = SPI_CONTROLLER_FT2232;

	return 0;
}

int ft2232_spi_command(unsigned int writecnt, unsigned int readcnt,
		const unsigned char *writearr, unsigned char *readarr)
{
	struct ftdi_context *ftdic = &ftdic_context;
	static unsigned char *buf = NULL;
	unsigned char port_val = 0;
	int i, ret = 0;

	buf = realloc(buf, writecnt + readcnt + 100);
	if (!buf) {
		fprintf(stderr, "Out of memory!\n");
		exit(1);
	}

	i = 0;

	/* minimize USB transfers by packing as many commands
	 * as possible together.  if we're not expecting to
	 * read, we can assert CS, write, and deassert CS all
	 * in one shot.  if reading, we do three separate
	 * operations. */
	printf_debug("Assert CS#\n");
	buf[i++] = SET_BITS_LOW;
	buf[i++] = (port_val &= ~CS_BIT);
	buf[i++] = 0x0b;

	if (writecnt) {
		buf[i++] = 0x11;
		buf[i++] = (writecnt - 1) & 0xff;
		buf[i++] = ((writecnt - 1) >> 8) & 0xff;
		memcpy(buf+i, writearr, writecnt);
		i += writecnt;
	}

	/* optionally terminate this batch of commands with a
	 * read command, then do the fetch of the results.
	 */
	if (readcnt) {
		buf[i++] = 0x20;
		buf[i++] = (readcnt - 1) & 0xff;
		buf[i++] = ((readcnt - 1) >> 8) & 0xff;
		ret = send_buf(ftdic, buf, i);
		i = 0;
		if (ret) goto deassert_cs;

		/* FIXME: This is unreliable. There's no guarantee that we read
		 * the response directly after sending the read command.
		 * We may be scheduled out etc.
		 */
		ret = get_buf(ftdic, readarr, readcnt);

	}

deassert_cs:
	printf_debug("De-assert CS#\n");
	buf[i++] = SET_BITS_LOW;
	buf[i++] = (port_val |= CS_BIT);
	buf[i++] = 0x0b;
	if (send_buf(ftdic, buf, i))
		return -1;

	return ret;
}

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

int ft2232_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;

		spi_write_enable();
		if ((r = spi_nbyte_program(i, &buf[i], l))) {
			fprintf(stderr, "%s: write fail %d\n", __FUNCTION__, r);
			// spi_write_disable();  chip does this for us
			return 1;
		}
		
		while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
			/* loop */;
	}
	// spi_write_disable();  chip does this for us

	return 0;
}

#else
int ft2232_spi_init(void)
{
	fprintf(stderr, "FT2232 SPI support was not compiled in\n");
	exit(1);
}

int ft2232_spi_command(unsigned int writecnt, unsigned int readcnt,
		const unsigned char *writearr, unsigned char *readarr)
{
	fprintf(stderr, "FT2232 SPI support was not compiled in\n");
	exit(1);
}

int ft2232_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len)
{
	fprintf(stderr, "FT2232 SPI support was not compiled in\n");
	exit(1);
}

int ft2232_spi_write_256(struct flashchip *flash, uint8_t *buf)
{
	fprintf(stderr, "FT2232 SPI support was not compiled in\n");
	exit(1);
}
#endif
