/*
 * 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
 */

#if FT2232_SPI_SUPPORT == 1

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "flash.h"
#include "spi.h"
#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];
	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 (programmer_param && !strlen(programmer_param)) {
		free(programmer_param);
		programmer_param = NULL;
	}
	if (programmer_param) {
		if (strstr(programmer_param, "2232"))
			ft2232_type = FTDI_FT2232H;
		if (strstr(programmer_param, "4232"))
			ft2232_type = FTDI_FT4232H;
		portpos = strstr(programmer_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(programmer_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] = 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_send_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;
	int i, ret = 0;

	if (writecnt > 65536 || readcnt > 65536)
		return SPI_INVALID_LENGTH;

	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++] = 0 & ~CS_BIT; /* assertive */
	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 == 0) {
			/* 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);
		}

	}

	printf_debug("De-assert CS#\n");
	buf[i++] = SET_BITS_LOW;
	buf[i++] = 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;

	spi_disable_blockprotect();
	/* Erase first */
	printf("Erasing flash before programming... ");
	if (erase_flash(flash)) {
		fprintf(stderr, "ERASE FAILED!\n");
		return -1;
	}
	printf("done.\n");
	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;
}

#endif
