/*
 * SPI master driver for ICP DAS LP-8841 RTC
 *
 * Copyright (C) 2016 Sergei Ianovich
 *
 * based on
 *
 * Dallas DS1302 RTC Support
 * Copyright (C) 2002 David McCullough
 * Copyright (C) 2003 - 2007 Paul Mundt
 *
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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 <linux/delay.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/spi/spi.h>

#define DRIVER_NAME	"spi_lp8841_rtc"

#define SPI_LP8841_RTC_CE	0x01
#define SPI_LP8841_RTC_CLK	0x02
#define SPI_LP8841_RTC_nWE	0x04
#define SPI_LP8841_RTC_MOSI	0x08
#define SPI_LP8841_RTC_MISO	0x01

/*
 * REVISIT If there is support for SPI_3WIRE and SPI_LSB_FIRST in SPI
 * GPIO driver, this SPI driver can be replaced by a simple GPIO driver
 * providing 3 GPIO pins.
 */

struct spi_lp8841_rtc {
	void		*iomem;
	unsigned long	state;
};

static inline void
setsck(struct spi_lp8841_rtc *data, int is_on)
{
	if (is_on)
		data->state |= SPI_LP8841_RTC_CLK;
	else
		data->state &= ~SPI_LP8841_RTC_CLK;
	writeb(data->state, data->iomem);
}

static inline void
setmosi(struct spi_lp8841_rtc *data, int is_on)
{
	if (is_on)
		data->state |= SPI_LP8841_RTC_MOSI;
	else
		data->state &= ~SPI_LP8841_RTC_MOSI;
	writeb(data->state, data->iomem);
}

static inline int
getmiso(struct spi_lp8841_rtc *data)
{
	return ioread8(data->iomem) & SPI_LP8841_RTC_MISO;
}

static inline u32
bitbang_txrx_be_cpha0_lsb(struct spi_lp8841_rtc *data,
		unsigned usecs, unsigned cpol, unsigned flags,
		u32 word, u8 bits)
{
	/* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */

	u32 shift = 32 - bits;
	/* clock starts at inactive polarity */
	for (; likely(bits); bits--) {

		/* setup LSB (to slave) on leading edge */
		if ((flags & SPI_MASTER_NO_TX) == 0)
			setmosi(data, (word & 1));

		usleep_range(usecs, usecs + 1);	/* T(setup) */

		/* sample LSB (from slave) on trailing edge */
		word >>= 1;
		if ((flags & SPI_MASTER_NO_RX) == 0)
			word |= (getmiso(data) << 31);

		setsck(data, !cpol);
		usleep_range(usecs, usecs + 1);

		setsck(data, cpol);
	}

	word >>= shift;
	return word;
}

static int
spi_lp8841_rtc_transfer_one(struct spi_master *master,
			    struct spi_device *spi,
			    struct spi_transfer *t)
{
	struct spi_lp8841_rtc	*data = spi_master_get_devdata(master);
	unsigned		count = t->len;
	const u8		*tx = t->tx_buf;
	u8			*rx = t->rx_buf;
	u8			word = 0;
	int			ret = 0;

	if (tx) {
		data->state &= ~SPI_LP8841_RTC_nWE;
		writeb(data->state, data->iomem);
		while (likely(count > 0)) {
			word = *tx++;
			bitbang_txrx_be_cpha0_lsb(data, 1, 0,
					SPI_MASTER_NO_RX, word, 8);
			count--;
		}
	} else if (rx) {
		data->state |= SPI_LP8841_RTC_nWE;
		writeb(data->state, data->iomem);
		while (likely(count > 0)) {
			word = bitbang_txrx_be_cpha0_lsb(data, 1, 0,
					SPI_MASTER_NO_TX, word, 8);
			*rx++ = word;
			count--;
		}
	} else {
		ret = -EINVAL;
	}

	spi_finalize_current_transfer(master);

	return ret;
}

static void
spi_lp8841_rtc_set_cs(struct spi_device *spi, bool enable)
{
	struct spi_lp8841_rtc *data = spi_master_get_devdata(spi->master);

	data->state = 0;
	writeb(data->state, data->iomem);
	if (enable) {
		usleep_range(4, 5);
		data->state |= SPI_LP8841_RTC_CE;
		writeb(data->state, data->iomem);
		usleep_range(4, 5);
	}
}

static int
spi_lp8841_rtc_setup(struct spi_device *spi)
{
	if ((spi->mode & SPI_CS_HIGH) == 0) {
		dev_err(&spi->dev, "unsupported active low chip select\n");
		return -EINVAL;
	}

	if ((spi->mode & SPI_LSB_FIRST) == 0) {
		dev_err(&spi->dev, "unsupported MSB first mode\n");
		return -EINVAL;
	}

	if ((spi->mode & SPI_3WIRE) == 0) {
		dev_err(&spi->dev, "unsupported wiring. 3 wires required\n");
		return -EINVAL;
	}

	return 0;
}

#ifdef CONFIG_OF
static const struct of_device_id spi_lp8841_rtc_dt_ids[] = {
	{ .compatible = "icpdas,lp8841-spi-rtc" },
	{ }
};

MODULE_DEVICE_TABLE(of, spi_lp8841_rtc_dt_ids);
#endif

static int
spi_lp8841_rtc_probe(struct platform_device *pdev)
{
	int				ret;
	struct spi_master		*master;
	struct spi_lp8841_rtc		*data;
	void				*iomem;

	master = spi_alloc_master(&pdev->dev, sizeof(*data));
	if (!master)
		return -ENOMEM;
	platform_set_drvdata(pdev, master);

	master->flags = SPI_MASTER_HALF_DUPLEX;
	master->mode_bits = SPI_CS_HIGH | SPI_3WIRE | SPI_LSB_FIRST;

	master->bus_num = pdev->id;
	master->num_chipselect = 1;
	master->setup = spi_lp8841_rtc_setup;
	master->set_cs = spi_lp8841_rtc_set_cs;
	master->transfer_one = spi_lp8841_rtc_transfer_one;
	master->bits_per_word_mask = SPI_BPW_MASK(8);
#ifdef CONFIG_OF
	master->dev.of_node = pdev->dev.of_node;
#endif

	data = spi_master_get_devdata(master);

	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	data->iomem = devm_ioremap_resource(&pdev->dev, iomem);
	ret = PTR_ERR_OR_ZERO(data->iomem);
	if (ret) {
		dev_err(&pdev->dev, "failed to get IO address\n");
		goto err_put_master;
	}

	/* register with the SPI framework */
	ret = devm_spi_register_master(&pdev->dev, master);
	if (ret) {
		dev_err(&pdev->dev, "cannot register spi master\n");
		goto err_put_master;
	}

	return ret;


err_put_master:
	spi_master_put(master);

	return ret;
}

MODULE_ALIAS("platform:" DRIVER_NAME);

static struct platform_driver spi_lp8841_rtc_driver = {
	.driver = {
		.name	= DRIVER_NAME,
		.of_match_table = of_match_ptr(spi_lp8841_rtc_dt_ids),
	},
	.probe		= spi_lp8841_rtc_probe,
};
module_platform_driver(spi_lp8841_rtc_driver);

MODULE_DESCRIPTION("SPI master driver for ICP DAS LP-8841 RTC");
MODULE_AUTHOR("Sergei Ianovich");
MODULE_LICENSE("GPL");
