// SPDX-License-Identifier: GPL-2.0-only
/*
 * Driver for the Diolan DLN-2 USB-SPI adapter
 *
 * Copyright (c) 2014 Intel Corporation
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/mfd/dln2.h>
#include <linux/spi/spi.h>
#include <linux/pm_runtime.h>
#include <linux/unaligned.h>

#define DLN2_SPI_MODULE_ID		0x02
#define DLN2_SPI_CMD(cmd)		DLN2_CMD(cmd, DLN2_SPI_MODULE_ID)

/* SPI commands */
#define DLN2_SPI_GET_PORT_COUNT			DLN2_SPI_CMD(0x00)
#define DLN2_SPI_ENABLE				DLN2_SPI_CMD(0x11)
#define DLN2_SPI_DISABLE			DLN2_SPI_CMD(0x12)
#define DLN2_SPI_IS_ENABLED			DLN2_SPI_CMD(0x13)
#define DLN2_SPI_SET_MODE			DLN2_SPI_CMD(0x14)
#define DLN2_SPI_GET_MODE			DLN2_SPI_CMD(0x15)
#define DLN2_SPI_SET_FRAME_SIZE			DLN2_SPI_CMD(0x16)
#define DLN2_SPI_GET_FRAME_SIZE			DLN2_SPI_CMD(0x17)
#define DLN2_SPI_SET_FREQUENCY			DLN2_SPI_CMD(0x18)
#define DLN2_SPI_GET_FREQUENCY			DLN2_SPI_CMD(0x19)
#define DLN2_SPI_READ_WRITE			DLN2_SPI_CMD(0x1A)
#define DLN2_SPI_READ				DLN2_SPI_CMD(0x1B)
#define DLN2_SPI_WRITE				DLN2_SPI_CMD(0x1C)
#define DLN2_SPI_SET_DELAY_BETWEEN_SS		DLN2_SPI_CMD(0x20)
#define DLN2_SPI_GET_DELAY_BETWEEN_SS		DLN2_SPI_CMD(0x21)
#define DLN2_SPI_SET_DELAY_AFTER_SS		DLN2_SPI_CMD(0x22)
#define DLN2_SPI_GET_DELAY_AFTER_SS		DLN2_SPI_CMD(0x23)
#define DLN2_SPI_SET_DELAY_BETWEEN_FRAMES	DLN2_SPI_CMD(0x24)
#define DLN2_SPI_GET_DELAY_BETWEEN_FRAMES	DLN2_SPI_CMD(0x25)
#define DLN2_SPI_SET_SS				DLN2_SPI_CMD(0x26)
#define DLN2_SPI_GET_SS				DLN2_SPI_CMD(0x27)
#define DLN2_SPI_RELEASE_SS			DLN2_SPI_CMD(0x28)
#define DLN2_SPI_SS_VARIABLE_ENABLE		DLN2_SPI_CMD(0x2B)
#define DLN2_SPI_SS_VARIABLE_DISABLE		DLN2_SPI_CMD(0x2C)
#define DLN2_SPI_SS_VARIABLE_IS_ENABLED		DLN2_SPI_CMD(0x2D)
#define DLN2_SPI_SS_AAT_ENABLE			DLN2_SPI_CMD(0x2E)
#define DLN2_SPI_SS_AAT_DISABLE			DLN2_SPI_CMD(0x2F)
#define DLN2_SPI_SS_AAT_IS_ENABLED		DLN2_SPI_CMD(0x30)
#define DLN2_SPI_SS_BETWEEN_FRAMES_ENABLE	DLN2_SPI_CMD(0x31)
#define DLN2_SPI_SS_BETWEEN_FRAMES_DISABLE	DLN2_SPI_CMD(0x32)
#define DLN2_SPI_SS_BETWEEN_FRAMES_IS_ENABLED	DLN2_SPI_CMD(0x33)
#define DLN2_SPI_SET_CPHA			DLN2_SPI_CMD(0x34)
#define DLN2_SPI_GET_CPHA			DLN2_SPI_CMD(0x35)
#define DLN2_SPI_SET_CPOL			DLN2_SPI_CMD(0x36)
#define DLN2_SPI_GET_CPOL			DLN2_SPI_CMD(0x37)
#define DLN2_SPI_SS_MULTI_ENABLE		DLN2_SPI_CMD(0x38)
#define DLN2_SPI_SS_MULTI_DISABLE		DLN2_SPI_CMD(0x39)
#define DLN2_SPI_SS_MULTI_IS_ENABLED		DLN2_SPI_CMD(0x3A)
#define DLN2_SPI_GET_SUPPORTED_MODES		DLN2_SPI_CMD(0x40)
#define DLN2_SPI_GET_SUPPORTED_CPHA_VALUES	DLN2_SPI_CMD(0x41)
#define DLN2_SPI_GET_SUPPORTED_CPOL_VALUES	DLN2_SPI_CMD(0x42)
#define DLN2_SPI_GET_SUPPORTED_FRAME_SIZES	DLN2_SPI_CMD(0x43)
#define DLN2_SPI_GET_SS_COUNT			DLN2_SPI_CMD(0x44)
#define DLN2_SPI_GET_MIN_FREQUENCY		DLN2_SPI_CMD(0x45)
#define DLN2_SPI_GET_MAX_FREQUENCY		DLN2_SPI_CMD(0x46)
#define DLN2_SPI_GET_MIN_DELAY_BETWEEN_SS	DLN2_SPI_CMD(0x47)
#define DLN2_SPI_GET_MAX_DELAY_BETWEEN_SS	DLN2_SPI_CMD(0x48)
#define DLN2_SPI_GET_MIN_DELAY_AFTER_SS		DLN2_SPI_CMD(0x49)
#define DLN2_SPI_GET_MAX_DELAY_AFTER_SS		DLN2_SPI_CMD(0x4A)
#define DLN2_SPI_GET_MIN_DELAY_BETWEEN_FRAMES	DLN2_SPI_CMD(0x4B)
#define DLN2_SPI_GET_MAX_DELAY_BETWEEN_FRAMES	DLN2_SPI_CMD(0x4C)

#define DLN2_SPI_MAX_XFER_SIZE			256
#define DLN2_SPI_BUF_SIZE			(DLN2_SPI_MAX_XFER_SIZE + 16)
#define DLN2_SPI_ATTR_LEAVE_SS_LOW		BIT(0)
#define DLN2_TRANSFERS_WAIT_COMPLETE		1
#define DLN2_TRANSFERS_CANCEL			0
#define DLN2_RPM_AUTOSUSPEND_TIMEOUT		2000

struct dln2_spi {
	struct platform_device *pdev;
	struct spi_controller *host;
	u8 port;

	/*
	 * This buffer will be used mainly for read/write operations. Since
	 * they're quite large, we cannot use the stack. Protection is not
	 * needed because all SPI communication is serialized by the SPI core.
	 */
	void *buf;

	u8 bpw;
	u32 speed;
	u16 mode;
	u8 cs;
};

/*
 * Enable/Disable SPI module. The disable command will wait for transfers to
 * complete first.
 */
static int dln2_spi_enable(struct dln2_spi *dln2, bool enable)
{
	u16 cmd;
	struct {
		u8 port;
		u8 wait_for_completion;
	} tx;
	unsigned len = sizeof(tx);

	tx.port = dln2->port;

	if (enable) {
		cmd = DLN2_SPI_ENABLE;
		len -= sizeof(tx.wait_for_completion);
	} else {
		tx.wait_for_completion = DLN2_TRANSFERS_WAIT_COMPLETE;
		cmd = DLN2_SPI_DISABLE;
	}

	return dln2_transfer_tx(dln2->pdev, cmd, &tx, len);
}

/*
 * Select/unselect multiple CS lines. The selected lines will be automatically
 * toggled LOW/HIGH by the board firmware during transfers, provided they're
 * enabled first.
 *
 * Ex: cs_mask = 0x03 -> CS0 & CS1 will be selected and the next WR/RD operation
 *                       will toggle the lines LOW/HIGH automatically.
 */
static int dln2_spi_cs_set(struct dln2_spi *dln2, u8 cs_mask)
{
	struct {
		u8 port;
		u8 cs;
	} tx;

	tx.port = dln2->port;

	/*
	 * According to Diolan docs, "a slave device can be selected by changing
	 * the corresponding bit value to 0". The rest must be set to 1. Hence
	 * the bitwise NOT in front.
	 */
	tx.cs = ~cs_mask;

	return dln2_transfer_tx(dln2->pdev, DLN2_SPI_SET_SS, &tx, sizeof(tx));
}

/*
 * Select one CS line. The other lines will be un-selected.
 */
static int dln2_spi_cs_set_one(struct dln2_spi *dln2, u8 cs)
{
	return dln2_spi_cs_set(dln2, BIT(cs));
}

/*
 * Enable/disable CS lines for usage. The module has to be disabled first.
 */
static int dln2_spi_cs_enable(struct dln2_spi *dln2, u8 cs_mask, bool enable)
{
	struct {
		u8 port;
		u8 cs;
	} tx;
	u16 cmd;

	tx.port = dln2->port;
	tx.cs = cs_mask;
	cmd = enable ? DLN2_SPI_SS_MULTI_ENABLE : DLN2_SPI_SS_MULTI_DISABLE;

	return dln2_transfer_tx(dln2->pdev, cmd, &tx, sizeof(tx));
}

static int dln2_spi_cs_enable_all(struct dln2_spi *dln2, bool enable)
{
	u8 cs_mask = GENMASK(dln2->host->num_chipselect - 1, 0);

	return dln2_spi_cs_enable(dln2, cs_mask, enable);
}

static int dln2_spi_get_cs_num(struct dln2_spi *dln2, u16 *cs_num)
{
	int ret;
	struct {
		u8 port;
	} tx;
	struct {
		__le16 cs_count;
	} rx;
	unsigned rx_len = sizeof(rx);

	tx.port = dln2->port;
	ret = dln2_transfer(dln2->pdev, DLN2_SPI_GET_SS_COUNT, &tx, sizeof(tx),
			    &rx, &rx_len);
	if (ret < 0)
		return ret;
	if (rx_len < sizeof(rx))
		return -EPROTO;

	*cs_num = le16_to_cpu(rx.cs_count);

	dev_dbg(&dln2->pdev->dev, "cs_num = %d\n", *cs_num);

	return 0;
}

static int dln2_spi_get_speed(struct dln2_spi *dln2, u16 cmd, u32 *freq)
{
	int ret;
	struct {
		u8 port;
	} tx;
	struct {
		__le32 speed;
	} rx;
	unsigned rx_len = sizeof(rx);

	tx.port = dln2->port;

	ret = dln2_transfer(dln2->pdev, cmd, &tx, sizeof(tx), &rx, &rx_len);
	if (ret < 0)
		return ret;
	if (rx_len < sizeof(rx))
		return -EPROTO;

	*freq = le32_to_cpu(rx.speed);

	return 0;
}

/*
 * Get bus min/max frequencies.
 */
static int dln2_spi_get_speed_range(struct dln2_spi *dln2, u32 *fmin, u32 *fmax)
{
	int ret;

	ret = dln2_spi_get_speed(dln2, DLN2_SPI_GET_MIN_FREQUENCY, fmin);
	if (ret < 0)
		return ret;

	ret = dln2_spi_get_speed(dln2, DLN2_SPI_GET_MAX_FREQUENCY, fmax);
	if (ret < 0)
		return ret;

	dev_dbg(&dln2->pdev->dev, "freq_min = %d, freq_max = %d\n",
		*fmin, *fmax);

	return 0;
}

/*
 * Set the bus speed. The module will automatically round down to the closest
 * available frequency and returns it. The module has to be disabled first.
 */
static int dln2_spi_set_speed(struct dln2_spi *dln2, u32 speed)
{
	int ret;
	struct {
		u8 port;
		__le32 speed;
	} __packed tx;
	struct {
		__le32 speed;
	} rx;
	int rx_len = sizeof(rx);

	tx.port = dln2->port;
	tx.speed = cpu_to_le32(speed);

	ret = dln2_transfer(dln2->pdev, DLN2_SPI_SET_FREQUENCY, &tx, sizeof(tx),
			    &rx, &rx_len);
	if (ret < 0)
		return ret;
	if (rx_len < sizeof(rx))
		return -EPROTO;

	return 0;
}

/*
 * Change CPOL & CPHA. The module has to be disabled first.
 */
static int dln2_spi_set_mode(struct dln2_spi *dln2, u8 mode)
{
	struct {
		u8 port;
		u8 mode;
	} tx;

	tx.port = dln2->port;
	tx.mode = mode;

	return dln2_transfer_tx(dln2->pdev, DLN2_SPI_SET_MODE, &tx, sizeof(tx));
}

/*
 * Change frame size. The module has to be disabled first.
 */
static int dln2_spi_set_bpw(struct dln2_spi *dln2, u8 bpw)
{
	struct {
		u8 port;
		u8 bpw;
	} tx;

	tx.port = dln2->port;
	tx.bpw = bpw;

	return dln2_transfer_tx(dln2->pdev, DLN2_SPI_SET_FRAME_SIZE,
				&tx, sizeof(tx));
}

static int dln2_spi_get_supported_frame_sizes(struct dln2_spi *dln2,
					      u32 *bpw_mask)
{
	int ret;
	struct {
		u8 port;
	} tx;
	struct {
		u8 count;
		u8 frame_sizes[36];
	} *rx = dln2->buf;
	unsigned rx_len = sizeof(*rx);
	int i;

	tx.port = dln2->port;

	ret = dln2_transfer(dln2->pdev, DLN2_SPI_GET_SUPPORTED_FRAME_SIZES,
			    &tx, sizeof(tx), rx, &rx_len);
	if (ret < 0)
		return ret;
	if (rx_len < sizeof(*rx))
		return -EPROTO;
	if (rx->count > ARRAY_SIZE(rx->frame_sizes))
		return -EPROTO;

	*bpw_mask = 0;
	for (i = 0; i < rx->count; i++)
		*bpw_mask |= BIT(rx->frame_sizes[i] - 1);

	dev_dbg(&dln2->pdev->dev, "bpw_mask = 0x%X\n", *bpw_mask);

	return 0;
}

/*
 * Copy the data to DLN2 buffer and change the byte order to LE, requested by
 * DLN2 module. SPI core makes sure that the data length is a multiple of word
 * size.
 */
static int dln2_spi_copy_to_buf(u8 *dln2_buf, const u8 *src, u16 len, u8 bpw)
{
#ifdef __LITTLE_ENDIAN
	memcpy(dln2_buf, src, len);
#else
	if (bpw <= 8) {
		memcpy(dln2_buf, src, len);
	} else if (bpw <= 16) {
		__le16 *d = (__le16 *)dln2_buf;
		u16 *s = (u16 *)src;

		len = len / 2;
		while (len--)
			*d++ = cpu_to_le16p(s++);
	} else {
		__le32 *d = (__le32 *)dln2_buf;
		u32 *s = (u32 *)src;

		len = len / 4;
		while (len--)
			*d++ = cpu_to_le32p(s++);
	}
#endif

	return 0;
}

/*
 * Copy the data from DLN2 buffer and convert to CPU byte order since the DLN2
 * buffer is LE ordered. SPI core makes sure that the data length is a multiple
 * of word size. The RX dln2_buf is 2 byte aligned so, for BE, we have to make
 * sure we avoid unaligned accesses for 32 bit case.
 */
static int dln2_spi_copy_from_buf(u8 *dest, const u8 *dln2_buf, u16 len, u8 bpw)
{
#ifdef __LITTLE_ENDIAN
	memcpy(dest, dln2_buf, len);
#else
	if (bpw <= 8) {
		memcpy(dest, dln2_buf, len);
	} else if (bpw <= 16) {
		u16 *d = (u16 *)dest;
		__le16 *s = (__le16 *)dln2_buf;

		len = len / 2;
		while (len--)
			*d++ = le16_to_cpup(s++);
	} else {
		u32 *d = (u32 *)dest;
		__le32 *s = (__le32 *)dln2_buf;

		len = len / 4;
		while (len--)
			*d++ = get_unaligned_le32(s++);
	}
#endif

	return 0;
}

/*
 * Perform one write operation.
 */
static int dln2_spi_write_one(struct dln2_spi *dln2, const u8 *data,
			      u16 data_len, u8 attr)
{
	struct {
		u8 port;
		__le16 size;
		u8 attr;
		u8 buf[DLN2_SPI_MAX_XFER_SIZE];
	} __packed *tx = dln2->buf;
	unsigned tx_len;

	BUILD_BUG_ON(sizeof(*tx) > DLN2_SPI_BUF_SIZE);

	if (data_len > DLN2_SPI_MAX_XFER_SIZE)
		return -EINVAL;

	tx->port = dln2->port;
	tx->size = cpu_to_le16(data_len);
	tx->attr = attr;

	dln2_spi_copy_to_buf(tx->buf, data, data_len, dln2->bpw);

	tx_len = sizeof(*tx) + data_len - DLN2_SPI_MAX_XFER_SIZE;
	return dln2_transfer_tx(dln2->pdev, DLN2_SPI_WRITE, tx, tx_len);
}

/*
 * Perform one read operation.
 */
static int dln2_spi_read_one(struct dln2_spi *dln2, u8 *data,
			     u16 data_len, u8 attr)
{
	int ret;
	struct {
		u8 port;
		__le16 size;
		u8 attr;
	} __packed tx;
	struct {
		__le16 size;
		u8 buf[DLN2_SPI_MAX_XFER_SIZE];
	} __packed *rx = dln2->buf;
	unsigned rx_len = sizeof(*rx);

	BUILD_BUG_ON(sizeof(*rx) > DLN2_SPI_BUF_SIZE);

	if (data_len > DLN2_SPI_MAX_XFER_SIZE)
		return -EINVAL;

	tx.port = dln2->port;
	tx.size = cpu_to_le16(data_len);
	tx.attr = attr;

	ret = dln2_transfer(dln2->pdev, DLN2_SPI_READ, &tx, sizeof(tx),
			    rx, &rx_len);
	if (ret < 0)
		return ret;
	if (rx_len < sizeof(rx->size) + data_len)
		return -EPROTO;
	if (le16_to_cpu(rx->size) != data_len)
		return -EPROTO;

	dln2_spi_copy_from_buf(data, rx->buf, data_len, dln2->bpw);

	return 0;
}

/*
 * Perform one write & read operation.
 */
static int dln2_spi_read_write_one(struct dln2_spi *dln2, const u8 *tx_data,
				   u8 *rx_data, u16 data_len, u8 attr)
{
	int ret;
	struct {
		u8 port;
		__le16 size;
		u8 attr;
		u8 buf[DLN2_SPI_MAX_XFER_SIZE];
	} __packed *tx;
	struct {
		__le16 size;
		u8 buf[DLN2_SPI_MAX_XFER_SIZE];
	} __packed *rx;
	unsigned tx_len, rx_len;

	BUILD_BUG_ON(sizeof(*tx) > DLN2_SPI_BUF_SIZE ||
		     sizeof(*rx) > DLN2_SPI_BUF_SIZE);

	if (data_len > DLN2_SPI_MAX_XFER_SIZE)
		return -EINVAL;

	/*
	 * Since this is a pseudo full-duplex communication, we're perfectly
	 * safe to use the same buffer for both tx and rx. When DLN2 sends the
	 * response back, with the rx data, we don't need the tx buffer anymore.
	 */
	tx = dln2->buf;
	rx = dln2->buf;

	tx->port = dln2->port;
	tx->size = cpu_to_le16(data_len);
	tx->attr = attr;

	dln2_spi_copy_to_buf(tx->buf, tx_data, data_len, dln2->bpw);

	tx_len = sizeof(*tx) + data_len - DLN2_SPI_MAX_XFER_SIZE;
	rx_len = sizeof(*rx);

	ret = dln2_transfer(dln2->pdev, DLN2_SPI_READ_WRITE, tx, tx_len,
			    rx, &rx_len);
	if (ret < 0)
		return ret;
	if (rx_len < sizeof(rx->size) + data_len)
		return -EPROTO;
	if (le16_to_cpu(rx->size) != data_len)
		return -EPROTO;

	dln2_spi_copy_from_buf(rx_data, rx->buf, data_len, dln2->bpw);

	return 0;
}

/*
 * Read/Write wrapper. It will automatically split an operation into multiple
 * single ones due to device buffer constraints.
 */
static int dln2_spi_rdwr(struct dln2_spi *dln2, const u8 *tx_data,
			 u8 *rx_data, u16 data_len, u8 attr)
{
	int ret;
	u16 len;
	u8 temp_attr;
	u16 remaining = data_len;
	u16 offset;

	do {
		if (remaining > DLN2_SPI_MAX_XFER_SIZE) {
			len = DLN2_SPI_MAX_XFER_SIZE;
			temp_attr = DLN2_SPI_ATTR_LEAVE_SS_LOW;
		} else {
			len = remaining;
			temp_attr = attr;
		}

		offset = data_len - remaining;

		if (tx_data && rx_data) {
			ret = dln2_spi_read_write_one(dln2,
						      tx_data + offset,
						      rx_data + offset,
						      len, temp_attr);
		} else if (tx_data) {
			ret = dln2_spi_write_one(dln2,
						 tx_data + offset,
						 len, temp_attr);
		} else if (rx_data) {
			ret = dln2_spi_read_one(dln2,
						rx_data + offset,
						len, temp_attr);
		 } else {
			return -EINVAL;
		 }

		if (ret < 0)
			return ret;

		remaining -= len;
	} while (remaining);

	return 0;
}

static int dln2_spi_prepare_message(struct spi_controller *host,
				    struct spi_message *message)
{
	int ret;
	struct dln2_spi *dln2 = spi_controller_get_devdata(host);
	struct spi_device *spi = message->spi;

	if (dln2->cs != spi_get_chipselect(spi, 0)) {
		ret = dln2_spi_cs_set_one(dln2, spi_get_chipselect(spi, 0));
		if (ret < 0)
			return ret;

		dln2->cs = spi_get_chipselect(spi, 0);
	}

	return 0;
}

static int dln2_spi_transfer_setup(struct dln2_spi *dln2, u32 speed,
				   u8 bpw, u8 mode)
{
	int ret;
	bool bus_setup_change;

	bus_setup_change = dln2->speed != speed || dln2->mode != mode ||
			   dln2->bpw != bpw;

	if (!bus_setup_change)
		return 0;

	ret = dln2_spi_enable(dln2, false);
	if (ret < 0)
		return ret;

	if (dln2->speed != speed) {
		ret = dln2_spi_set_speed(dln2, speed);
		if (ret < 0)
			return ret;

		dln2->speed = speed;
	}

	if (dln2->mode != mode) {
		ret = dln2_spi_set_mode(dln2, mode & 0x3);
		if (ret < 0)
			return ret;

		dln2->mode = mode;
	}

	if (dln2->bpw != bpw) {
		ret = dln2_spi_set_bpw(dln2, bpw);
		if (ret < 0)
			return ret;

		dln2->bpw = bpw;
	}

	return dln2_spi_enable(dln2, true);
}

static int dln2_spi_transfer_one(struct spi_controller *host,
				 struct spi_device *spi,
				 struct spi_transfer *xfer)
{
	struct dln2_spi *dln2 = spi_controller_get_devdata(host);
	int status;
	u8 attr = 0;

	status = dln2_spi_transfer_setup(dln2, xfer->speed_hz,
					 xfer->bits_per_word,
					 spi->mode);
	if (status < 0) {
		dev_err(&dln2->pdev->dev, "Cannot setup transfer\n");
		return status;
	}

	if (!xfer->cs_change && !spi_transfer_is_last(host, xfer))
		attr = DLN2_SPI_ATTR_LEAVE_SS_LOW;

	status = dln2_spi_rdwr(dln2, xfer->tx_buf, xfer->rx_buf,
			       xfer->len, attr);
	if (status < 0)
		dev_err(&dln2->pdev->dev, "write/read failed!\n");

	return status;
}

static int dln2_spi_probe(struct platform_device *pdev)
{
	struct spi_controller *host;
	struct dln2_spi *dln2;
	struct dln2_platform_data *pdata = dev_get_platdata(&pdev->dev);
	struct device *dev = &pdev->dev;
	int ret;

	host = spi_alloc_host(&pdev->dev, sizeof(*dln2));
	if (!host)
		return -ENOMEM;

	device_set_node(&host->dev, dev_fwnode(dev));

	platform_set_drvdata(pdev, host);

	dln2 = spi_controller_get_devdata(host);

	dln2->buf = devm_kmalloc(&pdev->dev, DLN2_SPI_BUF_SIZE, GFP_KERNEL);
	if (!dln2->buf) {
		ret = -ENOMEM;
		goto exit_free_host;
	}

	dln2->host = host;
	dln2->pdev = pdev;
	dln2->port = pdata->port;
	/* cs/mode can never be 0xff, so the first transfer will set them */
	dln2->cs = 0xff;
	dln2->mode = 0xff;

	/* disable SPI module before continuing with the setup */
	ret = dln2_spi_enable(dln2, false);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to disable SPI module\n");
		goto exit_free_host;
	}

	ret = dln2_spi_get_cs_num(dln2, &host->num_chipselect);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to get number of CS pins\n");
		goto exit_free_host;
	}

	ret = dln2_spi_get_speed_range(dln2,
				       &host->min_speed_hz,
				       &host->max_speed_hz);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to read bus min/max freqs\n");
		goto exit_free_host;
	}

	ret = dln2_spi_get_supported_frame_sizes(dln2,
						 &host->bits_per_word_mask);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to read supported frame sizes\n");
		goto exit_free_host;
	}

	ret = dln2_spi_cs_enable_all(dln2, true);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to enable CS pins\n");
		goto exit_free_host;
	}

	host->bus_num = -1;
	host->mode_bits = SPI_CPOL | SPI_CPHA;
	host->prepare_message = dln2_spi_prepare_message;
	host->transfer_one = dln2_spi_transfer_one;
	host->auto_runtime_pm = true;

	/* enable SPI module, we're good to go */
	ret = dln2_spi_enable(dln2, true);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to enable SPI module\n");
		goto exit_free_host;
	}

	pm_runtime_set_autosuspend_delay(&pdev->dev,
					 DLN2_RPM_AUTOSUSPEND_TIMEOUT);
	pm_runtime_use_autosuspend(&pdev->dev);
	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);

	ret = devm_spi_register_controller(&pdev->dev, host);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to register host\n");
		goto exit_register;
	}

	return ret;

exit_register:
	pm_runtime_disable(&pdev->dev);
	pm_runtime_set_suspended(&pdev->dev);

	if (dln2_spi_enable(dln2, false) < 0)
		dev_err(&pdev->dev, "Failed to disable SPI module\n");
exit_free_host:
	spi_controller_put(host);

	return ret;
}

static void dln2_spi_remove(struct platform_device *pdev)
{
	struct spi_controller *host = platform_get_drvdata(pdev);
	struct dln2_spi *dln2 = spi_controller_get_devdata(host);

	pm_runtime_disable(&pdev->dev);

	if (dln2_spi_enable(dln2, false) < 0)
		dev_err(&pdev->dev, "Failed to disable SPI module\n");
}

#ifdef CONFIG_PM_SLEEP
static int dln2_spi_suspend(struct device *dev)
{
	int ret;
	struct spi_controller *host = dev_get_drvdata(dev);
	struct dln2_spi *dln2 = spi_controller_get_devdata(host);

	ret = spi_controller_suspend(host);
	if (ret < 0)
		return ret;

	if (!pm_runtime_suspended(dev)) {
		ret = dln2_spi_enable(dln2, false);
		if (ret < 0)
			return ret;
	}

	/*
	 * USB power may be cut off during sleep. Resetting the following
	 * parameters will force the board to be set up before first transfer.
	 */
	dln2->cs = 0xff;
	dln2->speed = 0;
	dln2->bpw = 0;
	dln2->mode = 0xff;

	return 0;
}

static int dln2_spi_resume(struct device *dev)
{
	int ret;
	struct spi_controller *host = dev_get_drvdata(dev);
	struct dln2_spi *dln2 = spi_controller_get_devdata(host);

	if (!pm_runtime_suspended(dev)) {
		ret = dln2_spi_cs_enable_all(dln2, true);
		if (ret < 0)
			return ret;

		ret = dln2_spi_enable(dln2, true);
		if (ret < 0)
			return ret;
	}

	return spi_controller_resume(host);
}
#endif /* CONFIG_PM_SLEEP */

#ifdef CONFIG_PM
static int dln2_spi_runtime_suspend(struct device *dev)
{
	struct spi_controller *host = dev_get_drvdata(dev);
	struct dln2_spi *dln2 = spi_controller_get_devdata(host);

	return dln2_spi_enable(dln2, false);
}

static int dln2_spi_runtime_resume(struct device *dev)
{
	struct spi_controller *host = dev_get_drvdata(dev);
	struct dln2_spi *dln2 = spi_controller_get_devdata(host);

	return  dln2_spi_enable(dln2, true);
}
#endif /* CONFIG_PM */

static const struct dev_pm_ops dln2_spi_pm = {
	SET_SYSTEM_SLEEP_PM_OPS(dln2_spi_suspend, dln2_spi_resume)
	SET_RUNTIME_PM_OPS(dln2_spi_runtime_suspend,
			   dln2_spi_runtime_resume, NULL)
};

static struct platform_driver spi_dln2_driver = {
	.driver = {
		.name	= "dln2-spi",
		.pm	= &dln2_spi_pm,
	},
	.probe		= dln2_spi_probe,
	.remove_new	= dln2_spi_remove,
};
module_platform_driver(spi_dln2_driver);

MODULE_DESCRIPTION("Driver for the Diolan DLN2 SPI host interface");
MODULE_AUTHOR("Laurentiu Palcu <laurentiu.palcu@intel.com>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:dln2-spi");
