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

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

struct bitbang_spi_master_data {
	const struct bitbang_spi_master *mst;
	void *spi_data;
};

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

static void bitbang_spi_set_sck(const struct bitbang_spi_master * const master, int val, void *spi_data)
{
	master->set_sck(val, spi_data);
}

static void bitbang_spi_request_bus(const struct bitbang_spi_master * const master, void *spi_data)
{
	if (master->request_bus)
		master->request_bus(spi_data);
}

static void bitbang_spi_release_bus(const struct bitbang_spi_master * const master, void *spi_data)
{
	if (master->release_bus)
		master->release_bus(spi_data);
}

static void bitbang_spi_set_sck_set_mosi(const struct bitbang_spi_master * const master, int sck, int mosi,
					void *spi_data)
{
	if (master->set_sck_set_mosi) {
		master->set_sck_set_mosi(sck, mosi, spi_data);
		return;
	}

	master->set_sck(sck, spi_data);
	master->set_mosi(mosi, spi_data);
}

static int bitbang_spi_set_sck_get_miso(const struct bitbang_spi_master * const master, int sck,
					void *spi_data)
{
	if (master->set_sck_get_miso)
		return master->set_sck_get_miso(sck, spi_data);

	master->set_sck(sck, spi_data);
	return master->get_miso(spi_data);
}

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

static const struct spi_master spi_master_bitbang = {
	.features	= SPI_MASTER_4BA,
	.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,
	.shutdown	= bitbang_spi_shutdown,
	.probe_opcode	= default_spi_probe_opcode,
};

static int bitbang_spi_shutdown(void *data)
{
	/* FIXME: Run bitbang_spi_release_bus here or per command? */
	free(data);
	return 0;
}

int register_spi_bitbang_master(const struct bitbang_spi_master *master, void *spi_data)
{
	struct spi_master mst = spi_master_bitbang;
	/* If someone forgot to initialize a bitbang function, we catch it here. */
	if (!master || !master->set_cs ||
	    !master->set_sck || !master->set_mosi || !master->get_miso ||
	    (master->request_bus && !master->release_bus) ||
	    (!master->request_bus && master->release_bus)) {
		msg_perr("Incomplete SPI bitbang master setting!\n"
			 "Please report a bug at flashrom-stable@flashrom.org\n");
		return ERROR_FLASHROM_BUG;
	}

	struct bitbang_spi_master_data *data = calloc(1, sizeof(struct bitbang_spi_master_data));
	if (!data) {
		msg_perr("Out of memory!\n");
		return ERROR_OOM;
	}

	data->mst = master;
	data->spi_data = spi_data;
	register_spi_master(&mst, data);

	/* Only mess with the bus if we're sure nobody else uses it. */
	bitbang_spi_request_bus(master, spi_data);
	bitbang_spi_set_cs(master, 1, spi_data);
	bitbang_spi_set_sck_set_mosi(master, 0, 0, spi_data);
	/* FIXME: Release SPI bus here and request it again for each command or
	 * don't release it now and only release it on programmer shutdown?
	 */
	bitbang_spi_release_bus(master, spi_data);
	return 0;
}

static uint8_t bitbang_spi_read_byte(const struct bitbang_spi_master *master, void *spi_data)
{
	uint8_t ret = 0;
	int i;

	for (i = 7; i >= 0; i--) {
		if (i == 0)
			bitbang_spi_set_sck_set_mosi(master, 0, 0, spi_data);
		else
			bitbang_spi_set_sck(master, 0, spi_data);
		programmer_delay(master->half_period);
		ret <<= 1;
		ret |= bitbang_spi_set_sck_get_miso(master, 1, spi_data);
		programmer_delay(master->half_period);
	}
	return ret;
}

static void bitbang_spi_write_byte(const struct bitbang_spi_master *master, uint8_t val, void *spi_data)
{
	int i;

	for (i = 7; i >= 0; i--) {
		bitbang_spi_set_sck_set_mosi(master, 0, (val >> i) & 1, spi_data);
		programmer_delay(master->half_period);
		bitbang_spi_set_sck(master, 1, spi_data);
		programmer_delay(master->half_period);
	}
}

static int bitbang_spi_send_command(const struct flashctx *flash,
				    unsigned int writecnt, unsigned int readcnt,
				    const unsigned char *writearr,
				    unsigned char *readarr)
{
	unsigned int i;
	const struct bitbang_spi_master_data *data = flash->mst->spi.data;
	const struct bitbang_spi_master *master = data->mst;

	/* 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(master, data->spi_data);
	bitbang_spi_set_cs(master, 0, data->spi_data);
	for (i = 0; i < writecnt; i++)
		bitbang_spi_write_byte(master, writearr[i], data->spi_data);
	for (i = 0; i < readcnt; i++)
		readarr[i] = bitbang_spi_read_byte(master, data->spi_data);

	bitbang_spi_set_sck(master, 0, data->spi_data);
	programmer_delay(master->half_period);
	bitbang_spi_set_cs(master, 1, data->spi_data);
	programmer_delay(master->half_period);
	/* FIXME: Run bitbang_spi_release_bus here or in programmer init? */
	bitbang_spi_release_bus(master, data->spi_data);

	return 0;
}
