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

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "flash.h"
#include "programmer.h"
#include "spi.h"

/* Length of half a clock period in usecs. */
static int bitbang_spi_half_period;

static const struct bitbang_spi_master *bitbang_spi_master = NULL;

/* Note that CS# is active low, so val=0 means the chip is active. */
static void bitbang_spi_set_cs(int val)
{
	bitbang_spi_master->set_cs(val);
}

static void bitbang_spi_set_sck(int val)
{
	bitbang_spi_master->set_sck(val);
}

static void bitbang_spi_set_mosi(int val)
{
	bitbang_spi_master->set_mosi(val);
}

static int bitbang_spi_get_miso(void)
{
	return bitbang_spi_master->get_miso();
}

static void bitbang_spi_request_bus(void)
{
	if (bitbang_spi_master->request_bus)
		bitbang_spi_master->request_bus();
}

static void bitbang_spi_release_bus(void)
{
	if (bitbang_spi_master->release_bus)
		bitbang_spi_master->release_bus();
}

static int bitbang_spi_send_command(const struct flashctx *flash,
				    unsigned int writecnt, unsigned int readcnt,
				    const unsigned char *writearr,
				    unsigned char *readarr);

static const struct spi_master spi_master_bitbang = {
	.type		= SPI_CONTROLLER_BITBANG,
	.max_data_read	= MAX_DATA_READ_UNLIMITED,
	.max_data_write	= MAX_DATA_WRITE_UNLIMITED,
	.command	= bitbang_spi_send_command,
	.multicommand	= default_spi_send_multicommand,
	.read		= default_spi_read,
	.write_256	= default_spi_write_256,
};

int register_spi_bitbang_master(const struct bitbang_spi_master *master)
{
	/* BITBANG_SPI_INVALID is 0, so if someone forgot to initialize ->type,
	 * we catch it here. Same goes for missing initialization of bitbanging
	 * functions.
	 */
	if (!master || master->type == BITBANG_SPI_INVALID || !master->set_cs ||
	    !master->set_sck || !master->set_mosi || !master->get_miso) {
		msg_perr("Incomplete SPI bitbang master setting!\n"
			 "Please report a bug at flashrom@flashrom.org\n");
		return 1;
	}
	if (bitbang_spi_master) {
		msg_perr("SPI bitbang master already initialized!\n"
			 "Please report a bug at flashrom@flashrom.org\n");
		return 1;
	}

	bitbang_spi_master = master;
	bitbang_spi_half_period = master->half_period;

	register_spi_master(&spi_master_bitbang);

	/* FIXME: Run bitbang_spi_request_bus here or in programmer init? */
	bitbang_spi_set_cs(1);
	bitbang_spi_set_sck(0);
	bitbang_spi_set_mosi(0);
	return 0;
}

int bitbang_spi_shutdown(const struct bitbang_spi_master *master)
{
	if (!bitbang_spi_master) {
		msg_perr("Shutting down an uninitialized SPI bitbang master!\n"
			 "Please report a bug at flashrom@flashrom.org\n");
		return 1;
	}
	if (master != bitbang_spi_master) {
		msg_perr("Shutting down a mismatched SPI bitbang master!\n"
			 "Please report a bug at flashrom@flashrom.org\n");
		return 1;
	}

	/* FIXME: Run bitbang_spi_release_bus here or per command? */
	bitbang_spi_master = NULL;
	return 0;
}

static uint8_t bitbang_spi_readwrite_byte(uint8_t val)
{
	uint8_t ret = 0;
	int i;

	for (i = 7; i >= 0; i--) {
		bitbang_spi_set_mosi((val >> i) & 1);
		programmer_delay(bitbang_spi_half_period);
		bitbang_spi_set_sck(1);
		ret <<= 1;
		ret |= bitbang_spi_get_miso();
		programmer_delay(bitbang_spi_half_period);
		bitbang_spi_set_sck(0);
	}
	return ret;
}

static int bitbang_spi_send_command(const struct flashctx *flash,
				    unsigned int writecnt, unsigned int readcnt,
				    const unsigned char *writearr,
				    unsigned char *readarr)
{
	int i;

	/* FIXME: Run bitbang_spi_request_bus here or in programmer init?
	 * Requesting and releasing the SPI bus is handled in here to allow the
	 * programmer to use its own SPI engine for native accesses.
	 */
	bitbang_spi_request_bus();
	bitbang_spi_set_cs(0);
	for (i = 0; i < writecnt; i++)
		bitbang_spi_readwrite_byte(writearr[i]);
	for (i = 0; i < readcnt; i++)
		readarr[i] = bitbang_spi_readwrite_byte(0);

	programmer_delay(bitbang_spi_half_period);
	bitbang_spi_set_cs(1);
	programmer_delay(bitbang_spi_half_period);
	/* FIXME: Run bitbang_spi_release_bus here or in programmer init? */
	bitbang_spi_release_bus();

	return 0;
}
