// 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/mux/driver.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];
	unsigned int idle_state;
	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_to_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_to_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];

	if (priv->idle_state != MUX_IDLE_AS_IS &&
	    snd_soc_dapm_get_bias_level(dapm) < SND_SOC_BIAS_PREPARE)
		return 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 int simple_mux_event(struct snd_soc_dapm_widget *w,
			    struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
	struct simple_mux *priv = snd_soc_component_get_drvdata(c);

	if (priv->idle_state != MUX_IDLE_AS_IS) {
		switch (event) {
		case SND_SOC_DAPM_PRE_PMU:
			gpiod_set_value_cansleep(priv->gpiod_mux, priv->mux);
			break;
		case SND_SOC_DAPM_POST_PMD:
			gpiod_set_value_cansleep(priv->gpiod_mux, priv->idle_state);
			break;
		default:
			break;
		}
	}

	return 0;
}

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_E("MUX", SND_SOC_NOPM, 0, 0, &simple_mux_mux, // see simple_mux_probe()
			   simple_mux_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
	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;
	int ret;

	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);

	ret = of_property_read_u32(np, "idle-state", &priv->idle_state);
	if (ret < 0) {
		priv->idle_state = MUX_IDLE_AS_IS;
	} else if (priv->idle_state != MUX_IDLE_AS_IS && priv->idle_state >= 2) {
		dev_err(dev, "invalid idle-state %u\n", priv->idle_state);
		return -EINVAL;
	}

	/* 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");
