// SPDX-License-Identifier: (GPL-2.0 OR MIT)
//
// Copyright (c) 2018 BayLibre, SAS.
// Author: Jerome Brunet <jbrunet@baylibre.com>

#include <linux/clk.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <sound/soc.h>

#include "axg-tdm-formatter.h"

struct axg_tdm_formatter {
	struct list_head list;
	struct axg_tdm_stream *stream;
	const struct axg_tdm_formatter_driver *drv;
	struct clk *pclk;
	struct clk *sclk;
	struct clk *lrclk;
	struct clk *sclk_sel;
	struct clk *lrclk_sel;
	struct reset_control *reset;
	bool enabled;
	struct regmap *map;
};

int axg_tdm_formatter_set_channel_masks(struct regmap *map,
					struct axg_tdm_stream *ts,
					unsigned int offset)
{
	unsigned int val, ch = ts->channels;
	unsigned long mask;
	int i, j;

	/*
	 * Distribute the channels of the stream over the available slots
	 * of each TDM lane
	 */
	for (i = 0; i < AXG_TDM_NUM_LANES; i++) {
		val = 0;
		mask = ts->mask[i];

		for (j = find_first_bit(&mask, 32);
		     (j < 32) && ch;
		     j = find_next_bit(&mask, 32, j + 1)) {
			val |= 1 << j;
			ch -= 1;
		}

		regmap_write(map, offset, val);
		offset += regmap_get_reg_stride(map);
	}

	/*
	 * If we still have channel left at the end of the process, it means
	 * the stream has more channels than we can accommodate and we should
	 * have caught this earlier.
	 */
	if (WARN_ON(ch != 0)) {
		pr_err("channel mask error\n");
		return -EINVAL;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(axg_tdm_formatter_set_channel_masks);

static int axg_tdm_formatter_enable(struct axg_tdm_formatter *formatter)
{
	struct axg_tdm_stream *ts = formatter->stream;
	bool invert = formatter->drv->quirks->invert_sclk;
	int ret;

	/* Do nothing if the formatter is already enabled */
	if (formatter->enabled)
		return 0;

	/*
	 * On the g12a (and possibly other SoCs), when a stream using
	 * multiple lanes is restarted, it will sometimes not start
	 * from the first lane, but randomly from another used one.
	 * The result is an unexpected and random channel shift.
	 *
	 * The hypothesis is that an HW counter is not properly reset
	 * and the formatter simply starts on the lane it stopped
	 * before. Unfortunately, there does not seems to be a way to
	 * reset this through the registers of the block.
	 *
	 * However, the g12a has indenpendent reset lines for each audio
	 * devices. Using this reset before each start solves the issue.
	 */
	ret = reset_control_reset(formatter->reset);
	if (ret)
		return ret;

	/*
	 * If sclk is inverted, invert it back and provide the inversion
	 * required by the formatter
	 */
	invert ^= axg_tdm_sclk_invert(ts->iface->fmt);
	ret = clk_set_phase(formatter->sclk, invert ? 180 : 0);
	if (ret)
		return ret;

	/* Setup the stream parameter in the formatter */
	ret = formatter->drv->ops->prepare(formatter->map,
					   formatter->drv->quirks,
					   formatter->stream);
	if (ret)
		return ret;

	/* Enable the signal clocks feeding the formatter */
	ret = clk_prepare_enable(formatter->sclk);
	if (ret)
		return ret;

	ret = clk_prepare_enable(formatter->lrclk);
	if (ret) {
		clk_disable_unprepare(formatter->sclk);
		return ret;
	}

	/* Finally, actually enable the formatter */
	formatter->drv->ops->enable(formatter->map);
	formatter->enabled = true;

	return 0;
}

static void axg_tdm_formatter_disable(struct axg_tdm_formatter *formatter)
{
	/* Do nothing if the formatter is already disabled */
	if (!formatter->enabled)
		return;

	formatter->drv->ops->disable(formatter->map);
	clk_disable_unprepare(formatter->lrclk);
	clk_disable_unprepare(formatter->sclk);
	formatter->enabled = false;
}

static int axg_tdm_formatter_attach(struct axg_tdm_formatter *formatter)
{
	struct axg_tdm_stream *ts = formatter->stream;
	int ret = 0;

	mutex_lock(&ts->lock);

	/* Catch up if the stream is already running when we attach */
	if (ts->ready) {
		ret = axg_tdm_formatter_enable(formatter);
		if (ret) {
			pr_err("failed to enable formatter\n");
			goto out;
		}
	}

	list_add_tail(&formatter->list, &ts->formatter_list);
out:
	mutex_unlock(&ts->lock);
	return ret;
}

static void axg_tdm_formatter_dettach(struct axg_tdm_formatter *formatter)
{
	struct axg_tdm_stream *ts = formatter->stream;

	mutex_lock(&ts->lock);
	list_del(&formatter->list);
	mutex_unlock(&ts->lock);

	axg_tdm_formatter_disable(formatter);
}

static int axg_tdm_formatter_power_up(struct axg_tdm_formatter *formatter,
				      struct snd_soc_dapm_widget *w)
{
	struct axg_tdm_stream *ts = formatter->drv->ops->get_stream(w);
	int ret;

	/*
	 * If we don't get a stream at this stage, it would mean that the
	 * widget is powering up but is not attached to any backend DAI.
	 * It should not happen, ever !
	 */
	if (WARN_ON(!ts))
		return -ENODEV;

	/* Clock our device */
	ret = clk_prepare_enable(formatter->pclk);
	if (ret)
		return ret;

	/* Reparent the bit clock to the TDM interface */
	ret = clk_set_parent(formatter->sclk_sel, ts->iface->sclk);
	if (ret)
		goto disable_pclk;

	/* Reparent the sample clock to the TDM interface */
	ret = clk_set_parent(formatter->lrclk_sel, ts->iface->lrclk);
	if (ret)
		goto disable_pclk;

	formatter->stream = ts;
	ret = axg_tdm_formatter_attach(formatter);
	if (ret)
		goto disable_pclk;

	return 0;

disable_pclk:
	clk_disable_unprepare(formatter->pclk);
	return ret;
}

static void axg_tdm_formatter_power_down(struct axg_tdm_formatter *formatter)
{
	axg_tdm_formatter_dettach(formatter);
	clk_disable_unprepare(formatter->pclk);
	formatter->stream = NULL;
}

int axg_tdm_formatter_event(struct snd_soc_dapm_widget *w,
			    struct snd_kcontrol *control,
			    int event)
{
	struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
	struct axg_tdm_formatter *formatter = snd_soc_component_get_drvdata(c);
	int ret = 0;

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		ret = axg_tdm_formatter_power_up(formatter, w);
		break;

	case SND_SOC_DAPM_PRE_PMD:
		axg_tdm_formatter_power_down(formatter);
		break;

	default:
		dev_err(c->dev, "Unexpected event %d\n", event);
		return -EINVAL;
	}

	return ret;
}
EXPORT_SYMBOL_GPL(axg_tdm_formatter_event);

int axg_tdm_formatter_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	const struct axg_tdm_formatter_driver *drv;
	struct axg_tdm_formatter *formatter;
	struct resource *res;
	void __iomem *regs;
	int ret;

	drv = of_device_get_match_data(dev);
	if (!drv) {
		dev_err(dev, "failed to match device\n");
		return -ENODEV;
	}

	formatter = devm_kzalloc(dev, sizeof(*formatter), GFP_KERNEL);
	if (!formatter)
		return -ENOMEM;
	platform_set_drvdata(pdev, formatter);
	formatter->drv = drv;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	regs = devm_ioremap_resource(dev, res);
	if (IS_ERR(regs))
		return PTR_ERR(regs);

	formatter->map = devm_regmap_init_mmio(dev, regs, drv->regmap_cfg);
	if (IS_ERR(formatter->map)) {
		dev_err(dev, "failed to init regmap: %ld\n",
			PTR_ERR(formatter->map));
		return PTR_ERR(formatter->map);
	}

	/* Peripharal clock */
	formatter->pclk = devm_clk_get(dev, "pclk");
	if (IS_ERR(formatter->pclk)) {
		ret = PTR_ERR(formatter->pclk);
		if (ret != -EPROBE_DEFER)
			dev_err(dev, "failed to get pclk: %d\n", ret);
		return ret;
	}

	/* Formatter bit clock */
	formatter->sclk = devm_clk_get(dev, "sclk");
	if (IS_ERR(formatter->sclk)) {
		ret = PTR_ERR(formatter->sclk);
		if (ret != -EPROBE_DEFER)
			dev_err(dev, "failed to get sclk: %d\n", ret);
		return ret;
	}

	/* Formatter sample clock */
	formatter->lrclk = devm_clk_get(dev, "lrclk");
	if (IS_ERR(formatter->lrclk)) {
		ret = PTR_ERR(formatter->lrclk);
		if (ret != -EPROBE_DEFER)
			dev_err(dev, "failed to get lrclk: %d\n", ret);
		return ret;
	}

	/* Formatter bit clock input multiplexer */
	formatter->sclk_sel = devm_clk_get(dev, "sclk_sel");
	if (IS_ERR(formatter->sclk_sel)) {
		ret = PTR_ERR(formatter->sclk_sel);
		if (ret != -EPROBE_DEFER)
			dev_err(dev, "failed to get sclk_sel: %d\n", ret);
		return ret;
	}

	/* Formatter sample clock input multiplexer */
	formatter->lrclk_sel = devm_clk_get(dev, "lrclk_sel");
	if (IS_ERR(formatter->lrclk_sel)) {
		ret = PTR_ERR(formatter->lrclk_sel);
		if (ret != -EPROBE_DEFER)
			dev_err(dev, "failed to get lrclk_sel: %d\n", ret);
		return ret;
	}

	/* Formatter dedicated reset line */
	formatter->reset = reset_control_get_optional_exclusive(dev, NULL);
	if (IS_ERR(formatter->reset)) {
		ret = PTR_ERR(formatter->reset);
		if (ret != -EPROBE_DEFER)
			dev_err(dev, "failed to get reset: %d\n", ret);
		return ret;
	}

	return devm_snd_soc_register_component(dev, drv->component_drv,
					       NULL, 0);
}
EXPORT_SYMBOL_GPL(axg_tdm_formatter_probe);

int axg_tdm_stream_start(struct axg_tdm_stream *ts)
{
	struct axg_tdm_formatter *formatter;
	int ret = 0;

	mutex_lock(&ts->lock);
	ts->ready = true;

	/* Start all the formatters attached to the stream */
	list_for_each_entry(formatter, &ts->formatter_list, list) {
		ret = axg_tdm_formatter_enable(formatter);
		if (ret) {
			pr_err("failed to start tdm stream\n");
			goto out;
		}
	}

out:
	mutex_unlock(&ts->lock);
	return ret;
}
EXPORT_SYMBOL_GPL(axg_tdm_stream_start);

void axg_tdm_stream_stop(struct axg_tdm_stream *ts)
{
	struct axg_tdm_formatter *formatter;

	mutex_lock(&ts->lock);
	ts->ready = false;

	/* Stop all the formatters attached to the stream */
	list_for_each_entry(formatter, &ts->formatter_list, list) {
		axg_tdm_formatter_disable(formatter);
	}

	mutex_unlock(&ts->lock);
}
EXPORT_SYMBOL_GPL(axg_tdm_stream_stop);

struct axg_tdm_stream *axg_tdm_stream_alloc(struct axg_tdm_iface *iface)
{
	struct axg_tdm_stream *ts;

	ts = kzalloc(sizeof(*ts), GFP_KERNEL);
	if (ts) {
		INIT_LIST_HEAD(&ts->formatter_list);
		mutex_init(&ts->lock);
		ts->iface = iface;
	}

	return ts;
}
EXPORT_SYMBOL_GPL(axg_tdm_stream_alloc);

void axg_tdm_stream_free(struct axg_tdm_stream *ts)
{
	/*
	 * If the list is not empty, it would mean that one of the formatter
	 * widget is still powered and attached to the interface while we
	 * we are removing the TDM DAI. It should not be possible
	 */
	WARN_ON(!list_empty(&ts->formatter_list));
	mutex_destroy(&ts->lock);
	kfree(ts);
}
EXPORT_SYMBOL_GPL(axg_tdm_stream_free);

MODULE_DESCRIPTION("Amlogic AXG TDM formatter driver");
MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
MODULE_LICENSE("GPL v2");
