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

/* Driver for serial programmers compatible with SI-Prog or AJAWe.
 *
 * See http://www.lancos.com/siprogsch.html for SI-Prog schematics and instructions.
 * See http://www.ajawe.pl/ajawe0208.htm for AJAWe serial programmer documentation.
 *
 * Pin layout for SI-Prog-like hardware:
 *
 * MOSI <-------< DTR
 * MISO >-------> CTS
 * SCK  <---+---< RTS
 *          +---> DSR
 * CS#  <-------< TXD
 *
 * and for the AJAWe serial programmer:
 *
 * MOSI <-------< DTR
 * MISO >-------> CTS
 * SCK  <-------< RTS
 * CS#  <-------< TXD
 *
 * DCE  >-------> DSR
 */

#include <stdlib.h>
#include <strings.h>
#include <string.h>

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

enum pony_type {
	TYPE_SI_PROG,
	TYPE_SERBANG,
	TYPE_AJAWE
};

/* Pins for master->slave direction */
static int pony_negate_cs = 1;
static int pony_negate_sck = 0;
static int pony_negate_mosi = 0;
/* Pins for slave->master direction */
static int pony_negate_miso = 0;

static void pony_bitbang_set_cs(int val)
{
	if (pony_negate_cs)
		val ^=  1;

	sp_set_pin(PIN_TXD, val);
}

static void pony_bitbang_set_sck(int val)
{
	if (pony_negate_sck)
		val ^=  1;

	sp_set_pin(PIN_RTS, val);
}

static void pony_bitbang_set_mosi(int val)
{
	if (pony_negate_mosi)
		val ^=  1;

	sp_set_pin(PIN_DTR, val);
}

static int pony_bitbang_get_miso(void)
{
	int tmp = sp_get_pin(PIN_CTS);

	if (pony_negate_miso)
		tmp ^= 1;

	return tmp;
}

static const struct bitbang_spi_master bitbang_spi_master_pony = {
	.set_cs		= pony_bitbang_set_cs,
	.set_sck	= pony_bitbang_set_sck,
	.set_mosi	= pony_bitbang_set_mosi,
	.get_miso	= pony_bitbang_get_miso,
	.half_period	= 0,
};

static int pony_spi_shutdown(void *data)
{
	/* Shut down serial port communication */
	int ret = serialport_shutdown(NULL);
	if (ret)
		msg_pdbg("Pony SPI shutdown failed.\n");
	else
		msg_pdbg("Pony SPI shutdown completed.\n");

	return ret;
}

static int pony_spi_init(void)
{
	int i, data_out;
	char *arg = NULL;
	enum pony_type type = TYPE_SI_PROG;
	const char *name;
	int have_device = 0;
	int have_prog = 0;

	/* The parameter is in format "dev=/dev/device,type=serbang" */
	arg = extract_programmer_param("dev");
	if (arg && strlen(arg)) {
		sp_fd = sp_openserport(arg, 9600);
		if (sp_fd == SER_INV_FD) {
			free(arg);
			return 1;
		}
		if (register_shutdown(pony_spi_shutdown, NULL) != 0) {
			free(arg);
			serialport_shutdown(NULL);
			return 1;
		}
		have_device++;
	}
	free(arg);

	if (!have_device) {
		msg_perr("Error: No valid device specified.\n"
			 "Use flashrom -p pony_spi:dev=/dev/device[,type=name]\n");
		return 1;
	}

	arg = extract_programmer_param("type");
	if (arg && !strcasecmp(arg, "serbang")) {
		type = TYPE_SERBANG;
	} else if (arg && !strcasecmp(arg, "si_prog")) {
		type = TYPE_SI_PROG;
	} else if (arg && !strcasecmp( arg, "ajawe")) {
		type = TYPE_AJAWE;
	} else if (arg && !strlen(arg)) {
		msg_perr("Error: Missing argument for programmer type.\n");
		free(arg);
		return 1;
	} else if (arg){
		msg_perr("Error: Invalid programmer type specified.\n");
		free(arg);
		return 1;
	}
	free(arg);

	/*
	 * Configure the serial port pins, depending on the used programmer.
	 */
	switch (type) {
	case TYPE_AJAWE:
		pony_negate_cs = 1;
		pony_negate_sck = 1;
		pony_negate_mosi = 1;
		pony_negate_miso = 1;
		name = "AJAWe";
		break;
	case TYPE_SERBANG:
		pony_negate_cs = 0;
		pony_negate_sck = 0;
		pony_negate_mosi = 0;
		pony_negate_miso = 1;
		name = "serbang";
		break;
	default:
	case TYPE_SI_PROG:
		pony_negate_cs = 1;
		pony_negate_sck = 0;
		pony_negate_mosi = 0;
		pony_negate_miso = 0;
		name = "SI-Prog";
		break;
	}
	msg_pdbg("Using %s programmer pinout.\n", name);

	/*
	 * Detect if there is a compatible hardware programmer connected.
	 */
	pony_bitbang_set_cs(1);
	pony_bitbang_set_sck(1);
	pony_bitbang_set_mosi(1);

	switch (type) {
	case TYPE_AJAWE:
		have_prog = 1;
		break;
	case TYPE_SI_PROG:
	case TYPE_SERBANG:
	default:
		have_prog = 1;
		/* We toggle RTS/SCK a few times and see if DSR changes too. */
		for (i = 1; i <= 10; i++) {
			data_out = i & 1;
			sp_set_pin(PIN_RTS, data_out);
			programmer_delay(1000);

			/* If DSR does not change, we are not connected to what we think */
			if (data_out != sp_get_pin(PIN_DSR)) {
				have_prog = 0;
				break;
			}
		}
		break;
	}

	if (!have_prog) {
		msg_perr("No programmer compatible with %s detected.\n", name);
		return 1;
	}

	if (register_spi_bitbang_master(&bitbang_spi_master_pony)) {
		return 1;
	}
	return 0;
}

const struct programmer_entry programmer_pony_spi = {
	.name			= "pony_spi",
	.type			= OTHER,
				/* FIXME */
	.devs.note		= "Programmers compatible with SI-Prog, serbang or AJAWe\n",
	.init			= pony_spi_init,
};
