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

static 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(const 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 },
};

static 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;
}

const struct programmer_entry programmer_digilent_spi = {
	.name			= "digilent_spi",
	.type			= USB,
	.devs.dev		= devs_digilent_spi,
	.init			= digilent_spi_init,
	.map_flash_region	= fallback_map,
	.unmap_flash_region	= fallback_unmap,
	.delay			= internal_delay,
};
