/*
 * This file is part of the flashrom project.
 *
 * Copyright (C) 2018 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.
 *
 */

#include <ctype.h>
#include <inttypes.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ni845x.h>
#include <unistd.h>

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

#define NI845x_FIND_DEVICE_NO_DEVICE_FOUND			-301701

enum USB845x_type {
	USB8451 = 0x7166,
	USB8452 = 0x7514,
	Unknown_NI845X_Device
};

enum voltage_coerce_mode {
	USE_LOWER,
	USE_HIGHER
};

static unsigned char CS_number;	// use chip select 0 as default
static enum USB845x_type device_pid = Unknown_NI845X_Device;

static uInt32 device_handle;
static NiHandle configuration_handle;
static uint16_t io_voltage_in_mV;
static bool ignore_io_voltage_limits;

// USB-8452 supported voltages, keep this array in ascending order!
static const uint8_t usb8452_io_voltages_in_100mV[5] = {
	kNi845x12Volts,
	kNi845x15Volts,
	kNi845x18Volts,
	kNi845x25Volts,
	kNi845x33Volts
};

/* Copied from dediprog.c */
/* Might be useful for other USB devices as well. static for now. */
static int parse_voltage(char *voltage)
{
	char *tmp = NULL;
	int i;
	int millivolt = 0, fraction = 0;

	if (!voltage || !strlen(voltage)) {
		msg_perr("Empty voltage= specified.\n");
		return -1;
	}
	millivolt = (int)strtol(voltage, &tmp, 0);
	voltage = tmp;
	/* Handle "," and "." as decimal point. Everything after it is assumed
	 * to be in decimal notation.
	 */
	if ((*voltage == '.') || (*voltage == ',')) {
		voltage++;
		for (i = 0; i < 3; i++) {
			fraction *= 10;
			/* Don't advance if the current character is invalid,
			 * but continue multiplying.
			 */
			if ((*voltage < '0') || (*voltage > '9'))
				continue;
			fraction += *voltage - '0';
			voltage++;
		}
		/* Throw away remaining digits. */
		voltage += strspn(voltage, "0123456789");
	}
	/* The remaining string must be empty or "mV" or "V". */
	tolower_string(voltage);

	/* No unit or "V". */
	if ((*voltage == '\0') || !strncmp(voltage, "v", 1)) {
		millivolt *= 1000;
		millivolt += fraction;
	} else if (!strncmp(voltage, "mv", 2) || !strncmp(voltage, "millivolt", 9)) {
		/* No adjustment. fraction is discarded. */
	} else {
		/* Garbage at the end of the string. */
		msg_perr("Garbage voltage= specified.\n");
		return -1;
	}
	return millivolt;
}

static void ni845x_report_error(const char *const func, const int32 err)
{
	static char buf[1024];

	ni845xStatusToString(err, sizeof(buf), buf);
	msg_perr("%s failed with: %s (%d)\n", func, buf, (int)err);
}

static void ni845x_report_warning(const char *const func, const int32 err)
{
	static char buf[1024];

	ni845xStatusToString(err, sizeof(buf), buf);
	msg_pwarn("%s failed with: %s (%d)\n", func, buf, (int)err);
}

/**
 * @brief ni845x_spi_open_resource
 * @param resource_handle the resource handle returned by the ni845xFindDevice or ni845xFindDeviceNext
 * @param opened_handle the opened handle from the ni845xOpen
 * @return the 0 on successful competition, negative error code on failure positive code on warning
 */
static int32 ni845x_spi_open_resource(char *resource_handle, uInt32 *opened_handle)
{
	// NI-845x driver loads the FPGA bitfile at the first time
	// which can take couple seconds
	if (device_pid == USB8452)
		msg_pwarn("Opening NI-8452, this might take a while for the first time\n");

	int32 tmp = ni845xOpen(resource_handle, opened_handle);

	if (tmp < 0)
		ni845x_report_error("ni845xOpen", tmp);
	else if (tmp > 0)
		ni845x_report_warning("ni845xOpen", tmp);
	return tmp;
}

/**
 * @param serial a null terminated string containing the serial number of the specific device or NULL
 * @return the 0 on successful completion, negative error code on failure
 */
static int ni845x_spi_open(const char *serial, uInt32 *return_handle)
{
	char resource_name[256];
	NiHandle device_find_handle;
	uInt32 found_devices_count = 0;
	int32 tmp = 0;

	unsigned int vid, pid, usb_bus;
	unsigned long int serial_as_number;
	int ret = -1;

	tmp = ni845xFindDevice(resource_name, &device_find_handle, &found_devices_count);
	if (tmp != 0) {
		// suppress warning if no device found
		if (tmp != NI845x_FIND_DEVICE_NO_DEVICE_FOUND)
			ni845x_report_error("ni845xFindDevice", tmp);
		return -1;
	}

	for (; found_devices_count; --found_devices_count) {
		// Read the serial number and the PID here
		// VISA resource name format example:
		// USB0::0x3923::0x7514::DEADBEEF::RAW
		// where the 0x7514 is the PID
		// and the DEADBEEF is the serial of the device
		if (sscanf(resource_name,
			   "USB%u::0x%04X::0x%04X::%08lX::RAW",
			   &usb_bus, &vid, &pid, &serial_as_number) != 4) {
			// malformed resource string detected
			msg_pwarn("Warning: Unable to parse the %s NI-845x resource string.\n",
				  resource_name);
			msg_pwarn("Please report a bug at flashrom@flashrom.org\n");
			continue;
		}

		device_pid = pid;

		if (!serial || strtol(serial, NULL, 16) == serial_as_number)
			break;

		if (found_devices_count > 1) {
			tmp = ni845xFindDeviceNext(device_find_handle, resource_name);
			if (tmp) {
				ni845x_report_error("ni845xFindDeviceNext", tmp);
				goto _close_ret;
			}
		}
	}

	if (found_devices_count)
		ret = ni845x_spi_open_resource(resource_name, return_handle);

_close_ret:
	tmp = ni845xCloseFindDeviceHandle(device_find_handle);
	if (tmp) {
		ni845x_report_error("ni845xCloseFindDeviceHandle", tmp);
		return -1;
	}
	return ret;
}

/**
 * @brief usb8452_spi_set_io_voltage sets the IO voltage for the USB-8452 devices
 * @param requested_io_voltage_mV the desired IO voltage in mVolts
 * @param set_io_voltage_mV the IO voltage which was set in mVolts
 * @param coerce_mode if set to USE_LOWER the closest supported IO voltage which is lower or equal to
 * the requested_io_voltage_mV will be selected. Otherwise the next closest supported voltage will be chosen
 * which is higher or equal to the requested_io_voltage_mV.
 * @return 0 on success, negative on error, positive on warning
 */
static int usb8452_spi_set_io_voltage(uint16_t requested_io_voltage_mV,
				      uint16_t *set_io_voltage_mV,
				      enum voltage_coerce_mode coerce_mode)
{
	int i = 0;
	uint8_t selected_voltage_100mV = 0;
	uint8_t requested_io_voltage_100mV = 0;

	if (device_pid == USB8451) {
		io_voltage_in_mV = 3300;
		msg_pwarn("USB-8451 does not support the changing of the SPI IO voltage\n");
		return 0;
	}

	// limit the IO voltage to 3.3V
	if (requested_io_voltage_mV > 3300) {
		msg_pinfo("USB-8452 maximum IO voltage is 3.3V\n");
		return -1;
	}
	requested_io_voltage_100mV = (requested_io_voltage_mV / 100.0f);

	// usb8452_io_voltages_in_100mV contains the supported voltage levels in increasing order
	for (i = (ARRAY_SIZE(usb8452_io_voltages_in_100mV) - 1); i > 0; --i) {
		if (requested_io_voltage_100mV >= usb8452_io_voltages_in_100mV[i])
			break;
	}

	if (coerce_mode == USE_LOWER) {
		if (requested_io_voltage_100mV < usb8452_io_voltages_in_100mV[0]) {
			msg_perr("Unable to set the USB-8452 IO voltage below %.1fV "
				 "(the minimum supported IO voltage is %.1fV)\n",
				 (float)requested_io_voltage_100mV / 10.0f,
				 (float)usb8452_io_voltages_in_100mV[0] / 10.0f);
			return -1;
		}
		selected_voltage_100mV = usb8452_io_voltages_in_100mV[i];
	} else {
		if (i == ARRAY_SIZE(usb8452_io_voltages_in_100mV) - 1)
			selected_voltage_100mV = usb8452_io_voltages_in_100mV[i];
		else
			selected_voltage_100mV = usb8452_io_voltages_in_100mV[i + 1];
	}

	if (requested_io_voltage_100mV < usb8452_io_voltages_in_100mV[0]) {
		/* unsupported / would have to round up */
		msg_pwarn("The USB-8452 does not support the %.1fV IO voltage\n",
			  requested_io_voltage_mV / 1000.0f);
		selected_voltage_100mV = kNi845x12Volts;
		msg_pwarn("The output voltage is set to 1.2V (this is the lowest voltage)\n");
		msg_pwarn("Supported IO voltages:\n");
		for (i = 0; i < ARRAY_SIZE(usb8452_io_voltages_in_100mV); i++) {
			msg_pwarn("%.1fV", (float)usb8452_io_voltages_in_100mV[i] / 10.0f);
			if (i != ARRAY_SIZE(usb8452_io_voltages_in_100mV) - 1)
				msg_pwarn(", ");
		}
		msg_pwarn("\n");
	} else if (selected_voltage_100mV != requested_io_voltage_100mV) {
		/* we rounded down/up */
		msg_pwarn("USB-8452 IO voltage forced to: %.1f V\n",
			  (float)selected_voltage_100mV / 10.0f);
	} else {
		/* exact match */
		msg_pinfo("USB-8452 IO voltage set to: %.1f V\n",
			  (float)selected_voltage_100mV / 10.0f);
	}

	if (set_io_voltage_mV)
		*set_io_voltage_mV = (selected_voltage_100mV * 100);

	i = ni845xSetIoVoltageLevel(device_handle, selected_voltage_100mV);
	if (i != 0) {
		ni845x_report_error("ni845xSetIoVoltageLevel", i);
		return -1;
	}
	return 0;
}

/**
 * @brief ni845x_spi_set_speed sets the SPI SCK speed
 * @param SCK_freq_in_KHz SCK speed in KHz
 * @return
 */
static int ni845x_spi_set_speed(uint16_t SCK_freq_in_KHz)
{
	int32 i = ni845xSpiConfigurationSetClockRate(configuration_handle, SCK_freq_in_KHz);
	uInt16 clock_freq_read_KHz;

	if (i != 0) {
		ni845x_report_error("ni845xSpiConfigurationSetClockRate", i);
		return -1;
	}

	// read back the clock frequency and notify the user if it is not the same as it was requested
	i = ni845xSpiConfigurationGetClockRate(configuration_handle, &clock_freq_read_KHz);
	if (i != 0) {
		ni845x_report_error("ni845xSpiConfigurationGetClockRate", i);
		return -1;
	}

	if (clock_freq_read_KHz != SCK_freq_in_KHz) {
		msg_pinfo("SPI clock frequency forced to: %d KHz (requested: %d KHz)\n",
			  (int)clock_freq_read_KHz, (int)SCK_freq_in_KHz);
	} else {
		msg_pinfo("SPI clock frequency set to: %d KHz\n", (int)SCK_freq_in_KHz);
	}
	return 0;
}

/**
 * @brief ni845x_spi_print_available_devices prints a list of the available devices
 */
static void ni845x_spi_print_available_devices(void)
{
	char resource_handle[256], device_type_string[16];
	NiHandle device_find_handle;
	uInt32 found_devices_count = 0;
	int32 tmp = 0;
	unsigned int pid, vid, usb_bus;
	unsigned long int serial_as_number;

	tmp = ni845xFindDevice(resource_handle, &device_find_handle, &found_devices_count);
	if (tmp != 0) {
		// suppress warning if no device found
		if (tmp != NI845x_FIND_DEVICE_NO_DEVICE_FOUND)
			ni845x_report_error("ni845xFindDevice", tmp);
		return;
	}

	if (found_devices_count) {
		msg_pinfo("Available devices:\n");
		do {
			tmp = sscanf(resource_handle, "USB%d::0x%04X::0x%04X::%08lX::RAW",
				     &usb_bus, &vid, &pid, &serial_as_number);
			if (tmp == 4) {
				switch (pid) {
				case USB8451:
					snprintf(device_type_string,
							 ARRAY_SIZE(device_type_string), "USB-8451");
					break;
				case USB8452:
					snprintf(device_type_string,
							 ARRAY_SIZE(device_type_string), "USB-8452");
					break;
				default:
					snprintf(device_type_string,
							 ARRAY_SIZE(device_type_string), "Unknown device");
					break;
				}
				msg_pinfo("- %lX (%s)\n", serial_as_number, device_type_string);

				found_devices_count--;
				if (found_devices_count) {
					tmp = ni845xFindDeviceNext(device_find_handle, resource_handle);
					if (tmp)
						ni845x_report_error("ni845xFindDeviceNext", tmp);
				}
			}
		} while (found_devices_count);
	}

	tmp = ni845xCloseFindDeviceHandle(device_find_handle);
	if (tmp)
		ni845x_report_error("ni845xCloseFindDeviceHandle", tmp);
}

static int ni845x_spi_shutdown(void *data)
{
	int32 ret = 0;

	if (configuration_handle != 0) {
		ret = ni845xSpiConfigurationClose(configuration_handle);
		if (ret)
			ni845x_report_error("ni845xSpiConfigurationClose", ret);
	}

	if (device_handle != 0) {
		ret = ni845xClose(device_handle);
		if (ret)
			ni845x_report_error("ni845xClose", ret);
	}
	return 0;
}

static void ni845x_warn_over_max_voltage(const struct flashctx *flash)
{
	if (device_pid == USB8451) {
		msg_pwarn("The %s chip maximum voltage is %.1fV, while the USB-8451 "
			  "IO voltage levels are 3.3V.\n"
			  "Ignoring this because ignore_io_voltage_limits parameter is set.\n",
			 flash->chip->name,
			 flash->chip->voltage.max / 1000.0f);
	} else if (device_pid == USB8452) {
		msg_pwarn("The %s chip maximum voltage is %.1fV, while the USB-8452 "
			  "IO voltage is set to %.1fV.\n"
			  "Ignoring this because ignore_io_voltage_limits parameter is set.\n",
			  flash->chip->name,
			  flash->chip->voltage.max / 1000.0f,
			  io_voltage_in_mV / 1000.0f);
	}
}

static int ni845x_spi_io_voltage_check(const struct flashctx *flash)
{
	static bool first_transmit = true;

	if (first_transmit && flash->chip) {
		first_transmit = false;
		if (io_voltage_in_mV > flash->chip->voltage.max) {
			if (ignore_io_voltage_limits) {
				ni845x_warn_over_max_voltage(flash);
				return 0;
			}

			if (device_pid == USB8451) {
				msg_perr("The %s chip maximum voltage is %.1fV, while the USB-8451 "
					 "IO voltage levels are 3.3V.\nAborting operations\n",
					 flash->chip->name,
					 flash->chip->voltage.max / 1000.0f);
				return -1;
			} else if (device_pid == USB8452) {
				msg_perr("Lowering IO voltage because the %s chip maximum voltage is %.1fV, "
					 "(%.1fV was set)\n",
					 flash->chip->name,
					 flash->chip->voltage.max / 1000.0f,
					 io_voltage_in_mV / 1000.0f);
				if (usb8452_spi_set_io_voltage(flash->chip->voltage.max,
							       &io_voltage_in_mV,
							       USE_LOWER)) {
					msg_perr("Unable to lower the IO voltage below "
						 "the chip's maximum voltage\n");
					return -1;
				}
			}
		} else if (io_voltage_in_mV < flash->chip->voltage.min) {
			if (device_pid == USB8451) {
				msg_pwarn("Flash operations might be unreliable, because the %s chip's "
					  "minimum voltage is %.1fV, while the USB-8451's "
					  "IO voltage levels are 3.3V.\n",
					  flash->chip->name,
					  flash->chip->voltage.min / 1000.0f);
				return ignore_io_voltage_limits ? 0 : -1;
			} else if (device_pid == USB8452) {
				msg_pwarn("Raising the IO voltage because the %s chip's "
					  "minimum voltage is %.1fV, "
					  "(%.1fV was set)\n",
					  flash->chip->name,
					  flash->chip->voltage.min / 1000.0f,
					  io_voltage_in_mV / 1000.0f);
				if (usb8452_spi_set_io_voltage(flash->chip->voltage.min,
							       &io_voltage_in_mV,
							       USE_HIGHER)) {
					msg_pwarn("Unable to raise the IO voltage above the chip's "
						  "minimum voltage\n"
						  "Flash operations might be unreliable.\n");
					return ignore_io_voltage_limits ? 0 : -1;
				}
			}
		}
	}
	return 0;
}

static int ni845x_spi_transmit(const struct flashctx *flash,
			       unsigned int write_cnt,
			       unsigned int read_cnt,
			       const unsigned char *write_arr,
			       unsigned char *read_arr)
{
	uInt32 read_size = 0;
	uInt8 *transfer_buffer = NULL;
	int32 ret = 0;

	if (ni845x_spi_io_voltage_check(flash))
		return -1;

	transfer_buffer = calloc(write_cnt + read_cnt, sizeof(uInt8));
	if (transfer_buffer == NULL) {
		msg_gerr("Memory allocation failed!\n");
		return -1;
	}

	memcpy(transfer_buffer, write_arr, write_cnt);

	ret = ni845xSpiWriteRead(device_handle,
				 configuration_handle,
				 (write_cnt + read_cnt), transfer_buffer, &read_size, transfer_buffer);
	if (ret < 0) {
		// Negative specifies an error, meaning the function did not perform the expected behavior.
		ni845x_report_error("ni845xSpiWriteRead", ret);
		free(transfer_buffer);
		return -1;
	} else if (ret > 0) {
		// Positive specifies a warning, meaning the function performed as expected,
		// but a condition arose that might require attention.
		ni845x_report_warning("ni845xSpiWriteRead", ret);
	}

	if (read_cnt != 0 && read_arr != NULL) {
		if ((read_cnt + write_cnt) != read_size) {
			msg_perr("%s: expected and returned read count mismatch: %u expected, %ld received\n",
					 __func__, read_cnt, read_size);
			free(transfer_buffer);
			return -1;
		}
		memcpy(read_arr, &transfer_buffer[write_cnt], read_cnt);
	}
	free(transfer_buffer);
	return 0;
}

static const struct spi_master spi_programmer_ni845x = {
	.max_data_read = MAX_DATA_READ_UNLIMITED,
	.max_data_write = MAX_DATA_WRITE_UNLIMITED,
	.command = ni845x_spi_transmit,
	.multicommand = default_spi_send_multicommand,
	.read = default_spi_read,
	.write_256 = default_spi_write_256,
	.write_aai = default_spi_write_aai,
	.shutdown = ni845x_spi_shutdown,
};

static int ni845x_spi_init(void)
{
	char *speed_str = NULL;
	char *CS_str = NULL;
	char *voltage = NULL;
	char *endptr = NULL;
	int requested_io_voltage_mV = 1200;     // default the IO voltage to 1.2V
	int spi_speed_KHz = 1000;		// selecting 1 MHz SCK is a good bet
	char *serial_number = NULL;		// by default open the first connected device
	char *ignore_io_voltage_limits_str = NULL;
	int32 tmp = 0;

	// read the cs parameter (which Chip select should we use)
	CS_str = extract_programmer_param("cs");
	if (CS_str) {
		CS_number = CS_str[0] - '0';
		free(CS_str);
		if (strlen(CS_str) > 1 || CS_number < 0 || 7 < CS_number) {
			msg_perr("Only CS 0-7 supported\n");
			return 1;
		}
	}

	voltage = extract_programmer_param("voltage");
	if (voltage != NULL) {
		requested_io_voltage_mV = parse_voltage(voltage);
		free(voltage);
		if (requested_io_voltage_mV < 0)
			return 1;
	}

	serial_number = extract_programmer_param("serial");

	speed_str = extract_programmer_param("spispeed");
	if (speed_str) {
		spi_speed_KHz = strtoul(speed_str, &endptr, 0);
		if (*endptr) {
			msg_perr("The spispeed parameter passed with invalid format: %s\n",
				 speed_str);
			msg_perr("Please pass the parameter with a simple number in kHz\n");
			return 1;
		}
		free(speed_str);
	}

	ignore_io_voltage_limits = false;
	ignore_io_voltage_limits_str = extract_programmer_param("ignore_io_voltage_limits");
	if (ignore_io_voltage_limits_str
		&& strcmp(ignore_io_voltage_limits_str, "yes") == 0) {
		ignore_io_voltage_limits = true;
	}

	if (ni845x_spi_open(serial_number, &device_handle)) {
		if (serial_number) {
			msg_pinfo("Could not find any connected NI USB-8451/8452 with serialnumber: %s!\n",
				  serial_number);
			ni845x_spi_print_available_devices();
			msg_pinfo("Check the S/N field on the bottom of the device,\n"
				  "or use 'lsusb -v -d 3923:7166 | grep Serial' for USB-8451\n"
				  "or 'lsusb -v -d 3923:7514 | grep Serial' for USB-8452\n");
			free(serial_number);
		} else {
			msg_pinfo("Could not find any connected NI USB-845x device!\n");
		}
		return 1;
	}
	free(serial_number);

	// open the SPI config handle
	tmp = ni845xSpiConfigurationOpen(&configuration_handle);
	if (tmp != 0) {
		ni845x_report_error("ni845xSpiConfigurationOpen", tmp);
		ni845x_spi_shutdown(NULL);
		return 1;
	}

	if (usb8452_spi_set_io_voltage(requested_io_voltage_mV, &io_voltage_in_mV, USE_LOWER) < 0) {
		ni845x_spi_shutdown(NULL);
		return 1;	// no alert here usb8452_spi_set_io_voltage already printed that
	}

	if (ni845x_spi_set_speed(spi_speed_KHz)) {
		msg_perr("Unable to set SPI speed\n");
		ni845x_spi_shutdown(NULL);
		return 1;
	}

	return register_spi_master(&spi_programmer_ni845x, NULL);
}

const struct programmer_entry programmer_ni845x_spi = {
	.name			= "ni845x_spi",
	.type			= OTHER, // choose other because NI-845x uses own USB implementation
	.devs.note		= "National Instruments USB-845x\n",
	.init			= ni845x_spi_init,
	.map_flash_region	= fallback_map,
	.unmap_flash_region	= fallback_unmap,
	.delay			= internal_delay,
};
