/*
 * This file is part of the flashrom project.
 *
 * Copyright (C) 2018 Lubomir Rintel <lkundrak@v3.sk>
 *
 * Based on ft2232_spi.c:
 *
 * Copyright (C) 2011 asbokid <ballymunboy@gmail.com>
 * Copyright (C) 2014 Pluto Yang <yangyj.ee@gmail.com>
 * Copyright (C) 2015-2016 Stefan Tauner
 * Copyright (C) 2015 Urja Rannikko <urjaman@gmail.com>
 *
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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
 */

/*
 * The reverse-engineered protocol description was obtained from the
 * iceBurn project <https://github.com/davidcarne/iceBurn> by
 * David Carne <davidcarne@gmail.com>.
 */

#include <stdlib.h>
#include <string.h>
#include <libusb.h>
#include "programmer.h"

/* This is pretty much arbitrarily chosen. After one second without a
 * response we can be pretty sure we're not going to succeed. */
#define USB_TIMEOUT		1000

#define	CMD_WRITE_EP		0x01
#define	CMD_READ_EP		0x82
#define	DATA_WRITE_EP		0x03
#define	DATA_READ_EP		0x84

static struct libusb_device_handle *handle = NULL;
static bool reset_board;

#define DIGILENT_VID		0x1443
#define DIGILENT_JTAG_PID	0x0007

const struct dev_entry devs_digilent_spi[] = {
	{ DIGILENT_VID, DIGILENT_JTAG_PID, OK, "Digilent", "Development board JTAG" },
	{ 0 },
};

/* Control endpoint commands. */
enum {
	GET_BOARD_TYPE		= 0xe2,
	GET_BOARD_SERIAL	= 0xe4,
};

/* Command bulk endpoint command groups. */
enum {
	CMD_GPIO		= 0x03,
	CMD_BOARD		= 0x04,
	CMD_SPI			= 0x06,
};

/* GPIO subcommands. */
enum {
	CMD_GPIO_OPEN		= 0x00,
	CMD_GPIO_CLOSE		= 0x01,
	CMD_GPIO_SET_DIR	= 0x04,
	CMD_GPIO_SET_VAL	= 0x06,
};

/* Board subcommands. */
enum {
	CMD_BOARD_OPEN		= 0x00,
	CMD_BOARD_CLOSE		= 0x01,
	CMD_BOARD_SET_REG	= 0x04,
	CMD_BOARD_GET_REG	= 0x05,
	CMD_BOARD_PL_STAT	= 0x85,
};

/* SPI subcommands. */
enum {
	CMD_SPI_OPEN		= 0x00,
	CMD_SPI_CLOSE		= 0x01,
	CMD_SPI_SET_SPEED	= 0x03,
	CMD_SPI_SET_MODE	= 0x05,
	CMD_SPI_SET_CS		= 0x06,
	CMD_SPI_START_IO	= 0x07,
	CMD_SPI_TX_END		= 0x87,
};

static int do_command(uint8_t *req, int req_len, uint8_t *res, int res_len)
{
	int tx_len = 0;
	int ret;

	req[0] = req_len - 1;
	ret = libusb_bulk_transfer(handle, CMD_WRITE_EP, req, req_len, &tx_len, USB_TIMEOUT);
	if (ret) {
		msg_perr("Failed to issue a command: '%s'\n", libusb_error_name(ret));
		return -1;
	}

	if (tx_len != req_len) {
		msg_perr("Short write issuing a command\n");
		return -1;
	}

	ret = libusb_bulk_transfer(handle, CMD_READ_EP, res, res_len, &tx_len, USB_TIMEOUT);
	if (ret) {
		msg_perr("Failed to get a response: '%s'\n", libusb_error_name(ret));
		return -1;
	}

	if (tx_len != res_len) {
		msg_perr("Short read getting a response\n");
		return -1;
	}

	if (res[0] != res_len -1) {
		msg_perr("Response indicates incorrect length.\n");
		return -1;
	}

	return 0;
}

static int gpio_open(void)
{
	uint8_t req[] = { 0x00, CMD_GPIO, CMD_GPIO_OPEN, 0x00 };
	uint8_t res[2];

	return do_command(req, sizeof(req), res, sizeof(res));
}

static int gpio_set_dir(uint8_t direction)
{
	uint8_t req[] = { 0x00, CMD_GPIO, CMD_GPIO_SET_DIR, 0x00,
			  direction, 0x00, 0x00, 0x00 };
	uint8_t res[6];

	return do_command(req, sizeof(req), res, sizeof(res));
}

static int gpio_set_value(uint8_t value)
{
	uint8_t req[] = { 0x00, CMD_GPIO, CMD_GPIO_SET_VAL, 0x00,
			  value, 0x00, 0x00, 0x00 };
	uint8_t res[2];

	return do_command(req, sizeof(req), res, sizeof(res));
}

static int spi_open(void)
{
	uint8_t req[] = { 0x00, CMD_SPI, CMD_SPI_OPEN, 0x00 };
	uint8_t res[2];

	return do_command(req, sizeof(req), res, sizeof(res));
}

static int spi_set_speed(uint32_t speed)
{
	uint8_t req[] = { 0x00, CMD_SPI, CMD_SPI_SET_SPEED, 0x00,
			  (speed) & 0xff,
			  (speed >> 8) & 0xff,
			  (speed >> 16) & 0xff,
			  (speed >> 24) & 0xff };
	uint8_t res[6];
	uint32_t real_speed;
	int ret;

	ret = do_command(req, sizeof(req), res, sizeof(res));
	if (ret)
		return ret;

	real_speed = (res[5] << 24) | (res[4] << 16) | (res[3] << 8) | res[2];
	if (real_speed != speed)
		msg_pwarn("SPI speed set to %d instead of %d\n", real_speed, speed);

	return 0;
}

static int spi_set_mode(uint8_t mode)
{
	uint8_t req[] = { 0x00, CMD_SPI, CMD_SPI_SET_MODE, 0x00, mode };
	uint8_t res[2];

	return do_command(req, sizeof(req), res, sizeof(res));
}

static int spi_set_cs(uint8_t cs)
{
	uint8_t req[] = { 0x00, CMD_SPI, CMD_SPI_SET_CS, 0x00, cs };
	uint8_t res[2];

	return do_command(req, sizeof(req), res, sizeof(res));
}

static int spi_start_io(uint8_t read_follows, uint32_t write_len)
{
	uint8_t req[] = { 0x00, CMD_SPI, CMD_SPI_START_IO, 0x00,
			  0x00, 0x00, /* meaning unknown */
			  read_follows,
			  (write_len) & 0xff,
			  (write_len >> 8) & 0xff,
			  (write_len >> 16) & 0xff,
			  (write_len >> 24) & 0xff };
	uint8_t res[2];

	return do_command(req, sizeof(req), res, sizeof(res));
}

static int spi_tx_end(uint8_t read_follows, uint32_t tx_len)
{
	uint8_t req[] = { 0x00, CMD_SPI, CMD_SPI_TX_END, 0x00 };
	uint8_t res[read_follows ? 10 : 6];
	int ret;
	uint32_t count;

	ret = do_command(req, sizeof(req), res, sizeof(res));
	if (ret != 0)
		return ret;

	if ((res[1] & 0x80) == 0) {
		msg_perr("%s: response missing a write count\n", __func__);
		return -1;
	}

	count = res[2] | (res[3] << 8) | (res[4] << 16) | res[5] << 24;
	if (count != tx_len) {
		msg_perr("%s: wrote only %d bytes instead of %d\n", __func__, count, tx_len);
		return -1;
	}

	if (read_follows) {
		if ((res[1] & 0x40) == 0) {
			msg_perr("%s: response missing a read count\n", __func__);
			return -1;
		}

		count = res[6] | (res[7] << 8) | (res[8] << 16) | res[9] << 24;
		if (count != tx_len) {
			msg_perr("%s: read only %d bytes instead of %d\n", __func__, count, tx_len);
			return -1;
		}
	}

	return 0;
}

static int digilent_spi_send_command(struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
				     const unsigned char *writearr, unsigned char *readarr)
{
	int ret;
	int len = writecnt + readcnt;
	int tx_len = 0;
	uint8_t buf[len];
	uint8_t read_follows = readcnt > 0 ? 1 : 0;

	memcpy(buf, writearr, writecnt);
	memset(buf + writecnt, 0xff, readcnt);

	ret = spi_set_cs(0);
	if (ret != 0)
		return ret;

	ret = spi_start_io(read_follows, writecnt);
	if (ret != 0)
		return ret;

	ret = libusb_bulk_transfer(handle, DATA_WRITE_EP, buf, len, &tx_len, USB_TIMEOUT);
	if (ret != 0) {
		msg_perr("%s: failed to write data: '%s'\n", __func__, libusb_error_name(ret));
		return -1;
	}
	if (tx_len != len) {
		msg_perr("%s: short write\n", __func__);
		return -1;
	}

	if (read_follows) {
		ret = libusb_bulk_transfer(handle, DATA_READ_EP, buf, len, &tx_len, USB_TIMEOUT);
		if (ret != 0) {
			msg_perr("%s: failed to read data: '%s'\n", __func__, libusb_error_name(ret));
			return -1;
		}
		if (tx_len != len) {
			msg_perr("%s: short read\n", __func__);
			return -1;
		}
	}

	ret = spi_tx_end(read_follows, len);
	if (ret != 0)
		return ret;

	ret = spi_set_cs(1);
	if (ret != 0)
		return ret;

	memcpy(readarr, &buf[writecnt], readcnt);

	return 0;
}

static const struct spi_master spi_master_digilent_spi = {
	.features	= SPI_MASTER_4BA,
	.max_data_read	= 252,
	.max_data_write	= 252,
	.command	= digilent_spi_send_command,
	.multicommand	= default_spi_send_multicommand,
	.read		= default_spi_read,
	.write_256	= default_spi_write_256,
	.write_aai	= default_spi_write_aai,
};


static int digilent_spi_shutdown(void *data)
{
	if (reset_board)
		gpio_set_dir(0);

	libusb_close(handle);
	handle = NULL;

	return 0;
}

static bool default_reset(void)
{
	char board[17];

	libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR,
	                        GET_BOARD_TYPE, 0, 0,
	                        (unsigned char *)board, sizeof(board) - 1, USB_TIMEOUT);
	board[sizeof(board) -1] = '\0';

	if (strcmp(board, "iCE40") == 0)
		return true;

	msg_pwarn("%s: unknown board '%s' not attempting a reset. "
	          "Override with '-p digilent_spi=reset=1'.\n", __func__, board);
	return false;
}

struct digilent_spispeeds {
        const char *const name;
        const int speed;
};

static const struct digilent_spispeeds spispeeds[] = {
	{ "4M",		4000000 },
	{ "2M",		2000000 },
	{ "1M",		1000000 },
	{ "500k",	500000 },
	{ "250k",	250000 },
	{ "125k",	125000 },
	{ "62.5k",	62500 },
	{ NULL,		0 },
};

int digilent_spi_init(void)
{
	char *p;
	uint32_t speed_hz = spispeeds[0].speed;
	int i;

	if (handle != NULL) {
		msg_cerr("%s: handle already set! Please report a bug at flashrom@flashrom.org\n", __func__);
		return -1;
	}

	int32_t ret = libusb_init(NULL);
	if (ret < 0) {
		msg_perr("%s: couldn't initialize libusb!\n", __func__);
		return -1;
	}

#if LIBUSB_API_VERSION < 0x01000106
	libusb_set_debug(NULL, 3);
#else
	libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO);
#endif

	uint16_t vid = devs_digilent_spi[0].vendor_id;
	uint16_t pid = devs_digilent_spi[0].device_id;
	handle = libusb_open_device_with_vid_pid(NULL, vid, pid);
	if (handle == NULL) {
		msg_perr("%s: couldn't open device %04x:%04x.\n", __func__, vid, pid);
		return -1;
	}

	ret = libusb_claim_interface(handle, 0);
	if (ret != 0) {
		msg_perr("%s: failed to claim interface 0: '%s'\n", __func__, libusb_error_name(ret));
		goto close_handle;
	}

	p = extract_programmer_param("spispeed");
	if (p) {
		for (i = 0; spispeeds[i].name; ++i) {
			if (!strcasecmp(spispeeds[i].name, p)) {
				speed_hz = spispeeds[i].speed;
				break;
			}
		}
		if (!spispeeds[i].name) {
			msg_perr("Error: Invalid spispeed value: '%s'.\n", p);
			free(p);
			goto close_handle;
		}
		free(p);
	}

	p = extract_programmer_param("reset");
	if (p && strlen(p))
		reset_board = (p[0] == '1');
	else
		reset_board = default_reset();
	free(p);

	if (reset_board) {
		if (gpio_open() != 0)
			goto close_handle;
		if (gpio_set_dir(1) != 0)
			goto close_handle;
		if (gpio_set_value(0) != 0)
			goto close_handle;
	}

	if (spi_open() != 0)
		goto close_handle;
	if (spi_set_speed(speed_hz) != 0)
		goto close_handle;
	if (spi_set_mode(0x00) != 0)
		goto close_handle;

	register_shutdown(digilent_spi_shutdown, NULL);
	register_spi_master(&spi_master_digilent_spi);

	return 0;

close_handle:
	libusb_close(handle);
	handle = NULL;
	return -1;
}
