/*
 * B53 register access through SPI
 *
 * Copyright (C) 2011-2013 Jonas Gorski <jogo@openwrt.org>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <asm/unaligned.h>

#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/spi/spi.h>
#include <linux/platform_data/b53.h>

#include "b53_priv.h"

#define B53_SPI_DATA		0xf0

#define B53_SPI_STATUS		0xfe
#define B53_SPI_CMD_SPIF	BIT(7)
#define B53_SPI_CMD_RACK	BIT(5)

#define B53_SPI_CMD_READ	0x00
#define B53_SPI_CMD_WRITE	0x01
#define B53_SPI_CMD_NORMAL	0x60
#define B53_SPI_CMD_FAST	0x10

#define B53_SPI_PAGE_SELECT	0xff

static inline int b53_spi_read_reg(struct spi_device *spi, u8 reg, u8 *val,
				   unsigned int len)
{
	u8 txbuf[2];

	txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_READ;
	txbuf[1] = reg;

	return spi_write_then_read(spi, txbuf, 2, val, len);
}

static inline int b53_spi_clear_status(struct spi_device *spi)
{
	unsigned int i;
	u8 rxbuf;
	int ret;

	for (i = 0; i < 10; i++) {
		ret = b53_spi_read_reg(spi, B53_SPI_STATUS, &rxbuf, 1);
		if (ret)
			return ret;

		if (!(rxbuf & B53_SPI_CMD_SPIF))
			break;

		mdelay(1);
	}

	if (i == 10)
		return -EIO;

	return 0;
}

static inline int b53_spi_set_page(struct spi_device *spi, u8 page)
{
	u8 txbuf[3];

	txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE;
	txbuf[1] = B53_SPI_PAGE_SELECT;
	txbuf[2] = page;

	return spi_write(spi, txbuf, sizeof(txbuf));
}

static inline int b53_prepare_reg_access(struct spi_device *spi, u8 page)
{
	int ret = b53_spi_clear_status(spi);

	if (ret)
		return ret;

	return b53_spi_set_page(spi, page);
}

static int b53_spi_prepare_reg_read(struct spi_device *spi, u8 reg)
{
	u8 rxbuf;
	int retry_count;
	int ret;

	ret = b53_spi_read_reg(spi, reg, &rxbuf, 1);
	if (ret)
		return ret;

	for (retry_count = 0; retry_count < 10; retry_count++) {
		ret = b53_spi_read_reg(spi, B53_SPI_STATUS, &rxbuf, 1);
		if (ret)
			return ret;

		if (rxbuf & B53_SPI_CMD_RACK)
			break;

		mdelay(1);
	}

	if (retry_count == 10)
		return -EIO;

	return 0;
}

static int b53_spi_read(struct b53_device *dev, u8 page, u8 reg, u8 *data,
			unsigned int len)
{
	struct spi_device *spi = dev->priv;
	int ret;

	ret = b53_prepare_reg_access(spi, page);
	if (ret)
		return ret;

	ret = b53_spi_prepare_reg_read(spi, reg);
	if (ret)
		return ret;

	return b53_spi_read_reg(spi, B53_SPI_DATA, data, len);
}

static int b53_spi_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val)
{
	return b53_spi_read(dev, page, reg, val, 1);
}

static int b53_spi_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val)
{
	int ret = b53_spi_read(dev, page, reg, (u8 *)val, 2);

	if (!ret)
		*val = le16_to_cpu(*val);

	return ret;
}

static int b53_spi_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val)
{
	int ret = b53_spi_read(dev, page, reg, (u8 *)val, 4);

	if (!ret)
		*val = le32_to_cpu(*val);

	return ret;
}

static int b53_spi_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val)
{
	int ret;

	*val = 0;
	ret = b53_spi_read(dev, page, reg, (u8 *)val, 6);
	if (!ret)
		*val = le64_to_cpu(*val);

	return ret;
}

static int b53_spi_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val)
{
	int ret = b53_spi_read(dev, page, reg, (u8 *)val, 8);

	if (!ret)
		*val = le64_to_cpu(*val);

	return ret;
}

static int b53_spi_write8(struct b53_device *dev, u8 page, u8 reg, u8 value)
{
	struct spi_device *spi = dev->priv;
	int ret;
	u8 txbuf[3];

	ret = b53_prepare_reg_access(spi, page);
	if (ret)
		return ret;

	txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE;
	txbuf[1] = reg;
	txbuf[2] = value;

	return spi_write(spi, txbuf, sizeof(txbuf));
}

static int b53_spi_write16(struct b53_device *dev, u8 page, u8 reg, u16 value)
{
	struct spi_device *spi = dev->priv;
	int ret;
	u8 txbuf[4];

	ret = b53_prepare_reg_access(spi, page);
	if (ret)
		return ret;

	txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE;
	txbuf[1] = reg;
	put_unaligned_le16(value, &txbuf[2]);

	return spi_write(spi, txbuf, sizeof(txbuf));
}

static int b53_spi_write32(struct b53_device *dev, u8 page, u8 reg, u32 value)
{
	struct spi_device *spi = dev->priv;
	int ret;
	u8 txbuf[6];

	ret = b53_prepare_reg_access(spi, page);
	if (ret)
		return ret;

	txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE;
	txbuf[1] = reg;
	put_unaligned_le32(value, &txbuf[2]);

	return spi_write(spi, txbuf, sizeof(txbuf));
}

static int b53_spi_write48(struct b53_device *dev, u8 page, u8 reg, u64 value)
{
	struct spi_device *spi = dev->priv;
	int ret;
	u8 txbuf[10];

	ret = b53_prepare_reg_access(spi, page);
	if (ret)
		return ret;

	txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE;
	txbuf[1] = reg;
	put_unaligned_le64(value, &txbuf[2]);

	return spi_write(spi, txbuf, sizeof(txbuf) - 2);
}

static int b53_spi_write64(struct b53_device *dev, u8 page, u8 reg, u64 value)
{
	struct spi_device *spi = dev->priv;
	int ret;
	u8 txbuf[10];

	ret = b53_prepare_reg_access(spi, page);
	if (ret)
		return ret;

	txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE;
	txbuf[1] = reg;
	put_unaligned_le64(value, &txbuf[2]);

	return spi_write(spi, txbuf, sizeof(txbuf));
}

static const struct b53_io_ops b53_spi_ops = {
	.read8 = b53_spi_read8,
	.read16 = b53_spi_read16,
	.read32 = b53_spi_read32,
	.read48 = b53_spi_read48,
	.read64 = b53_spi_read64,
	.write8 = b53_spi_write8,
	.write16 = b53_spi_write16,
	.write32 = b53_spi_write32,
	.write48 = b53_spi_write48,
	.write64 = b53_spi_write64,
};

static int b53_spi_probe(struct spi_device *spi)
{
	struct b53_device *dev;
	int ret;

	dev = b53_switch_alloc(&spi->dev, &b53_spi_ops, spi);
	if (!dev)
		return -ENOMEM;

	if (spi->dev.platform_data)
		dev->pdata = spi->dev.platform_data;

	ret = b53_switch_register(dev);
	if (ret)
		return ret;

	spi_set_drvdata(spi, dev);

	return 0;
}

static int b53_spi_remove(struct spi_device *spi)
{
	struct b53_device *dev = spi_get_drvdata(spi);

	if (dev)
		b53_switch_remove(dev);

	return 0;
}

static struct spi_driver b53_spi_driver = {
	.driver = {
		.name	= "b53-switch",
	},
	.probe	= b53_spi_probe,
	.remove	= b53_spi_remove,
};

module_spi_driver(b53_spi_driver);

MODULE_AUTHOR("Jonas Gorski <jogo@openwrt.org>");
MODULE_DESCRIPTION("B53 SPI access driver");
MODULE_LICENSE("Dual BSD/GPL");
