/*
 * This file is part of the flashrom project.
 *
 * Copyright (C) 2019 Miklós Márton martonmiklosqdev@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.
 *
 */

/*
 * Driver for programming SPI flash chips using the SPI port
 * of the STMicroelectronics's STLINK-V3 programmer/debugger.
 *
 * The implementation is inspired by the ST's STLINK-V3-BRIDGE C++ API:
 * https://www.st.com/en/development-tools/stlink-v3-bridge.html
 */

#include "flash.h"
#include "programmer.h"
#include "spi.h"

#include <libusb.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

enum fw_version_check_result {
	FW_VERSION_OK,
	FW_VERSION_OLD,
};

enum spi_prescaler {
	SPI_BAUDRATEPRESCALER_2 = 0,
	SPI_BAUDRATEPRESCALER_4 = 1,
	SPI_BAUDRATEPRESCALER_8 = 2,
	SPI_BAUDRATEPRESCALER_16 = 3,
	SPI_BAUDRATEPRESCALER_32 = 4,
	SPI_BAUDRATEPRESCALER_64 = 5,
	SPI_BAUDRATEPRESCALER_128 = 6,
	SPI_BAUDRATEPRESCALER_256 = 7
};

enum spi_dir {
	SPI_DIRECTION_2LINES_FULLDUPLEX = 0,
	SPI_DIRECTION_2LINES_RXONLY = 1,
	SPI_DIRECTION_1LINE_RX = 2,
	SPI_DIRECTION_1LINE_TX = 3
};

enum spi_mode {
	SPI_MODE_SLAVE = 0,
	SPI_MODE_MASTER = 1
};

enum spi_datasize {
	SPI_DATASIZE_16B = 0,
	SPI_DATASIZE_8B = 1
};

enum spi_cpol {
	SPI_CPOL_LOW = 0,
	SPI_CPOL_HIGH = 1
};

enum spi_cpha {
	SPI_CPHA_1EDGE = 0,
	SPI_CPHA_2EDGE = 1
};

enum spi_firstbit {
	SPI_FIRSTBIT_LSB = 0,
	SPI_FIRSTBIT_MSB = 1
};

// ST calls the Chip select (CS) NSS == Negated Slave Select
enum spi_nss {
	SPI_NSS_SOFT = 0,
	SPI_NSS_HARD = 1
};

enum spi_nss_level {
	SPI_NSS_LOW = 0,
	SPI_NSS_HIGH = 1
};

#define ST_GETVERSION_EXT					0xFB

#define STLINK_BRIDGE_COMMAND					0xFC
#define STLINK_BRIDGE_CLOSE					0x01
#define STLINK_BRIDGE_GET_RWCMD_STATUS				0x02
#define STLINK_BRIDGE_GET_CLOCK					0x03
#define STLINK_BRIDGE_INIT_SPI					0x20
#define STLINK_BRIDGE_WRITE_SPI					0x21
#define STLINK_BRIDGE_READ_SPI					0x22
#define STLINK_BRIDGE_CS_SPI					0x23

#define STLINK_BRIDGE_SPI_ERROR					0x02

#define STLINK_SPI_COM						0x02

#define STLINK_EP_OUT						0x06
#define STLINK_EP_IN						0x86

#define FIRST_COMPATIBLE_BRIDGE_FW_VERSION			3

#define USB_TIMEOUT_IN_MS					5000

const struct dev_entry devs_stlinkv3_spi[] = {
	{0x0483, 0x374F, OK, "STMicroelectronics", "STLINK-V3"},
	{0}
};

static struct libusb_context *usb_ctx;
static libusb_device_handle *stlinkv3_handle;

static int stlinkv3_command(uint8_t *command, size_t command_length,
		     uint8_t *answer, size_t answer_length, const char *command_name)
{
	int actual_length = 0;
	int rc = libusb_bulk_transfer(stlinkv3_handle, STLINK_EP_OUT,
				  command, command_length,
				  &actual_length, USB_TIMEOUT_IN_MS);
	if (rc != LIBUSB_TRANSFER_COMPLETED || (size_t)actual_length != command_length) {
		msg_perr("Failed to issue the %s command: '%s'\n",
			 command_name,
			 libusb_error_name(rc));
		return -1;
	}

	rc = libusb_bulk_transfer(stlinkv3_handle, STLINK_EP_IN,
				  answer, answer_length,
				  &actual_length, USB_TIMEOUT_IN_MS);
	if (rc != LIBUSB_TRANSFER_COMPLETED || (size_t)actual_length != answer_length) {
		msg_perr("Failed to get %s answer: '%s'\n",
			 command_name,
			 libusb_error_name(rc));
		return -1;
	}
	return 0;
}

/**
 * @param[out] bridge_input_clk Current input frequency in kHz of the given com.
 */
static int stlinkv3_get_clk(uint32_t *bridge_input_clk)
{
	uint8_t command[16] = { 0 };
	uint8_t answer[12];

	if (bridge_input_clk == NULL)
		return -1;

	command[0] = STLINK_BRIDGE_COMMAND;
	command[1] = STLINK_BRIDGE_GET_CLOCK;
	command[2] = STLINK_SPI_COM;

	if (stlinkv3_command(command, sizeof(command), answer, sizeof(answer), "STLINK_BRIDGE_GET_CLOCK") != 0)
		return -1;

	*bridge_input_clk = (uint32_t)answer[4]
			  | (uint32_t)answer[5]<<8
			  | (uint32_t)answer[6]<<16
			  | (uint32_t)answer[7]<<24;
	return 0;

}

static int stlinkv3_spi_calc_prescaler(uint16_t reqested_freq_in_kHz,
				       enum spi_prescaler *prescaler,
				       uint16_t *calculated_freq_in_kHz)
{
	uint32_t bridge_clk_in_kHz;
	uint32_t calculated_prescaler = 1;
	uint16_t prescaler_value;

	if (stlinkv3_get_clk(&bridge_clk_in_kHz))
		return -1;

	calculated_prescaler  = bridge_clk_in_kHz/reqested_freq_in_kHz;
	// Apply a smaller frequency if not exact
	if (calculated_prescaler  <= 2) {
		*prescaler = SPI_BAUDRATEPRESCALER_2;
		prescaler_value = 2;
	} else if (calculated_prescaler  <= 4) {
		*prescaler = SPI_BAUDRATEPRESCALER_4;
		prescaler_value = 4;
	} else if (calculated_prescaler  <= 8) {
		*prescaler = SPI_BAUDRATEPRESCALER_8;
		prescaler_value = 8;
	} else if (calculated_prescaler  <= 16) {
		*prescaler = SPI_BAUDRATEPRESCALER_16;
		prescaler_value = 16;
	} else if (calculated_prescaler  <= 32) {
		*prescaler = SPI_BAUDRATEPRESCALER_32;
		prescaler_value = 32;
	} else if (calculated_prescaler  <= 64) {
		*prescaler = SPI_BAUDRATEPRESCALER_64;
		prescaler_value = 64;
	} else if (calculated_prescaler  <= 128) {
		*prescaler = SPI_BAUDRATEPRESCALER_128;
		prescaler_value = 128;
	} else if (calculated_prescaler  <= 256) {
		*prescaler = SPI_BAUDRATEPRESCALER_256;
		prescaler_value = 256;
	} else {
		// smaller frequency not possible
		*prescaler = SPI_BAUDRATEPRESCALER_256;
		prescaler_value = 256;
	}

	*calculated_freq_in_kHz = bridge_clk_in_kHz / prescaler_value;

	return 0;
}

static int stlinkv3_check_version(enum fw_version_check_result *result)
{
	uint8_t answer[12];
	uint8_t command[16] = { 0 };

	command[0] = ST_GETVERSION_EXT;
	command[1] = 0x80;

	if (stlinkv3_command(command, sizeof(command), answer, sizeof(answer), "ST_GETVERSION_EXT") != 0)
		return -1;

	msg_pinfo("Connected to STLink V3 with bridge FW version: %d\n", answer[4]);
	*result = answer[4] >= FIRST_COMPATIBLE_BRIDGE_FW_VERSION
			? FW_VERSION_OK
			: FW_VERSION_OLD;
	return 0;
}

static int stlinkv3_spi_open(uint16_t reqested_freq_in_kHz)
{
	uint8_t command[16] = { 0 };
	uint8_t answer[2];
	uint16_t SCK_freq_in_kHz;
	enum spi_prescaler prescaler;
	enum fw_version_check_result fw_check_result;

	if (stlinkv3_check_version(&fw_check_result)) {
		msg_perr("Failed to query FW version\n");
		return -1;
	}

	if (fw_check_result != FW_VERSION_OK) {
		msg_pinfo("Your STLink V3 has a too old version of the bridge interface\n"
			  "Please update the firmware to version 2.33.25 or newer of the STSW-LINK007\n"
			  "which can be downloaded from here:\n"
			  "https://www.st.com/en/development-tools/stsw-link007.html\n");
		return -1;
	}

	if (stlinkv3_spi_calc_prescaler(reqested_freq_in_kHz,
					&prescaler,
					&SCK_freq_in_kHz)) {
		msg_perr("Failed to calculate SPI clock prescaler\n");
		return -1;
	}
	msg_pinfo("SCK frequency set to %d kHz\n", SCK_freq_in_kHz);

	command[0] = STLINK_BRIDGE_COMMAND;
	command[1] = STLINK_BRIDGE_INIT_SPI;
	command[2] = SPI_DIRECTION_2LINES_FULLDUPLEX;
	command[3] = (SPI_MODE_MASTER
		      | (SPI_CPHA_1EDGE << 1)
		      | (SPI_CPOL_LOW << 2)
		      | (SPI_FIRSTBIT_MSB << 3));
	command[4] = SPI_DATASIZE_8B;
	command[5] = SPI_NSS_SOFT;
	command[6] = (uint8_t)prescaler;

	return stlinkv3_command(command, sizeof(command), answer, sizeof(answer), "STLINK_BRIDGE_INIT_SPI");
}

static int stlinkv3_get_last_readwrite_status(uint32_t *status)
{
	uint8_t command[16] = { 0 };
	uint16_t answer[4];

	command[0] = STLINK_BRIDGE_COMMAND;
	command[1] = STLINK_BRIDGE_GET_RWCMD_STATUS;

	if (stlinkv3_command(command, sizeof(command),
			     (uint8_t *)answer, sizeof(answer),
			     "STLINK_BRIDGE_GET_RWCMD_STATUS") != 0)
		return -1;

	*status = (uint32_t)answer[2] | (uint32_t)answer[3]<<16;
	return 0;
}

static int stlinkv3_spi_set_SPI_NSS(enum spi_nss_level nss_level)
{
	uint8_t command[16] = { 0 };
	uint8_t answer[2];

	command[0] = STLINK_BRIDGE_COMMAND;
	command[1] = STLINK_BRIDGE_CS_SPI;
	command[2] = (uint8_t) (nss_level);

	if (stlinkv3_command(command, sizeof(command), answer, sizeof(answer), "STLINK_BRIDGE_CS_SPI") != 0)
		return -1;
	return 0;
}

static int stlinkv3_spi_transmit(const struct flashctx *flash,
				 unsigned int write_cnt,
				 unsigned int read_cnt,
				 const unsigned char *write_arr,
				 unsigned char *read_arr)
{
	uint8_t command[16] = { 0 };
	int rc = 0;
	int actual_length = 0;
	uint32_t rw_status = 0;
	unsigned int i;

	if (stlinkv3_spi_set_SPI_NSS(SPI_NSS_LOW)) {
		msg_perr("Failed to set the NSS pin to low\n");
		return -1;
	}

	command[0] = STLINK_BRIDGE_COMMAND;
	command[1] = STLINK_BRIDGE_WRITE_SPI;
	command[2] = (uint8_t)write_cnt;
	command[3] = (uint8_t)(write_cnt >> 8);

	for (i = 0; (i < 8) && (i < write_cnt); i++)
		command[4+i] = write_arr[i];

	rc = libusb_bulk_transfer(stlinkv3_handle, STLINK_EP_OUT,
				  command, sizeof(command),
				  &actual_length, USB_TIMEOUT_IN_MS);
	if (rc != LIBUSB_TRANSFER_COMPLETED || actual_length != sizeof(command)) {
		msg_perr("Failed to issue the STLINK_BRIDGE_WRITE_SPI command: '%s'\n",
			 libusb_error_name(rc));
		goto transmit_err;
	}

	if (write_cnt > 8) {
		rc = libusb_bulk_transfer(stlinkv3_handle,
					  STLINK_EP_OUT,
					  (unsigned char *)&write_arr[8],
					  (unsigned int)(write_cnt - 8),
					  &actual_length,
					  USB_TIMEOUT_IN_MS);
		if (rc != LIBUSB_TRANSFER_COMPLETED || (unsigned int)actual_length != (write_cnt - 8)) {
			msg_perr("Failed to send the  data after the  STLINK_BRIDGE_WRITE_SPI command: '%s'\n",
				 libusb_error_name(rc));
			goto transmit_err;
		}
	}

	if (stlinkv3_get_last_readwrite_status(&rw_status))
		return -1;

	if (rw_status != 0) {
		msg_perr("SPI read/write failure: %d\n", rw_status);
		goto transmit_err;
	}

	if (read_cnt) {
		command[1] = STLINK_BRIDGE_READ_SPI;
		command[2] = (uint8_t)read_cnt;
		command[3] = (uint8_t)(read_cnt >> 8);

		rc = libusb_bulk_transfer(stlinkv3_handle, STLINK_EP_OUT,
					  command, sizeof(command),
					  &actual_length, USB_TIMEOUT_IN_MS);
		if (rc != LIBUSB_TRANSFER_COMPLETED || (unsigned int)actual_length != sizeof(command)) {
			msg_perr("Failed to issue the STLINK_BRIDGE_READ_SPI command: '%s'\n",
				 libusb_error_name(rc));
			goto transmit_err;
		}

		rc = libusb_bulk_transfer(stlinkv3_handle,
					  STLINK_EP_IN,
					  (unsigned char *)read_arr,
					  (int)read_cnt,
					  &actual_length,
					  USB_TIMEOUT_IN_MS);
		if (rc != LIBUSB_TRANSFER_COMPLETED || (unsigned int)actual_length != read_cnt) {
			msg_perr("Failed to retrive the STLINK_BRIDGE_READ_SPI answer: '%s'\n",
				 libusb_error_name(rc));
			goto transmit_err;
		}
	}

	if (stlinkv3_get_last_readwrite_status(&rw_status))
		goto transmit_err;

	if (rw_status != 0) {
		msg_perr("SPI read/write failure: %d\n", rw_status);
		goto transmit_err;
	}

	if (stlinkv3_spi_set_SPI_NSS(SPI_NSS_HIGH)) {
		msg_perr("Failed to set the NSS pin to high\n");
		return -1;
	}
	return 0;

transmit_err:
	if (stlinkv3_spi_set_SPI_NSS(SPI_NSS_HIGH))
		msg_perr("Failed to set the NSS pin to high\n");
	return -1;
}

static int stlinkv3_spi_shutdown(void *data)
{
	uint8_t command[16] = { 0 };
	uint8_t answer[2];

	command[0] = STLINK_BRIDGE_COMMAND;
	command[1] = STLINK_BRIDGE_CLOSE;
	command[2] = STLINK_SPI_COM;

	stlinkv3_command(command, sizeof(command), answer, sizeof(answer), "STLINK_BRIDGE_CLOSE");

	libusb_close(stlinkv3_handle);
	libusb_exit(usb_ctx);

	return 0;
}

static const struct spi_master spi_programmer_stlinkv3 = {
	.max_data_read = UINT16_MAX,
	.max_data_write = UINT16_MAX,
	.command = stlinkv3_spi_transmit,
	.multicommand = default_spi_send_multicommand,
	.read = default_spi_read,
	.write_256 = default_spi_write_256,
	.write_aai = default_spi_write_aai,
};

int stlinkv3_spi_init(void)
{
	uint16_t sck_freq_kHz = 1000;	// selecting 1 MHz SCK is a good bet
	char *speed_str = NULL;
	char *serialno = NULL;
	char *endptr = NULL;
	int ret = 1;

	libusb_init(&usb_ctx);
	if (!usb_ctx) {
		msg_perr("Could not initialize libusb!\n");
		return 1;
	}

	serialno = extract_programmer_param("serial");
	if (serialno)
		msg_pdbg("Opening STLINK-V3 with serial: %s\n", serialno);
	stlinkv3_handle = usb_dev_get_by_vid_pid_serial(usb_ctx,
							devs_stlinkv3_spi[0].vendor_id,
							devs_stlinkv3_spi[0].device_id,
							serialno);

	if (!stlinkv3_handle) {
		if (serialno)
			msg_perr("No STLINK-V3 seems to be connected with serial %s\n", serialno);
		else
			msg_perr("Could not find any connected STLINK-V3\n");
		free(serialno);
		goto init_err_exit;
	}
	free(serialno);

	speed_str = extract_programmer_param("spispeed");
	if (speed_str) {
		sck_freq_kHz = strtoul(speed_str, &endptr, 0);
		if (*endptr || sck_freq_kHz == 0) {
			msg_perr("The spispeed parameter passed with invalid format: %s\n",
				 speed_str);
			msg_perr("Please pass the parameter "
				 "with a simple non-zero number in kHz\n");
			free(speed_str);
			ret = -1;
			goto init_err_exit;
		}
		free(speed_str);
	}

	if (stlinkv3_spi_open(sck_freq_kHz))
		goto init_err_exit;

	if (register_shutdown(stlinkv3_spi_shutdown, NULL))
		goto init_err_cleanup_exit;

	if (register_spi_master(&spi_programmer_stlinkv3))
		return 1; /* shutdown function does cleanup */

	return 0;

init_err_cleanup_exit:
	stlinkv3_spi_shutdown(NULL);
	return 1;

init_err_exit:
	if (stlinkv3_handle)
		libusb_close(stlinkv3_handle);
	libusb_exit(usb_ctx);
	return ret;
}
