// SPDX-License-Identifier: GPL-2.0
//
// General Purpose SPI multiplexer

#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mux/consumer.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>

#define SPI_MUX_NO_CS	((unsigned int)-1)

/**
 * DOC: Driver description
 *
 * This driver supports a MUX on an SPI bus. This can be useful when you need
 * more chip selects than the hardware peripherals support, or than are
 * available in a particular board setup.
 *
 * The driver will create an additional SPI controller. Devices added under the
 * mux will be handled as 'chip selects' on this controller.
 */

/**
 * struct spi_mux_priv - the basic spi_mux structure
 * @spi:		pointer to the device struct attached to the parent
 *			spi controller
 * @current_cs:		The current chip select set in the mux
 * @child_msg_complete: The mux replaces the complete callback in the child's
 *			message to its own callback; this field is used by the
 *			driver to store the child's callback during a transfer
 * @child_msg_context:	Used to store the child's context to the callback
 * @child_msg_dev:	Used to store the spi_device pointer to the child
 * @mux:		mux_control structure used to provide chip selects for
 *			downstream spi devices
 */
struct spi_mux_priv {
	struct spi_device	*spi;
	unsigned int		current_cs;

	void			(*child_msg_complete)(void *context);
	void			*child_msg_context;
	struct spi_device	*child_msg_dev;
	struct mux_control	*mux;
};

/* should not get called when the parent controller is doing a transfer */
static int spi_mux_select(struct spi_device *spi)
{
	struct spi_mux_priv *priv = spi_controller_get_devdata(spi->controller);
	int ret;

	ret = mux_control_select(priv->mux, spi_get_chipselect(spi, 0));
	if (ret)
		return ret;

	if (priv->current_cs == spi_get_chipselect(spi, 0))
		return 0;

	dev_dbg(&priv->spi->dev, "setting up the mux for cs %d\n",
		spi_get_chipselect(spi, 0));

	/* copy the child device's settings except for the cs */
	priv->spi->max_speed_hz = spi->max_speed_hz;
	priv->spi->mode = spi->mode;
	priv->spi->bits_per_word = spi->bits_per_word;

	priv->current_cs = spi_get_chipselect(spi, 0);

	spi_setup(priv->spi);

	return 0;
}

static int spi_mux_setup(struct spi_device *spi)
{
	struct spi_mux_priv *priv = spi_controller_get_devdata(spi->controller);

	/*
	 * can be called multiple times, won't do a valid setup now but we will
	 * change the settings when we do a transfer (necessary because we
	 * can't predict from which device it will be anyway)
	 */
	return spi_setup(priv->spi);
}

static void spi_mux_complete_cb(void *context)
{
	struct spi_mux_priv *priv = (struct spi_mux_priv *)context;
	struct spi_controller *ctlr = spi_get_drvdata(priv->spi);
	struct spi_message *m = ctlr->cur_msg;

	m->complete = priv->child_msg_complete;
	m->context = priv->child_msg_context;
	m->spi = priv->child_msg_dev;
	spi_finalize_current_message(ctlr);
	mux_control_deselect(priv->mux);
}

static int spi_mux_transfer_one_message(struct spi_controller *ctlr,
						struct spi_message *m)
{
	struct spi_mux_priv *priv = spi_controller_get_devdata(ctlr);
	struct spi_device *spi = m->spi;
	int ret;

	ret = spi_mux_select(spi);
	if (ret)
		return ret;

	/*
	 * Replace the complete callback, context and spi_device with our own
	 * pointers. Save originals
	 */
	priv->child_msg_complete = m->complete;
	priv->child_msg_context = m->context;
	priv->child_msg_dev = m->spi;

	m->complete = spi_mux_complete_cb;
	m->context = priv;
	m->spi = priv->spi;

	/* do the transfer */
	return spi_async(priv->spi, m);
}

static int spi_mux_probe(struct spi_device *spi)
{
	struct spi_controller *ctlr;
	struct spi_mux_priv *priv;
	int ret;

	ctlr = spi_alloc_host(&spi->dev, sizeof(*priv));
	if (!ctlr)
		return -ENOMEM;

	spi_set_drvdata(spi, ctlr);
	priv = spi_controller_get_devdata(ctlr);
	priv->spi = spi;

	/*
	 * Increase lockdep class as these lock are taken while the parent bus
	 * already holds their instance's lock.
	 */
	lockdep_set_subclass(&ctlr->io_mutex, 1);
	lockdep_set_subclass(&ctlr->add_lock, 1);

	priv->mux = devm_mux_control_get(&spi->dev, NULL);
	if (IS_ERR(priv->mux)) {
		ret = dev_err_probe(&spi->dev, PTR_ERR(priv->mux),
				    "failed to get control-mux\n");
		goto err_put_ctlr;
	}

	priv->current_cs = SPI_MUX_NO_CS;

	/* supported modes are the same as our parent's */
	ctlr->mode_bits = spi->controller->mode_bits;
	ctlr->flags = spi->controller->flags;
	ctlr->bits_per_word_mask = spi->controller->bits_per_word_mask;
	ctlr->transfer_one_message = spi_mux_transfer_one_message;
	ctlr->setup = spi_mux_setup;
	ctlr->num_chipselect = mux_control_states(priv->mux);
	ctlr->bus_num = -1;
	ctlr->dev.of_node = spi->dev.of_node;
	ctlr->must_async = true;
	ctlr->defer_optimize_message = true;

	ret = devm_spi_register_controller(&spi->dev, ctlr);
	if (ret)
		goto err_put_ctlr;

	return 0;

err_put_ctlr:
	spi_controller_put(ctlr);

	return ret;
}

static const struct spi_device_id spi_mux_id[] = {
	{ "spi-mux" },
	{ }
};
MODULE_DEVICE_TABLE(spi, spi_mux_id);

static const struct of_device_id spi_mux_of_match[] = {
	{ .compatible = "spi-mux" },
	{ }
};
MODULE_DEVICE_TABLE(of, spi_mux_of_match);

static struct spi_driver spi_mux_driver = {
	.probe  = spi_mux_probe,
	.driver = {
		.name   = "spi-mux",
		.of_match_table = spi_mux_of_match,
	},
	.id_table = spi_mux_id,
};

module_spi_driver(spi_mux_driver);

MODULE_DESCRIPTION("SPI multiplexer");
MODULE_LICENSE("GPL");
