// SPDX-License-Identifier: GPL-2.0+
#include <linux/extcon.h>
#include <linux/iio/consumer.h>
#include <linux/iio/iio.h>
#include <linux/input-event-codes.h>
#include <linux/mfd/wm8994/registers.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/regulator/consumer.h>
#include <sound/jack.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>

#include "i2s.h"
#include "../codecs/wm8994.h"

#define ARIES_MCLK1_FREQ 24000000

struct aries_wm8994_variant {
	unsigned int modem_dai_fmt;
	bool has_fm_radio;
};

struct aries_wm8994_data {
	struct extcon_dev *usb_extcon;
	struct regulator *reg_main_micbias;
	struct regulator *reg_headset_micbias;
	struct gpio_desc *gpio_headset_detect;
	struct gpio_desc *gpio_headset_key;
	struct gpio_desc *gpio_earpath_sel;
	struct iio_channel *adc;
	const struct aries_wm8994_variant *variant;
};

/* USB dock */
static struct snd_soc_jack aries_dock;

static struct snd_soc_jack_pin dock_pins[] = {
	{
		.pin = "LINE",
		.mask = SND_JACK_LINEOUT,
	},
};

static int aries_extcon_notifier(struct notifier_block *this,
				 unsigned long connected, void *_cmd)
{
	if (connected)
		snd_soc_jack_report(&aries_dock, SND_JACK_LINEOUT,
				SND_JACK_LINEOUT);
	else
		snd_soc_jack_report(&aries_dock, 0, SND_JACK_LINEOUT);

	return NOTIFY_DONE;
}

static struct notifier_block aries_extcon_notifier_block = {
	.notifier_call = aries_extcon_notifier,
};

/* Headset jack */
static struct snd_soc_jack aries_headset;

static struct snd_soc_jack_pin jack_pins[] = {
	{
		.pin = "HP",
		.mask = SND_JACK_HEADPHONE,
	}, {
		.pin = "Headset Mic",
		.mask = SND_JACK_MICROPHONE,
	},
};

static struct snd_soc_jack_zone headset_zones[] = {
	{
		.min_mv = 0,
		.max_mv = 241,
		.jack_type = SND_JACK_HEADPHONE,
	}, {
		.min_mv = 242,
		.max_mv = 2980,
		.jack_type = SND_JACK_HEADSET,
	}, {
		.min_mv = 2981,
		.max_mv = UINT_MAX,
		.jack_type = SND_JACK_HEADPHONE,
	},
};

static irqreturn_t headset_det_irq_thread(int irq, void *data)
{
	struct aries_wm8994_data *priv = (struct aries_wm8994_data *) data;
	int ret = 0;
	int time_left_ms = 300;
	int adc;

	while (time_left_ms > 0) {
		if (!gpiod_get_value(priv->gpio_headset_detect)) {
			snd_soc_jack_report(&aries_headset, 0,
					SND_JACK_HEADSET);
			gpiod_set_value(priv->gpio_earpath_sel, 0);
			return IRQ_HANDLED;
		}
		msleep(20);
		time_left_ms -= 20;
	}

	/* Temporarily enable micbias and earpath selector */
	ret = regulator_enable(priv->reg_headset_micbias);
	if (ret)
		pr_err("%s failed to enable micbias: %d", __func__, ret);

	gpiod_set_value(priv->gpio_earpath_sel, 1);

	ret = iio_read_channel_processed(priv->adc, &adc);
	if (ret < 0) {
		/* failed to read ADC, so assume headphone */
		pr_err("%s failed to read ADC, assuming headphones", __func__);
		snd_soc_jack_report(&aries_headset, SND_JACK_HEADPHONE,
				SND_JACK_HEADSET);
	} else {
		snd_soc_jack_report(&aries_headset,
				snd_soc_jack_get_type(&aries_headset, adc),
				SND_JACK_HEADSET);
	}

	ret = regulator_disable(priv->reg_headset_micbias);
	if (ret)
		pr_err("%s failed disable micbias: %d", __func__, ret);

	/* Disable earpath selector when no mic connected */
	if (!(aries_headset.status & SND_JACK_MICROPHONE))
		gpiod_set_value(priv->gpio_earpath_sel, 0);

	return IRQ_HANDLED;
}

static int headset_button_check(void *data)
{
	struct aries_wm8994_data *priv = (struct aries_wm8994_data *) data;

	/* Filter out keypresses when 4 pole jack not detected */
	if (gpiod_get_value_cansleep(priv->gpio_headset_key) &&
			aries_headset.status & SND_JACK_MICROPHONE)
		return SND_JACK_BTN_0;

	return 0;
}

static struct snd_soc_jack_gpio headset_button_gpio[] = {
	{
		.name = "Media Button",
		.report = SND_JACK_BTN_0,
		.debounce_time  = 30,
		.jack_status_check = headset_button_check,
	},
};

static int aries_spk_cfg(struct snd_soc_dapm_widget *w,
			struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_card *card = w->dapm->card;
	struct snd_soc_pcm_runtime *rtd;
	struct snd_soc_component *component;
	int ret = 0;

	rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]);
	component = asoc_rtd_to_codec(rtd, 0)->component;

	/**
	 * We have an odd setup - the SPKMODE pin is pulled up so
	 * we only have access to the left side SPK configs,
	 * but SPKOUTR isn't bridged so when playing back in
	 * stereo, we only get the left hand channel.  The only
	 * option we're left with is to force the AIF into mono
	 * mode.
	 */
	switch (event) {
	case SND_SOC_DAPM_POST_PMU:
		ret = snd_soc_component_update_bits(component,
				WM8994_AIF1_DAC1_FILTERS_1,
				WM8994_AIF1DAC1_MONO, WM8994_AIF1DAC1_MONO);
		break;
	case SND_SOC_DAPM_PRE_PMD:
		ret = snd_soc_component_update_bits(component,
				WM8994_AIF1_DAC1_FILTERS_1,
				WM8994_AIF1DAC1_MONO, 0);
		break;
	}

	return ret;
}

static int aries_main_bias(struct snd_soc_dapm_widget *w,
			  struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_card *card = w->dapm->card;
	struct aries_wm8994_data *priv = snd_soc_card_get_drvdata(card);
	int ret = 0;

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		ret = regulator_enable(priv->reg_main_micbias);
		break;
	case SND_SOC_DAPM_POST_PMD:
		ret = regulator_disable(priv->reg_main_micbias);
		break;
	}

	return ret;
}

static int aries_headset_bias(struct snd_soc_dapm_widget *w,
			  struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_card *card = w->dapm->card;
	struct aries_wm8994_data *priv = snd_soc_card_get_drvdata(card);
	int ret = 0;

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		ret = regulator_enable(priv->reg_headset_micbias);
		break;
	case SND_SOC_DAPM_POST_PMD:
		ret = regulator_disable(priv->reg_headset_micbias);
		break;
	}

	return ret;
}

static const struct snd_kcontrol_new aries_controls[] = {
	SOC_DAPM_PIN_SWITCH("Modem In"),
	SOC_DAPM_PIN_SWITCH("Modem Out"),
};

static const struct snd_soc_dapm_widget aries_dapm_widgets[] = {
	SND_SOC_DAPM_HP("HP", NULL),

	SND_SOC_DAPM_SPK("SPK", aries_spk_cfg),
	SND_SOC_DAPM_SPK("RCV", NULL),

	SND_SOC_DAPM_LINE("LINE", NULL),

	SND_SOC_DAPM_MIC("Main Mic", aries_main_bias),
	SND_SOC_DAPM_MIC("Headset Mic", aries_headset_bias),

	SND_SOC_DAPM_MIC("Bluetooth Mic", NULL),
	SND_SOC_DAPM_SPK("Bluetooth SPK", NULL),

	SND_SOC_DAPM_LINE("Modem In", NULL),
	SND_SOC_DAPM_LINE("Modem Out", NULL),

	/* This must be last as it is conditionally not used */
	SND_SOC_DAPM_LINE("FM In", NULL),
};

static int aries_hw_params(struct snd_pcm_substream *substream,
	struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
	unsigned int pll_out;
	int ret;

	/* AIF1CLK should be >=3MHz for optimal performance */
	if (params_width(params) == 24)
		pll_out = params_rate(params) * 384;
	else if (params_rate(params) == 8000 || params_rate(params) == 11025)
		pll_out = params_rate(params) * 512;
	else
		pll_out = params_rate(params) * 256;

	ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1,
				ARIES_MCLK1_FREQ, pll_out);
	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1,
				pll_out, SND_SOC_CLOCK_IN);
	if (ret < 0)
		return ret;

	return 0;
}

static int aries_hw_free(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
	int ret;

	/* Switch sysclk to MCLK1 */
	ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1,
				ARIES_MCLK1_FREQ, SND_SOC_CLOCK_IN);
	if (ret < 0)
		return ret;

	/* Stop PLL */
	ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1,
				ARIES_MCLK1_FREQ, 0);
	if (ret < 0)
		return ret;

	return 0;
}

/*
 * Main DAI operations
 */
static const struct snd_soc_ops aries_ops = {
	.hw_params = aries_hw_params,
	.hw_free = aries_hw_free,
};

static int aries_baseband_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
	unsigned int pll_out;
	int ret;

	pll_out = 8000 * 512;

	/* Set the codec FLL */
	ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, WM8994_FLL_SRC_MCLK1,
			ARIES_MCLK1_FREQ, pll_out);
	if (ret < 0)
		return ret;

	/* Set the codec system clock */
	ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2,
			pll_out, SND_SOC_CLOCK_IN);
	if (ret < 0)
		return ret;

	return 0;
}

static int aries_late_probe(struct snd_soc_card *card)
{
	struct aries_wm8994_data *priv = snd_soc_card_get_drvdata(card);
	int ret, irq;

	ret = snd_soc_card_jack_new_pins(card, "Dock", SND_JACK_LINEOUT,
			&aries_dock, dock_pins, ARRAY_SIZE(dock_pins));
	if (ret)
		return ret;

	ret = devm_extcon_register_notifier(card->dev,
			priv->usb_extcon, EXTCON_JACK_LINE_OUT,
			&aries_extcon_notifier_block);
	if (ret)
		return ret;

	if (extcon_get_state(priv->usb_extcon,
			EXTCON_JACK_LINE_OUT) > 0)
		snd_soc_jack_report(&aries_dock, SND_JACK_LINEOUT,
				SND_JACK_LINEOUT);
	else
		snd_soc_jack_report(&aries_dock, 0, SND_JACK_LINEOUT);

	ret = snd_soc_card_jack_new_pins(card, "Headset",
			SND_JACK_HEADSET | SND_JACK_BTN_0,
			&aries_headset,
			jack_pins, ARRAY_SIZE(jack_pins));
	if (ret)
		return ret;

	ret = snd_soc_jack_add_zones(&aries_headset, ARRAY_SIZE(headset_zones),
			headset_zones);
	if (ret)
		return ret;

	irq = gpiod_to_irq(priv->gpio_headset_detect);
	if (irq < 0) {
		dev_err(card->dev, "Failed to map headset detect gpio to irq");
		return -EINVAL;
	}

	ret = devm_request_threaded_irq(card->dev, irq, NULL,
			headset_det_irq_thread,
			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
			IRQF_ONESHOT, "headset_detect", priv);
	if (ret) {
		dev_err(card->dev, "Failed to request headset detect irq");
		return ret;
	}

	headset_button_gpio[0].data = priv;
	headset_button_gpio[0].desc = priv->gpio_headset_key;

	snd_jack_set_key(aries_headset.jack, SND_JACK_BTN_0, KEY_MEDIA);

	return snd_soc_jack_add_gpios(&aries_headset,
			ARRAY_SIZE(headset_button_gpio), headset_button_gpio);
}

static const struct snd_soc_pcm_stream baseband_params = {
	.formats = SNDRV_PCM_FMTBIT_S16_LE,
	.rate_min = 8000,
	.rate_max = 8000,
	.channels_min = 1,
	.channels_max = 1,
};

static const struct snd_soc_pcm_stream bluetooth_params = {
	.formats = SNDRV_PCM_FMTBIT_S16_LE,
	.rate_min = 8000,
	.rate_max = 8000,
	.channels_min = 1,
	.channels_max = 2,
};

static const struct snd_soc_dapm_widget aries_modem_widgets[] = {
	SND_SOC_DAPM_INPUT("Modem RX"),
	SND_SOC_DAPM_OUTPUT("Modem TX"),
};

static const struct snd_soc_dapm_route aries_modem_routes[] = {
	{ "Modem Capture", NULL, "Modem RX" },
	{ "Modem TX", NULL, "Modem Playback" },
};

static const struct snd_soc_component_driver aries_component = {
	.name			= "aries-audio",
	.dapm_widgets		= aries_modem_widgets,
	.num_dapm_widgets	= ARRAY_SIZE(aries_modem_widgets),
	.dapm_routes		= aries_modem_routes,
	.num_dapm_routes	= ARRAY_SIZE(aries_modem_routes),
	.idle_bias_on		= 1,
	.use_pmdown_time	= 1,
	.endianness		= 1,
	.non_legacy_dai_naming	= 1,
};

static struct snd_soc_dai_driver aries_ext_dai[] = {
	{
		.name = "Voice call",
		.playback = {
			.stream_name = "Modem Playback",
			.channels_min = 1,
			.channels_max = 1,
			.rate_min = 8000,
			.rate_max = 8000,
			.rates = SNDRV_PCM_RATE_8000,
			.formats = SNDRV_PCM_FMTBIT_S16_LE,
		},
		.capture = {
			.stream_name = "Modem Capture",
			.channels_min = 1,
			.channels_max = 1,
			.rate_min = 8000,
			.rate_max = 8000,
			.rates = SNDRV_PCM_RATE_8000,
			.formats = SNDRV_PCM_FMTBIT_S16_LE,
		},
	},
};

SND_SOC_DAILINK_DEFS(aif1,
	DAILINK_COMP_ARRAY(COMP_CPU(SAMSUNG_I2S_DAI)),
	DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "wm8994-aif1")),
	DAILINK_COMP_ARRAY(COMP_EMPTY()));

SND_SOC_DAILINK_DEFS(baseband,
	DAILINK_COMP_ARRAY(COMP_CPU("Voice call")),
	DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "wm8994-aif2")));

SND_SOC_DAILINK_DEFS(bluetooth,
	DAILINK_COMP_ARRAY(COMP_CPU("bt-sco-pcm")),
	DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "wm8994-aif3")));

static struct snd_soc_dai_link aries_dai[] = {
	{
		.name = "WM8994 AIF1",
		.stream_name = "HiFi",
		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
			SND_SOC_DAIFMT_CBM_CFM,
		.ops = &aries_ops,
		SND_SOC_DAILINK_REG(aif1),
	},
	{
		.name = "WM8994 AIF2",
		.stream_name = "Baseband",
		.init = &aries_baseband_init,
		.params = &baseband_params,
		.ignore_suspend = 1,
		SND_SOC_DAILINK_REG(baseband),
	},
	{
		.name = "WM8994 AIF3",
		.stream_name = "Bluetooth",
		.params = &bluetooth_params,
		.ignore_suspend = 1,
		SND_SOC_DAILINK_REG(bluetooth),
	},
};

static struct snd_soc_card aries_card = {
	.name = "ARIES",
	.owner = THIS_MODULE,
	.dai_link = aries_dai,
	.num_links = ARRAY_SIZE(aries_dai),
	.controls = aries_controls,
	.num_controls = ARRAY_SIZE(aries_controls),
	.dapm_widgets = aries_dapm_widgets,
	.num_dapm_widgets = ARRAY_SIZE(aries_dapm_widgets),
	.late_probe = aries_late_probe,
};

static const struct aries_wm8994_variant fascinate4g_variant = {
	.modem_dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS
		| SND_SOC_DAIFMT_IB_NF,
	.has_fm_radio = false,
};

static const struct aries_wm8994_variant aries_variant = {
	.modem_dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM
		| SND_SOC_DAIFMT_IB_NF,
	.has_fm_radio = true,
};

static const struct of_device_id samsung_wm8994_of_match[] = {
	{
		.compatible = "samsung,fascinate4g-wm8994",
		.data = &fascinate4g_variant,
	},
	{
		.compatible = "samsung,aries-wm8994",
		.data = &aries_variant,
	},
	{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, samsung_wm8994_of_match);

static int aries_audio_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct device_node *cpu, *codec, *extcon_np;
	struct device *dev = &pdev->dev;
	struct snd_soc_card *card = &aries_card;
	struct aries_wm8994_data *priv;
	struct snd_soc_dai_link *dai_link;
	const struct of_device_id *match;
	int ret, i;

	if (!np)
		return -EINVAL;

	card->dev = dev;

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

	snd_soc_card_set_drvdata(card, priv);

	match = of_match_node(samsung_wm8994_of_match, np);
	priv->variant = match->data;

	/* Remove FM widget if not present */
	if (!priv->variant->has_fm_radio)
		card->num_dapm_widgets--;

	priv->reg_main_micbias = devm_regulator_get(dev, "main-micbias");
	if (IS_ERR(priv->reg_main_micbias)) {
		dev_err(dev, "Failed to get main micbias regulator\n");
		return PTR_ERR(priv->reg_main_micbias);
	}

	priv->reg_headset_micbias = devm_regulator_get(dev, "headset-micbias");
	if (IS_ERR(priv->reg_headset_micbias)) {
		dev_err(dev, "Failed to get headset micbias regulator\n");
		return PTR_ERR(priv->reg_headset_micbias);
	}

	priv->gpio_earpath_sel = devm_gpiod_get(dev, "earpath-sel",
			GPIOD_OUT_LOW);
	if (IS_ERR(priv->gpio_earpath_sel)) {
		dev_err(dev, "Failed to get earpath selector gpio");
		return PTR_ERR(priv->gpio_earpath_sel);
	}

	extcon_np = of_parse_phandle(np, "extcon", 0);
	priv->usb_extcon = extcon_find_edev_by_node(extcon_np);
	of_node_put(extcon_np);
	if (IS_ERR(priv->usb_extcon))
		return dev_err_probe(dev, PTR_ERR(priv->usb_extcon),
				     "Failed to get extcon device");

	priv->adc = devm_iio_channel_get(dev, "headset-detect");
	if (IS_ERR(priv->adc))
		return dev_err_probe(dev, PTR_ERR(priv->adc),
				     "Failed to get ADC channel");

	if (priv->adc->channel->type != IIO_VOLTAGE)
		return -EINVAL;

	priv->gpio_headset_key = devm_gpiod_get(dev, "headset-key",
			GPIOD_IN);
	if (IS_ERR(priv->gpio_headset_key)) {
		dev_err(dev, "Failed to get headset key gpio");
		return PTR_ERR(priv->gpio_headset_key);
	}

	priv->gpio_headset_detect = devm_gpiod_get(dev,
			"headset-detect", GPIOD_IN);
	if (IS_ERR(priv->gpio_headset_detect)) {
		dev_err(dev, "Failed to get headset detect gpio");
		return PTR_ERR(priv->gpio_headset_detect);
	}

	/* Update card-name if provided through DT, else use default name */
	snd_soc_of_parse_card_name(card, "model");

	ret = snd_soc_of_parse_audio_routing(card, "samsung,audio-routing");
	if (ret < 0) {
		dev_err(dev, "Audio routing invalid/unspecified\n");
		return ret;
	}

	aries_dai[1].dai_fmt = priv->variant->modem_dai_fmt;

	cpu = of_get_child_by_name(dev->of_node, "cpu");
	if (!cpu)
		return -EINVAL;

	codec = of_get_child_by_name(dev->of_node, "codec");
	if (!codec)
		return -EINVAL;

	for_each_card_prelinks(card, i, dai_link) {
		dai_link->codecs->of_node = of_parse_phandle(codec,
				"sound-dai", 0);
		if (!dai_link->codecs->of_node) {
			ret = -EINVAL;
			goto out;
		}
	}

	/* Set CPU and platform of_node for main DAI */
	aries_dai[0].cpus->of_node = of_parse_phandle(cpu,
			"sound-dai", 0);
	if (!aries_dai[0].cpus->of_node) {
		ret = -EINVAL;
		goto out;
	}

	aries_dai[0].platforms->of_node = aries_dai[0].cpus->of_node;

	/* Set CPU of_node for BT DAI */
	aries_dai[2].cpus->of_node = of_parse_phandle(cpu,
			"sound-dai", 1);
	if (!aries_dai[2].cpus->of_node) {
		ret = -EINVAL;
		goto out;
	}

	ret = devm_snd_soc_register_component(dev, &aries_component,
				aries_ext_dai, ARRAY_SIZE(aries_ext_dai));
	if (ret < 0) {
		dev_err(dev, "Failed to register component: %d\n", ret);
		goto out;
	}

	ret = devm_snd_soc_register_card(dev, card);
	if (ret)
		dev_err(dev, "snd_soc_register_card() failed:%d\n", ret);

out:
	of_node_put(cpu);
	of_node_put(codec);

	return ret;
}

static struct platform_driver aries_audio_driver = {
	.driver		= {
		.name	= "aries-audio-wm8994",
		.of_match_table = of_match_ptr(samsung_wm8994_of_match),
		.pm	= &snd_soc_pm_ops,
	},
	.probe		= aries_audio_probe,
};

module_platform_driver(aries_audio_driver);

MODULE_DESCRIPTION("ALSA SoC ARIES WM8994");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:aries-audio-wm8994");
