// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2020 Bootlin SA
 * Author: Alexandre Belloni <alexandre.belloni@bootlin.com>
 */

#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/regulator/consumer.h>
#include <sound/soc.h>

#define MUX_TEXT_SIZE	2
#define MUX_WIDGET_SIZE	4
#define MUX_ROUTE_SIZE	3
struct simple_mux {
	struct gpio_desc *gpiod_mux;
	unsigned int mux;
	const char *mux_texts[MUX_TEXT_SIZE];
	struct soc_enum mux_enum;
	struct snd_kcontrol_new mux_mux;
	struct snd_soc_dapm_widget mux_widgets[MUX_WIDGET_SIZE];
	struct snd_soc_dapm_route mux_routes[MUX_ROUTE_SIZE];
	struct snd_soc_component_driver mux_driver;
};

static const char * const simple_mux_texts[MUX_TEXT_SIZE] = {
	"Input 1", "Input 2"
};

static SOC_ENUM_SINGLE_EXT_DECL(simple_mux_enum, simple_mux_texts);

static int simple_mux_control_get(struct snd_kcontrol *kcontrol,
				  struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
	struct snd_soc_component *c = snd_soc_dapm_to_component(dapm);
	struct simple_mux *priv = snd_soc_component_get_drvdata(c);

	ucontrol->value.enumerated.item[0] = priv->mux;

	return 0;
}

static int simple_mux_control_put(struct snd_kcontrol *kcontrol,
				  struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	struct snd_soc_component *c = snd_soc_dapm_to_component(dapm);
	struct simple_mux *priv = snd_soc_component_get_drvdata(c);

	if (ucontrol->value.enumerated.item[0] > e->items)
		return -EINVAL;

	if (priv->mux == ucontrol->value.enumerated.item[0])
		return 0;

	priv->mux = ucontrol->value.enumerated.item[0];

	gpiod_set_value_cansleep(priv->gpiod_mux, priv->mux);

	return snd_soc_dapm_mux_update_power(dapm, kcontrol,
					     ucontrol->value.enumerated.item[0],
					     e, NULL);
}

static unsigned int simple_mux_read(struct snd_soc_component *component,
				    unsigned int reg)
{
	struct simple_mux *priv = snd_soc_component_get_drvdata(component);

	return priv->mux;
}

static const struct snd_kcontrol_new simple_mux_mux =
	SOC_DAPM_ENUM_EXT("Muxer", simple_mux_enum, simple_mux_control_get, simple_mux_control_put);

static const struct snd_soc_dapm_widget simple_mux_dapm_widgets[MUX_WIDGET_SIZE] = {
	SND_SOC_DAPM_INPUT("IN1"),
	SND_SOC_DAPM_INPUT("IN2"),
	SND_SOC_DAPM_MUX("MUX", SND_SOC_NOPM, 0, 0, &simple_mux_mux), // see simple_mux_probe()
	SND_SOC_DAPM_OUTPUT("OUT"),
};

static const struct snd_soc_dapm_route simple_mux_dapm_routes[MUX_ROUTE_SIZE] = {
	{ "OUT", NULL, "MUX" },
	{ "MUX", "Input 1", "IN1" }, // see simple_mux_probe()
	{ "MUX", "Input 2", "IN2" }, // see simple_mux_probe()
};

static int simple_mux_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct simple_mux *priv;

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	dev_set_drvdata(dev, priv);

	priv->gpiod_mux = devm_gpiod_get(dev, "mux", GPIOD_OUT_LOW);
	if (IS_ERR(priv->gpiod_mux))
		return dev_err_probe(dev, PTR_ERR(priv->gpiod_mux),
				     "Failed to get 'mux' gpio");

	/* Copy default settings */
	memcpy(&priv->mux_texts,	&simple_mux_texts,		sizeof(priv->mux_texts));
	memcpy(&priv->mux_enum,		&simple_mux_enum,		sizeof(priv->mux_enum));
	memcpy(&priv->mux_mux,		&simple_mux_mux,		sizeof(priv->mux_mux));
	memcpy(&priv->mux_widgets,	&simple_mux_dapm_widgets,	sizeof(priv->mux_widgets));
	memcpy(&priv->mux_routes,	&simple_mux_dapm_routes,	sizeof(priv->mux_routes));

	priv->mux_driver.dapm_widgets		= priv->mux_widgets;
	priv->mux_driver.num_dapm_widgets	= MUX_WIDGET_SIZE;
	priv->mux_driver.dapm_routes		= priv->mux_routes;
	priv->mux_driver.num_dapm_routes	= MUX_ROUTE_SIZE;
	priv->mux_driver.read			= simple_mux_read;

	/* Overwrite text ("Input 1", "Input 2") if property exists */
	of_property_read_string_array(np, "state-labels", priv->mux_texts, MUX_TEXT_SIZE);

	/* switch to use priv data instead of default */
	priv->mux_enum.texts			= priv->mux_texts;
	priv->mux_mux.private_value		= (unsigned long)&priv->mux_enum;
	priv->mux_widgets[2].kcontrol_news	= &priv->mux_mux;
	priv->mux_routes[1].control		= priv->mux_texts[0]; // "Input 1"
	priv->mux_routes[2].control		= priv->mux_texts[1]; // "Input 2"

	return devm_snd_soc_register_component(dev, &priv->mux_driver, NULL, 0);
}

#ifdef CONFIG_OF
static const struct of_device_id simple_mux_ids[] = {
	{ .compatible = "simple-audio-mux", },
	{ }
};
MODULE_DEVICE_TABLE(of, simple_mux_ids);
#endif

static struct platform_driver simple_mux_driver = {
	.driver = {
		.name = "simple-mux",
		.of_match_table = of_match_ptr(simple_mux_ids),
	},
	.probe = simple_mux_probe,
};

module_platform_driver(simple_mux_driver);

MODULE_DESCRIPTION("ASoC Simple Audio Mux driver");
MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>");
MODULE_LICENSE("GPL");
