/*
 * This file is part of the flashrom project.
 *
 * Copyright (C) 2012 James Laird <jhl@mafipulation.org>
 *
 * 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
 */

/*
 * Device should be connected as per "active serial" mode:
 *
 *      +---------+------+-----------+
 *      | SPI     | Pin  |  Altera   |
 *      +---------+------+-----------+
 *      | SCLK    | 1    | DCLK      |
 *      | GND     | 2,10 | GND       |
 *      | VCC     | 4    | VCC(TRGT) |
 *      | MISO    | 7    | DATAOUT   |
 *      | /CS     | 8    | nCS       |
 *      | MOSI    | 9    | ASDI      |
 *      +---------+------+-----------+
 *
 * See also the USB-Blaster Download Cable User Guide: http://www.altera.com/literature/ug/ug_usb_blstr.pdf
 */

#if CONFIG_USBBLASTER_SPI == 1

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

/* Please keep sorted by vendor ID, then device ID. */
#define ALTERA_VID		0x09fb
#define ALTERA_USBBLASTER_PID	0x6001

const struct dev_entry devs_usbblasterspi[] = {
	{ALTERA_VID, ALTERA_USBBLASTER_PID, OK, "Altera", "USB-Blaster"},

	{}
};

static const struct spi_programmer spi_programmer_usbblaster;

static struct ftdi_context ftdic;

// command bytes
#define BIT_BYTE	(1<<7)	// byte mode (rather than bitbang)
#define BIT_READ	(1<<6)	// read request
#define BIT_LED		(1<<5)
#define BIT_CS		(1<<3)
#define BIT_TMS		(1<<1)
#define BIT_CLK		(1<<0)

#define BUF_SIZE	64

/* The programmer shifts bits in the wrong order for SPI, so we use this method to reverse the bits when needed.
 * http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits */
uint8_t reverse(uint8_t b)
{
	return ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
}


/* Returns 0 upon success, a negative number upon errors. */
int usbblaster_spi_init(void)
{
	uint8_t buf[BUF_SIZE + 1];

	if (ftdi_init(&ftdic) < 0)
		return -1;

	if (ftdi_usb_open(&ftdic, ALTERA_VID, ALTERA_USBBLASTER_PID) < 0) {
		msg_perr("Failed to open USB-Blaster: %s\n", ftdic.error_str);
		return -1;
	}

	if (ftdi_usb_reset(&ftdic) < 0) {
		msg_perr("USB-Blaster reset failed\n");
		return -1;
	}

	if (ftdi_set_latency_timer(&ftdic, 2) < 0) {
		msg_perr("USB-Blaster set latency timer failed\n");
		return -1;
	}

	if (ftdi_write_data_set_chunksize(&ftdic, 4096) < 0 ||
	    ftdi_read_data_set_chunksize(&ftdic, BUF_SIZE) < 0) {
		msg_perr("USB-Blaster set chunk size failed\n");
		return -1;
	}

	memset(buf, 0, sizeof(buf));
	buf[sizeof(buf)-1] = BIT_LED | BIT_CS;
	if (ftdi_write_data(&ftdic, buf, sizeof(buf)) < 0) {
		msg_perr("USB-Blaster reset write failed\n");
		return -1;
	}
	if (ftdi_read_data(&ftdic, buf, sizeof(buf)) < 0) {
		msg_perr("USB-Blaster reset read failed\n");
		return -1;
	}

	register_spi_programmer(&spi_programmer_usbblaster);
	return 0;
}

static int send_write(unsigned int writecnt, const unsigned char *writearr)
{
	int i;
	uint8_t buf[BUF_SIZE];

	memset(buf, 0, sizeof(buf));
	while (writecnt) {
		unsigned int n_write = min(writecnt, BUF_SIZE - 1);
		msg_pspew("writing %d-byte packet\n", n_write);

		buf[0] = BIT_BYTE | (uint8_t)n_write;
		for (i = 0; i < n_write; i++) {
			buf[i+1] = reverse(writearr[i]);
		}
		if (ftdi_write_data(&ftdic, buf, n_write + 1) < 0) {
			msg_perr("USB-Blaster write failed\n");
			return -1;
		}

		writearr += n_write;
		writecnt -= n_write;
	}
	return 0;
}

static int send_read(unsigned int readcnt, unsigned char *readarr)
{
	int i;
	unsigned int n_read;
	uint8_t buf[BUF_SIZE];
	memset(buf, 0, sizeof(buf));

	n_read = readcnt;
	while (n_read) {
		unsigned int payload_size = min(n_read, BUF_SIZE - 1);
		msg_pspew("reading %d-byte packet\n", payload_size);

		buf[0] = BIT_BYTE | BIT_READ | (uint8_t)payload_size;
		if (ftdi_write_data(&ftdic, buf, payload_size + 1) < 0) {
			msg_perr("USB-Blaster write failed\n");
			return -1;
		}
		n_read -= payload_size;
	};

	n_read = readcnt;
	while (n_read) {
		int ret = ftdi_read_data(&ftdic, readarr, n_read);
		if (ret < 0) {
			msg_perr("USB-Blaster read failed\n");
			return -1;
		}
		for (i = 0; i < ret; i++) {
			readarr[i] = reverse(readarr[i]);
		}
		n_read -= ret;
		readarr += ret;
	}
	return 0;
}

/* Returns 0 upon success, a negative number upon errors. */
static int usbblaster_spi_send_command(struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
				       const unsigned char *writearr, unsigned char *readarr)
{
	uint8_t cmd;
	int ret = 0;

	cmd = BIT_LED; // asserts /CS
	if (ftdi_write_data(&ftdic, &cmd, 1) < 0) {
		msg_perr("USB-Blaster enable chip select failed\n");
		ret = -1;
	}

	if (!ret && writecnt)
		ret = send_write(writecnt, writearr);

	if (!ret && readcnt)
		ret = send_read(readcnt, readarr);

	cmd = BIT_CS;
	if (ftdi_write_data(&ftdic, &cmd, 1) < 0) {
		msg_perr("USB-Blaster disable chip select failed\n");
		ret = -1;
	}

	return ret;
}


static const struct spi_programmer spi_programmer_usbblaster = {
	.type		= SPI_CONTROLLER_USBBLASTER,
	.max_data_read	= 256,
	.max_data_write	= 256,
	.command	= usbblaster_spi_send_command,
	.multicommand	= default_spi_send_multicommand,
	.read		= default_spi_read,
	.write_256	= default_spi_write_256,
	.write_aai	= default_spi_write_aai,
};

#endif
