/*
 * 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];
	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 (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] = (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_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;
	unsigned char port_val = 0;
	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++] = (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;

	spi_disable_blockprotect();
	/* Erase first */
	printf("Erasing flash before programming... ");
	if (flash->erase(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", __FUNCTION__, r);
			return 1;
		}
		
		while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
			/* loop */;
	}

	return 0;
}

#endif
