/*
 * This file is part of the flashrom project.
 *
 * Copyright (C) 2009,2010 Carl-Daniel Hailfinger
 *
 * 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 various LPT adapters.
 *
 * This driver uses non-portable direct I/O port accesses which won't work on
 * any non-x86 platform, and even on x86 there is a high chance there will be
 * collisions with any loaded parallel port drivers.
 * The big advantage of direct port I/O is OS independence and speed because
 * most OS parport drivers will perform many unnecessary accesses although
 * this driver just treats the parallel port as a GPIO set.
 */

#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include "flash.h"
#include "programmer.h"
#include "hwaccess_x86_io.h"

/* We have two sets of pins, out and in. The numbers for both sets are
 * independent and are bitshift values, not real pin numbers.
 * Default settings are for the RayeR hardware.
 */

struct rayer_programmer {
	const char *type;
	const enum test_state status;
	const char *description;
	const void *dev_data;
};

struct rayer_pinout {
	uint8_t cs_bit;
	uint8_t sck_bit;
	uint8_t mosi_bit;
	uint8_t miso_bit;
	void (*preinit)(const void *);
	int (*shutdown)(void *);
};

static const struct rayer_pinout rayer_spipgm = {
	.cs_bit = 5,
	.sck_bit = 6,
	.mosi_bit = 7,
	.miso_bit = 6,
};

static void dlc5_preinit(const void *);
static int dlc5_shutdown(void *);

static const struct rayer_pinout xilinx_dlc5 = {
	.cs_bit = 2,
	.sck_bit = 1,
	.mosi_bit = 0,
	.miso_bit = 4,
	.preinit =  dlc5_preinit,
	.shutdown = dlc5_shutdown,
};

static void byteblaster_preinit(const void *);
static int byteblaster_shutdown(void *);

static const struct rayer_pinout altera_byteblastermv = {
	.cs_bit = 1,
	.sck_bit = 0,
	.mosi_bit = 6,
	.miso_bit = 7,
	.preinit =  byteblaster_preinit,
	.shutdown = byteblaster_shutdown,
};

static void stk200_preinit(const void *);
static int stk200_shutdown(void *);

static const struct rayer_pinout atmel_stk200 = {
	.cs_bit = 7,
	.sck_bit = 4,
	.mosi_bit = 5,
	.miso_bit = 6,
	.preinit =  stk200_preinit,
	.shutdown = stk200_shutdown,
};

static const struct rayer_pinout wiggler_lpt = {
	.cs_bit = 1,
	.sck_bit = 2,
	.mosi_bit = 3,
	.miso_bit = 7,
};

static const struct rayer_pinout spi_tt = {
	.cs_bit = 2,
	.sck_bit = 0,
	.mosi_bit = 4,
	.miso_bit = 7,
};

static const struct rayer_programmer rayer_spi_types[] = {
	{"rayer",		NT,	"RayeR SPIPGM",					&rayer_spipgm},
	{"xilinx",		NT,	"Xilinx Parallel Cable III (DLC 5)",		&xilinx_dlc5},
	{"byteblastermv",	OK,	"Altera ByteBlasterMV",				&altera_byteblastermv},
	{"stk200",		NT,	"Atmel STK200/300 adapter",			&atmel_stk200},
	{"wiggler",		OK,	"Wiggler LPT",					&wiggler_lpt},
	{"spi_tt",		NT,	"SPI Tiny Tools (SPI_TT LPT)",			&spi_tt},
	{0},
};

static const struct rayer_pinout *pinout = NULL;

static uint16_t lpt_iobase;

/* Cached value of last byte sent. */
static uint8_t lpt_outbyte;

static void rayer_bitbang_set_cs(int val, void *spi_data)
{
	lpt_outbyte &= ~(1 << pinout->cs_bit);
	lpt_outbyte |= (val << pinout->cs_bit);
	OUTB(lpt_outbyte, lpt_iobase);
}

static void rayer_bitbang_set_sck(int val, void *spi_data)
{
	lpt_outbyte &= ~(1 << pinout->sck_bit);
	lpt_outbyte |= (val << pinout->sck_bit);
	OUTB(lpt_outbyte, lpt_iobase);
}

static void rayer_bitbang_set_mosi(int val, void *spi_data)
{
	lpt_outbyte &= ~(1 << pinout->mosi_bit);
	lpt_outbyte |= (val << pinout->mosi_bit);
	OUTB(lpt_outbyte, lpt_iobase);
}

static int rayer_bitbang_get_miso(void *spi_data)
{
	uint8_t tmp;

	tmp = INB(lpt_iobase + 1) ^ 0x80; // bit.7 inverted
	tmp = (tmp >> pinout->miso_bit) & 0x1;
	return tmp;
}

static const struct bitbang_spi_master bitbang_spi_master_rayer = {
	.set_cs		= rayer_bitbang_set_cs,
	.set_sck	= rayer_bitbang_set_sck,
	.set_mosi	= rayer_bitbang_set_mosi,
	.get_miso	= rayer_bitbang_get_miso,
	.half_period	= 0,
};

static int rayer_spi_init(struct flashprog_programmer *const flashprog)
{
	const struct rayer_programmer *prog = rayer_spi_types;
	char *arg = NULL;

	/* Non-default port requested? */
	arg = extract_programmer_param("iobase");
	if (arg) {
		char *endptr = NULL;
		unsigned long tmp;
		tmp = strtoul(arg, &endptr, 0);
		/* Port 0, port >0x10000, unaligned ports and garbage strings
		 * are rejected.
		 */
		if (!tmp || (tmp >= 0x10000) || (tmp & 0x3) ||
		    (*endptr != '\0')) {
			/* Using ports below 0x100 is a really bad idea, and
			 * should only be done if no port between 0x100 and
			 * 0xfffc works due to routing issues.
			 */
			msg_perr("Error: iobase= specified, but the I/O base "
				 "given was invalid.\nIt must be a multiple of "
				 "0x4 and lie between 0x100 and 0xfffc.\n");
			free(arg);
			return 1;
		} else {
			lpt_iobase = (uint16_t)tmp;
			msg_pinfo("Non-default I/O base requested. This will "
				  "not change the hardware settings.\n");
		}
	} else {
		/* Pick a default value for the I/O base. */
		lpt_iobase = 0x378;
	}
	free(arg);

	msg_pdbg("Using address 0x%x as I/O base for parallel port access.\n",
		 lpt_iobase);

	arg = extract_programmer_param("type");
	if (arg) {
		for (; prog->type != NULL; prog++) {
			if (strcasecmp(arg, prog->type) == 0) {
				break;
			}
		}
		if (prog->type == NULL) {
			msg_perr("Error: Invalid device type specified.\n");
			free(arg);
			return 1;
		}
		free(arg);
	}
	msg_pinfo("Using %s pinout.\n", prog->description);
	pinout = (struct rayer_pinout *)prog->dev_data;

	if (rget_io_perms())
		return 1;

	/* Get the initial value before writing to any line. */
	lpt_outbyte = INB(lpt_iobase);

	if (pinout->shutdown)
		register_shutdown(pinout->shutdown, (void*)pinout);
	if (pinout->preinit)
		pinout->preinit(pinout);

	if (register_spi_bitbang_master(&bitbang_spi_master_rayer, NULL))
		return 1;

	return 0;
}

static void byteblaster_preinit(const void *data){
	msg_pdbg("byteblaster_preinit\n");
	/* Assert #EN signal. */
	OUTB(2, lpt_iobase + 2 );
}

static int byteblaster_shutdown(void *data){
	msg_pdbg("byteblaster_shutdown\n");
	/* De-Assert #EN signal. */
	OUTB(0, lpt_iobase + 2 );
	return 0;
}

static void stk200_preinit(const void *data) {
	msg_pdbg("stk200_init\n");
	/* Assert #EN signals, set LED signal. */
	lpt_outbyte = (1 << 6) ;
	OUTB(lpt_outbyte, lpt_iobase);
}

static int stk200_shutdown(void *data) {
	msg_pdbg("stk200_shutdown\n");
	/* Assert #EN signals, clear LED signal. */
	lpt_outbyte = (1 << 2) | (1 << 3);
	OUTB(lpt_outbyte, lpt_iobase);
	return 0;
}

static void dlc5_preinit(const void *data) {
	msg_pdbg("dlc5_preinit\n");
	/* Assert pin 6 to receive MISO. */
	lpt_outbyte |= (1<<4);
	OUTB(lpt_outbyte, lpt_iobase);
}

static int dlc5_shutdown(void *data) {
	msg_pdbg("dlc5_shutdown\n");
	/* De-assert pin 6 to force MISO low. */
	lpt_outbyte &= ~(1<<4);
	OUTB(lpt_outbyte, lpt_iobase);
	return 0;
}

const struct programmer_entry programmer_rayer_spi = {
	.name			= "rayer_spi",
	.type			= OTHER,
				/* FIXME */
	.devs.note		= "RayeR parallel port programmer\n",
	.init			= rayer_spi_init,
};
