/*
 * Copyright (C) 2013-2014 Google Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
#ifndef __BBSI_H
#define __BBSI_H

/*
 * Resources:
 * BCM6803 Data Sheet (Document ID: 6803-DS205-R), Chapter 5: Host Interface and CPU
 * BBVLSI Serial Interface (BBSI) (Document ID: BBSI-UM200-R)
 */

#include <linux/netdevice.h>
#include <linux/spi/spi.h>

#ifndef KSEG1
#define KSEG1 0  // just to appease non-MIPS CPUs. Not really used.
#endif

#define BP_MOCA_MAX_NUM 1

#define SPI_FIFO_LEN 32

#define BBSI_COMMAND_BYTE 0x80
#define STATUS_REGISTER_ADDR 0x06
#define CONFIG_REGISTER_ADDR 0x07
#define DATA0_REGISTER_ADDR 0x0c

#define READ_RBUS (1<<0)
#define SPECULATIVE_READ_EN (1<<1)
#define NO_RBUS_ADDR_INC (1<<2)

#define STATUS_BUSY (1<<4)

enum bbsi_operation_state {
	START,
	COMMAND_STATE,
	DATA_STATE,
	POLLSTATUS_STATE,
	DONE,
	FAIL,
};

struct bbsi_operation {
	enum bbsi_operation_state state;
	struct spi_device *spi;
	struct spi_message sm;
	struct spi_transfer st[2];
	/* address on MoCA chip we want to read from/write to */
	uint32_t addr;
	/* len must be a multiple of 4 */
	size_t len;
	uint8_t *data;
	/* number of bytes already read or written. data_len <= len */
	size_t data_len;
	uint8_t tx_buf[8];
	uint8_t rx_buf[SPI_FIFO_LEN - 2];
	/* See interpret_data() for a definition of rx_state */
	int rx_state;
	struct completion done;
};

/*
 * The exact values here don't matter, as they're translated into "real"
 * values before talking to mocad.  This is just for the device registration
 * tables.
 */
enum {
	BP_MOCA_TYPE_WAN,
	BP_MOCA_TYPE_LAN,
};

enum {
	BP_MOCA_RF_BAND_D_LOW,
	BP_MOCA_RF_BAND_D_HIGH,
	BP_MOCA_RF_BAND_EXT_D,
	BP_MOCA_RF_BAND_E,
	BP_MOCA_RF_BAND_F,
};

typedef struct BpMocaInfo {
	int type;
	int rfBand;
} BP_MOCA_INFO;

static void BpGetMocaInfo(BP_MOCA_INFO *chips, int *nchips) {
	if (*nchips >= 1) {
		*nchips = 1;
		chips[0].type = BP_MOCA_TYPE_LAN;
		chips[0].rfBand = BP_MOCA_RF_BAND_E;
	}
}

// TODO(apenwarr): don't make this global.
//   Or fix the driver to just only enable/disable interrupts at the right
//   times.
static int irq_disabled = 0;

static void kerSysMocaHostIntrEnable(struct spi_device *spi) {
	if (irq_disabled == 1) {
		irq_disabled = 0;
		enable_irq(spi->irq);
	}
}

static void kerSysMocaHostIntrDisable(struct spi_device *spi) {
	if (irq_disabled == 0) {
		disable_irq_nosync(spi->irq);
		irq_disabled = 1;
	}
}

static void state_machine_read(void *context);
static void state_machine_write(void *context);

static void bbsi_op_fail(struct bbsi_operation *t) {
	t->state = FAIL;
	complete(&t->done);
}

static int send_readcmd(struct bbsi_operation *t, int burst) {
	int ret;
	spi_message_init(&t->sm);
	t->sm.complete = state_machine_read;
	t->sm.context = t;
	t->tx_buf[0] = BBSI_COMMAND_BYTE | 0x01;
	t->tx_buf[1] = CONFIG_REGISTER_ADDR;
	t->tx_buf[2] = READ_RBUS |
		(burst ? SPECULATIVE_READ_EN : NO_RBUS_ADDR_INC);
	writel(cpu_to_be32(t->addr), t->tx_buf + 3);
	t->st[0] = ((struct spi_transfer) { .tx_buf = t->tx_buf, .len = 7 });
	spi_message_add_tail(&t->st[0], &t->sm);
	ret = spi_async_locked(t->spi, &t->sm);
	if (ret) {
		pr_err("%s: spi_async failed with %d\n", __func__, ret);
		bbsi_op_fail(t);
	}
	return ret;
}

static int send_writecmd(struct bbsi_operation *t) {
	int ret;
	spi_message_init(&t->sm);
	t->sm.complete = state_machine_write;
	t->sm.context = t;
	t->tx_buf[0] = BBSI_COMMAND_BYTE | 0x01;
	t->tx_buf[1] = CONFIG_REGISTER_ADDR;
	t->tx_buf[2] = 0;
	writel(cpu_to_be32(t->addr), t->tx_buf + 3);
	t->st[0] = ((struct spi_transfer) { .tx_buf = t->tx_buf, .len = 7 });
	spi_message_add_tail(&t->st[0], &t->sm);
	ret = spi_async_locked(t->spi, &t->sm);
	if (ret) {
		pr_err("%s: spi_async failed with %d\n", __func__, ret);
		bbsi_op_fail(t);
	}
	return ret;
}

static int send_pollstatuscmd(struct bbsi_operation *t, void (*complete)(void *context)) {
	int ret;
	spi_message_init(&t->sm);
	t->sm.complete = complete;
	t->sm.context = t;
	t->tx_buf[0] = BBSI_COMMAND_BYTE;
	t->tx_buf[1] = STATUS_REGISTER_ADDR;
	t->st[0] = ((struct spi_transfer) { .tx_buf = t->tx_buf, .len = 2 });
	t->st[1] = ((struct spi_transfer) { .rx_buf = t->rx_buf, .len = 1 });
	spi_message_add_tail(&t->st[0], &t->sm);
	spi_message_add_tail(&t->st[1], &t->sm);
	ret = spi_async_locked(t->spi, &t->sm);
	if (ret) {
		pr_err("%s: spi_async failed with %d\n", __func__, ret);
		bbsi_op_fail(t);
	}
	return ret;
}

static int read_data(struct bbsi_operation *t) {
	int ret;
	spi_message_init(&t->sm);
	t->sm.complete = state_machine_read;
	t->sm.context = t;
	t->tx_buf[0] = BBSI_COMMAND_BYTE;
	/* We want to continue reading where we left off. See interpret_data()
	 * for the definition of t->rx_state */
	if (t->rx_state == 0) {
		t->tx_buf[1] = STATUS_REGISTER_ADDR;
	} else {
		t->tx_buf[1] = DATA0_REGISTER_ADDR + t->rx_state - 1;
	}
	t->st[0] = ((struct spi_transfer) { .tx_buf = t->tx_buf, .len = 2 });
	t->st[1] = ((struct spi_transfer) { .rx_buf = t->rx_buf,
			.len = sizeof(t->rx_buf)});
	spi_message_add_tail(&t->st[0], &t->sm);
	spi_message_add_tail(&t->st[1], &t->sm);
	ret = spi_async_locked(t->spi, &t->sm);
	if (ret) {
		pr_err("%s: spi_async failed with %d\n", __func__, ret);
		bbsi_op_fail(t);
	}
	return ret;
}

static int write_data(struct bbsi_operation *t) {
	int ret;
	size_t len;
	len = min(t->len - t->data_len, sizeof(t->rx_buf));
	spi_message_init(&t->sm);
	t->sm.complete = state_machine_write;
	t->sm.context = t;
	t->tx_buf[0] = BBSI_COMMAND_BYTE | 0x01;
	t->tx_buf[1] = DATA0_REGISTER_ADDR + (t->data_len & 3);
	t->st[0] = ((struct spi_transfer) { .tx_buf = t->tx_buf, .len = 2 });
	t->st[1] = ((struct spi_transfer) { .tx_buf = t->data + t->data_len,
			.len = len});
	spi_message_add_tail(&t->st[0], &t->sm);
	spi_message_add_tail(&t->st[1], &t->sm);
	ret = spi_async_locked(t->spi, &t->sm);
	if (ret) {
		pr_err("%s: spi_async failed with %d\n", __func__, ret);
		bbsi_op_fail(t);
	}
	t->data_len += len;
	return ret;
}

static int interpret_data(struct bbsi_operation *t) {
	/* The bytes we are receiving over the SPI bus are the values of
	 * registers in the BBSI interface on the BCM6803. The register csrAddr
	 * points to the register that we are going to read next. It cycles
	 * through the following registers:
	 *  - STATUS (t->rx_state==0)
	 *  - DATA0 (t->rx_state==1)
	 *  - DATA1 (t->rx_state==2)
	 *  - DATA2 (t->rx_state==3)
	 *  - DATA3 (t->rx_state==4)
	 *
	 * If csrAddr points to the status register, csrAddr is not incremented
	 * if the busy bit in the status register is set. As a result, we might
	 * read the status register multiple times before we get to DATA0. We
	 * therefore might have to skip over multiple status bytes.
	 *
	 * t->rx_state defines the register that we are going to read next: 0
	 * stands for STATUS, 1 stands for DATA0, 2 for DATA1 and so on.
	*/
	uint8_t *r;
	r = t->rx_buf;
	for(r = t->rx_buf;r < t->rx_buf + sizeof(t->rx_buf);r++) {
		if (t->rx_state == 0) {
			if (*r & STATUS_BUSY)
				/* t->rx_state stays at 0 because the next byte
				 * will be another status byte */
				continue;
			else if (*r) {
				pr_err("rbus error 0x%02x while trying to read %u "
						"bytes from 0x%08x\n",
						(unsigned) *r, t->len, t->addr);
				bbsi_op_fail(t);
				return -1;
			} else
				/* The busy bit is not set which means that the next byte will be DATA0. */
				t->rx_state = 1;
		} else {
			BUG_ON(t->data_len >= t->len);
			t->data[t->data_len++] = *r;
			/* t->rx_state==4 means that we just read DATA3. The
			 * next byte will be a status byte (t->rx_state==0) */
			t->rx_state++;
			t->rx_state%=5;
			if (t->data_len == t->len) return 0;
		}

	}
	return 0;
}

static void state_machine_read(void *context) {
	struct bbsi_operation *t = (struct bbsi_operation *) context;
	int ret;

	BUG_ON(t->len&3);

	switch (t->state) {
		case START:
			t->state = COMMAND_STATE;
			ret = send_readcmd(t, t->len>4);
			if (ret) return;
			break;
		case COMMAND_STATE:
			if (t->sm.status) {
				pr_err("readcmd returned bad status %d\n", t->sm.status);
				bbsi_op_fail(t);
				return;
			}
			t->state = DATA_STATE;
			ret = read_data(t);
			if (ret) return;
			break;
		case DATA_STATE:
			if (t->sm.status) {
				pr_err("read_data returned bad status %d\n", t->sm.status);
				bbsi_op_fail(t);
				return;
			}
			if (interpret_data(t)) return;
			if (t->data_len == t->len) {
				t->state = DONE;
				complete(&t->done);
			} else {
				/* Stay in this state */
				ret = read_data(t);
				if (ret) return;
			}
			break;
		default:
			BUG();
			break;
	}
}

static void state_machine_write(void *context) {
	struct bbsi_operation *t = (struct bbsi_operation *) context;
	int ret;

	BUG_ON(t->len&3);

	switch (t->state) {
		case START:
			t->state = COMMAND_STATE;
			ret = send_writecmd(t);
			if (ret) return;
			break;
		case COMMAND_STATE:
			if (t->sm.status) {
				pr_err("writecmd returned bad status %d\n", t->sm.status);
				bbsi_op_fail(t);
				return;
			}
			t->state = DATA_STATE;
			ret = write_data(t);
			if (ret) return;
			break;
		case DATA_STATE:
			if (t->sm.status) {
				pr_err("write_data returned bad status %d\n", t->sm.status);
				bbsi_op_fail(t);
				return;
			}
			if (t->data_len == t->len) {
				t->state = POLLSTATUS_STATE;
				ret = send_pollstatuscmd(t, state_machine_write);
				if (ret) return;
			} else {
				/* Stay in this state */
				ret = write_data(t);
				if (ret) return;
			}
			break;
		case POLLSTATUS_STATE:
			if (t->sm.status) {
				pr_err("pollstatuscmd returned bad status %d\n", t->sm.status);
				bbsi_op_fail(t);
				return;
			}
			if (*t->rx_buf & STATUS_BUSY) {
				/* Stay in this state */
				ret = send_pollstatuscmd(t, state_machine_write);
				if (ret) return;
			} else if (*t->rx_buf) {
				pr_err("rbus error 0x%02x while trying to write %u "
						"bytes to 0x%08x\n",
						(unsigned) *t->rx_buf, t->len, t->addr);
				bbsi_op_fail(t);
			} else {
				t->state = DONE;
				complete(&t->done);
			}
			break;
		default:
			BUG();
			break;
	}
}

static uint32_t bbsi_read(struct spi_device *spi, uint32_t addr, void *dst, size_t len) {
	struct bbsi_operation *t;
	t = kmalloc(sizeof(*t), GFP_KERNEL);
	t->state = START;
	t->spi = spi;
	t->addr = addr;
	t->len = len;
	t->data = dst;
	t->data_len = 0;
	t->rx_state = 0;
	init_completion(&t->done);
	state_machine_read((void*) t);
	wait_for_completion(&t->done);
	kfree(t);
	return 0;
}

static uint32_t bbsi_write(struct spi_device *spi, uint32_t addr, const void *src, size_t len) {
	struct bbsi_operation *t;
	t = kmalloc(sizeof(*t), GFP_KERNEL);
	t->state = START;
	t->spi = spi;
	t->addr = addr;
	t->len = len;
	t->data = (void*) src;
	t->data_len = 0;
	init_completion(&t->done);
	state_machine_write((void*) t);
	wait_for_completion(&t->done);
	kfree(t);
	return 0;
}

static uint32_t _spi_read32(struct spi_device *spi, uint32_t addr) {
	uint32_t retval = 0;

	spi_bus_lock(spi->master);
	bbsi_read(spi, addr, &retval, sizeof(retval));
	spi_bus_unlock(spi->master);
	return be32_to_cpu(retval);
}

static void _spi_write32(struct spi_device *spi, uint32_t addr, uint32_t value) {
	spi_bus_lock(spi->master);
	value = cpu_to_be32(value);
	bbsi_write(spi, addr, &value, sizeof(value));
	spi_bus_unlock(spi->master);
}

static uint32_t kerSysBcmSpiSlaveReadReg32(struct spi_device *spi, uint32_t addr) {
	return _spi_read32(spi, addr);
}

static void kerSysBcmSpiSlaveWriteReg32(struct spi_device *spi, uint32_t addr, uint32_t value) {
	_spi_write32(spi, addr, value);
}

static void kerSysBcmSpiSlaveReadBuf(struct spi_device *spi, uint32_t addr, void *dst, int len, int wordsize) {
	if (len == 0) {
		pr_warn("spi readbuf: buffer size 0 invalid\n");
		return;
	}
	if (wordsize != 4) {
		pr_info("SPI readbuf: only word size == 4 bytes is supported!\n");
		return;
	}
	spi_bus_lock(spi->master);
	bbsi_read(spi, addr, dst, len);
	spi_bus_unlock(spi->master);
}

static void kerSysBcmSpiSlaveWriteBuf(struct spi_device *spi, uint32_t addr, const void *src, int len, int wordsize) {
	if (len > 8192) {
		pr_warn("spi writebuf: buffer size %d is too large\n", len);
		return;
	}
	if (wordsize != 4 || len&3) {
		pr_err("SPI writebuf: only word size == 4 bytes is supported!\n");
		return;
	}

	spi_bus_lock(spi->master);
	bbsi_write(spi, addr, src, len);
	spi_bus_unlock(spi->master);
}

#endif // __BBSI_H
