// SPDX-License-Identifier: GPL-2.0
/*
 * This file is part the core part STM32 DFSDM driver
 *
 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
 * Author(s): Arnaud Pouliquen <arnaud.pouliquen@st.com> for STMicroelectronics.
 */

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/slab.h>

#include "stm32-dfsdm.h"

/**
 * struct stm32_dfsdm_dev_data - DFSDM compatible configuration data
 * @ipid: DFSDM identification number. Used only if hardware provides identification registers
 * @num_filters: DFSDM number of filters. Unused if identification registers are available
 * @num_channels: DFSDM number of channels. Unused if identification registers are available
 * @regmap_cfg: SAI register map configuration pointer
 */
struct stm32_dfsdm_dev_data {
	u32 ipid;
	unsigned int num_filters;
	unsigned int num_channels;
	const struct regmap_config *regmap_cfg;
};

#define STM32H7_DFSDM_NUM_FILTERS	4
#define STM32H7_DFSDM_NUM_CHANNELS	8

static bool stm32_dfsdm_volatile_reg(struct device *dev, unsigned int reg)
{
	if (reg < DFSDM_FILTER_BASE_ADR)
		return false;

	/*
	 * Mask is done on register to avoid to list registers of all
	 * filter instances.
	 */
	switch (reg & DFSDM_FILTER_REG_MASK) {
	case DFSDM_CR1(0) & DFSDM_FILTER_REG_MASK:
	case DFSDM_ISR(0) & DFSDM_FILTER_REG_MASK:
	case DFSDM_JDATAR(0) & DFSDM_FILTER_REG_MASK:
	case DFSDM_RDATAR(0) & DFSDM_FILTER_REG_MASK:
		return true;
	}

	return false;
}

static const struct regmap_config stm32h7_dfsdm_regmap_cfg = {
	.reg_bits = 32,
	.val_bits = 32,
	.reg_stride = sizeof(u32),
	.max_register = 0x2B8,
	.volatile_reg = stm32_dfsdm_volatile_reg,
	.fast_io = true,
};

static const struct stm32_dfsdm_dev_data stm32h7_dfsdm_data = {
	.num_filters = STM32H7_DFSDM_NUM_FILTERS,
	.num_channels = STM32H7_DFSDM_NUM_CHANNELS,
	.regmap_cfg = &stm32h7_dfsdm_regmap_cfg,
};

static const struct regmap_config stm32mp1_dfsdm_regmap_cfg = {
	.reg_bits = 32,
	.val_bits = 32,
	.reg_stride = sizeof(u32),
	.max_register = 0x7fc,
	.volatile_reg = stm32_dfsdm_volatile_reg,
	.fast_io = true,
};

static const struct stm32_dfsdm_dev_data stm32mp1_dfsdm_data = {
	.ipid = STM32MP15_IPIDR_NUMBER,
	.regmap_cfg = &stm32mp1_dfsdm_regmap_cfg,
};

struct dfsdm_priv {
	struct platform_device *pdev; /* platform device */

	struct stm32_dfsdm dfsdm; /* common data exported for all instances */

	unsigned int spi_clk_out_div; /* SPI clkout divider value */
	atomic_t n_active_ch;	/* number of current active channels */

	struct clk *clk; /* DFSDM clock */
	struct clk *aclk; /* audio clock */
};

static inline struct dfsdm_priv *to_stm32_dfsdm_priv(struct stm32_dfsdm *dfsdm)
{
	return container_of(dfsdm, struct dfsdm_priv, dfsdm);
}

static int stm32_dfsdm_clk_prepare_enable(struct stm32_dfsdm *dfsdm)
{
	struct dfsdm_priv *priv = to_stm32_dfsdm_priv(dfsdm);
	int ret;

	ret = clk_prepare_enable(priv->clk);
	if (ret || !priv->aclk)
		return ret;

	ret = clk_prepare_enable(priv->aclk);
	if (ret)
		clk_disable_unprepare(priv->clk);

	return ret;
}

static void stm32_dfsdm_clk_disable_unprepare(struct stm32_dfsdm *dfsdm)
{
	struct dfsdm_priv *priv = to_stm32_dfsdm_priv(dfsdm);

	clk_disable_unprepare(priv->aclk);
	clk_disable_unprepare(priv->clk);
}

/**
 * stm32_dfsdm_start_dfsdm - start global dfsdm interface.
 *
 * Enable interface if n_active_ch is not null.
 * @dfsdm: Handle used to retrieve dfsdm context.
 */
int stm32_dfsdm_start_dfsdm(struct stm32_dfsdm *dfsdm)
{
	struct dfsdm_priv *priv = to_stm32_dfsdm_priv(dfsdm);
	struct device *dev = &priv->pdev->dev;
	unsigned int clk_div = priv->spi_clk_out_div, clk_src;
	int ret;

	if (atomic_inc_return(&priv->n_active_ch) == 1) {
		ret = pm_runtime_resume_and_get(dev);
		if (ret < 0)
			goto error_ret;

		/* select clock source, e.g. 0 for "dfsdm" or 1 for "audio" */
		clk_src = priv->aclk ? 1 : 0;
		ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0),
					 DFSDM_CHCFGR1_CKOUTSRC_MASK,
					 DFSDM_CHCFGR1_CKOUTSRC(clk_src));
		if (ret < 0)
			goto pm_put;

		/* Output the SPI CLKOUT (if clk_div == 0 clock if OFF) */
		ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0),
					 DFSDM_CHCFGR1_CKOUTDIV_MASK,
					 DFSDM_CHCFGR1_CKOUTDIV(clk_div));
		if (ret < 0)
			goto pm_put;

		/* Global enable of DFSDM interface */
		ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0),
					 DFSDM_CHCFGR1_DFSDMEN_MASK,
					 DFSDM_CHCFGR1_DFSDMEN(1));
		if (ret < 0)
			goto pm_put;
	}

	dev_dbg(dev, "%s: n_active_ch %d\n", __func__,
		atomic_read(&priv->n_active_ch));

	return 0;

pm_put:
	pm_runtime_put_sync(dev);
error_ret:
	atomic_dec(&priv->n_active_ch);

	return ret;
}
EXPORT_SYMBOL_GPL(stm32_dfsdm_start_dfsdm);

/**
 * stm32_dfsdm_stop_dfsdm - stop global DFSDM interface.
 *
 * Disable interface if n_active_ch is null
 * @dfsdm: Handle used to retrieve dfsdm context.
 */
int stm32_dfsdm_stop_dfsdm(struct stm32_dfsdm *dfsdm)
{
	struct dfsdm_priv *priv = to_stm32_dfsdm_priv(dfsdm);
	int ret;

	if (atomic_dec_and_test(&priv->n_active_ch)) {
		/* Global disable of DFSDM interface */
		ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0),
					 DFSDM_CHCFGR1_DFSDMEN_MASK,
					 DFSDM_CHCFGR1_DFSDMEN(0));
		if (ret < 0)
			return ret;

		/* Stop SPI CLKOUT */
		ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0),
					 DFSDM_CHCFGR1_CKOUTDIV_MASK,
					 DFSDM_CHCFGR1_CKOUTDIV(0));
		if (ret < 0)
			return ret;

		pm_runtime_put_sync(&priv->pdev->dev);
	}
	dev_dbg(&priv->pdev->dev, "%s: n_active_ch %d\n", __func__,
		atomic_read(&priv->n_active_ch));

	return 0;
}
EXPORT_SYMBOL_GPL(stm32_dfsdm_stop_dfsdm);

static int stm32_dfsdm_parse_of(struct platform_device *pdev,
				struct dfsdm_priv *priv)
{
	struct device_node *node = pdev->dev.of_node;
	struct resource *res;
	unsigned long clk_freq, divider;
	unsigned int spi_freq, rem;
	int ret;

	if (!node)
		return -EINVAL;

	priv->dfsdm.base = devm_platform_get_and_ioremap_resource(pdev, 0,
							&res);
	if (IS_ERR(priv->dfsdm.base))
		return PTR_ERR(priv->dfsdm.base);

	priv->dfsdm.phys_base = res->start;

	/*
	 * "dfsdm" clock is mandatory for DFSDM peripheral clocking.
	 * "dfsdm" or "audio" clocks can be used as source clock for
	 * the SPI clock out signal and internal processing, depending
	 * on use case.
	 */
	priv->clk = devm_clk_get(&pdev->dev, "dfsdm");
	if (IS_ERR(priv->clk))
		return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk),
				     "Failed to get clock\n");

	priv->aclk = devm_clk_get(&pdev->dev, "audio");
	if (IS_ERR(priv->aclk))
		priv->aclk = NULL;

	if (priv->aclk)
		clk_freq = clk_get_rate(priv->aclk);
	else
		clk_freq = clk_get_rate(priv->clk);

	/* SPI clock out frequency */
	ret = of_property_read_u32(pdev->dev.of_node, "spi-max-frequency",
				   &spi_freq);
	if (ret < 0) {
		/* No SPI master mode */
		return 0;
	}

	divider = div_u64_rem(clk_freq, spi_freq, &rem);
	/* Round up divider when ckout isn't precise, not to exceed spi_freq */
	if (rem)
		divider++;

	/* programmable divider is in range of [2:256] */
	if (divider < 2 || divider > 256) {
		dev_err(&pdev->dev, "spi-max-frequency not achievable\n");
		return -EINVAL;
	}

	/* SPI clock output divider is: divider = CKOUTDIV + 1 */
	priv->spi_clk_out_div = divider - 1;
	priv->dfsdm.spi_master_freq = clk_freq / (priv->spi_clk_out_div + 1);

	if (rem) {
		dev_warn(&pdev->dev, "SPI clock not accurate\n");
		dev_warn(&pdev->dev, "%ld = %d * %d + %d\n",
			 clk_freq, spi_freq, priv->spi_clk_out_div + 1, rem);
	}

	return 0;
};

static const struct of_device_id stm32_dfsdm_of_match[] = {
	{
		.compatible = "st,stm32h7-dfsdm",
		.data = &stm32h7_dfsdm_data,
	},
	{
		.compatible = "st,stm32mp1-dfsdm",
		.data = &stm32mp1_dfsdm_data,
	},
	{ }
};
MODULE_DEVICE_TABLE(of, stm32_dfsdm_of_match);

static int stm32_dfsdm_probe_identification(struct platform_device *pdev,
					    struct dfsdm_priv *priv,
					    const struct stm32_dfsdm_dev_data *dev_data)
{
	struct device_node *np = pdev->dev.of_node;
	struct device_node *child;
	struct stm32_dfsdm *dfsdm = &priv->dfsdm;
	const char *compat;
	int ret, count = 0;
	u32 id, val;

	if (!dev_data->ipid) {
		dfsdm->num_fls = dev_data->num_filters;
		dfsdm->num_chs = dev_data->num_channels;
		return 0;
	}

	ret = regmap_read(dfsdm->regmap, DFSDM_IPIDR, &id);
	if (ret)
		return ret;

	if (id != dev_data->ipid) {
		dev_err(&pdev->dev, "Unexpected IP version: 0x%x", id);
		return -EINVAL;
	}

	for_each_child_of_node(np, child) {
		ret = of_property_read_string(child, "compatible", &compat);
		if (ret)
			continue;
		/* Count only child nodes with dfsdm compatible */
		if (strstr(compat, "dfsdm"))
			count++;
	}

	ret = regmap_read(dfsdm->regmap, DFSDM_HWCFGR, &val);
	if (ret)
		return ret;

	dfsdm->num_fls = FIELD_GET(DFSDM_HWCFGR_NBF_MASK, val);
	dfsdm->num_chs = FIELD_GET(DFSDM_HWCFGR_NBT_MASK, val);

	if (count > dfsdm->num_fls) {
		dev_err(&pdev->dev, "Unexpected child number: %d", count);
		return -EINVAL;
	}

	ret = regmap_read(dfsdm->regmap, DFSDM_VERR, &val);
	if (ret)
		return ret;

	dev_dbg(&pdev->dev, "DFSDM version: %lu.%lu. %d channels/%d filters\n",
		FIELD_GET(DFSDM_VERR_MAJREV_MASK, val),
		FIELD_GET(DFSDM_VERR_MINREV_MASK, val),
		dfsdm->num_chs, dfsdm->num_fls);

	return 0;
}

static int stm32_dfsdm_probe(struct platform_device *pdev)
{
	struct dfsdm_priv *priv;
	const struct stm32_dfsdm_dev_data *dev_data;
	struct stm32_dfsdm *dfsdm;
	int ret;

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

	priv->pdev = pdev;

	dev_data = of_device_get_match_data(&pdev->dev);

	dfsdm = &priv->dfsdm;

	ret = stm32_dfsdm_parse_of(pdev, priv);
	if (ret < 0)
		return ret;

	dfsdm->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "dfsdm",
						  dfsdm->base,
						  dev_data->regmap_cfg);
	if (IS_ERR(dfsdm->regmap)) {
		ret = PTR_ERR(dfsdm->regmap);
		dev_err(&pdev->dev, "%s: Failed to allocate regmap: %d\n",
			__func__, ret);
		return ret;
	}

	ret = stm32_dfsdm_probe_identification(pdev, priv, dev_data);
	if (ret < 0)
		return ret;

	dfsdm->fl_list = devm_kcalloc(&pdev->dev, dfsdm->num_fls,
				      sizeof(*dfsdm->fl_list), GFP_KERNEL);
	if (!dfsdm->fl_list)
		return -ENOMEM;

	dfsdm->ch_list = devm_kcalloc(&pdev->dev, dfsdm->num_chs,
				      sizeof(*dfsdm->ch_list), GFP_KERNEL);
	if (!dfsdm->ch_list)
		return -ENOMEM;

	platform_set_drvdata(pdev, dfsdm);

	ret = stm32_dfsdm_clk_prepare_enable(dfsdm);
	if (ret) {
		dev_err(&pdev->dev, "Failed to start clock\n");
		return ret;
	}

	pm_runtime_get_noresume(&pdev->dev);
	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);

	ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
	if (ret)
		goto pm_put;

	pm_runtime_put(&pdev->dev);

	return 0;

pm_put:
	pm_runtime_disable(&pdev->dev);
	pm_runtime_set_suspended(&pdev->dev);
	pm_runtime_put_noidle(&pdev->dev);
	stm32_dfsdm_clk_disable_unprepare(dfsdm);

	return ret;
}

static void stm32_dfsdm_core_remove(struct platform_device *pdev)
{
	struct stm32_dfsdm *dfsdm = platform_get_drvdata(pdev);

	pm_runtime_get_sync(&pdev->dev);
	of_platform_depopulate(&pdev->dev);
	pm_runtime_disable(&pdev->dev);
	pm_runtime_set_suspended(&pdev->dev);
	pm_runtime_put_noidle(&pdev->dev);
	stm32_dfsdm_clk_disable_unprepare(dfsdm);
}

static int stm32_dfsdm_core_suspend(struct device *dev)
{
	struct stm32_dfsdm *dfsdm = dev_get_drvdata(dev);
	struct dfsdm_priv *priv = to_stm32_dfsdm_priv(dfsdm);
	int ret;

	ret = pm_runtime_force_suspend(dev);
	if (ret)
		return ret;

	/* Balance devm_regmap_init_mmio_clk() clk_prepare() */
	clk_unprepare(priv->clk);

	return pinctrl_pm_select_sleep_state(dev);
}

static int stm32_dfsdm_core_resume(struct device *dev)
{
	struct stm32_dfsdm *dfsdm = dev_get_drvdata(dev);
	struct dfsdm_priv *priv = to_stm32_dfsdm_priv(dfsdm);
	int ret;

	ret = pinctrl_pm_select_default_state(dev);
	if (ret)
		return ret;

	ret = clk_prepare(priv->clk);
	if (ret)
		return ret;

	return pm_runtime_force_resume(dev);
}

static int stm32_dfsdm_core_runtime_suspend(struct device *dev)
{
	struct stm32_dfsdm *dfsdm = dev_get_drvdata(dev);

	stm32_dfsdm_clk_disable_unprepare(dfsdm);

	return 0;
}

static int stm32_dfsdm_core_runtime_resume(struct device *dev)
{
	struct stm32_dfsdm *dfsdm = dev_get_drvdata(dev);

	return stm32_dfsdm_clk_prepare_enable(dfsdm);
}

static const struct dev_pm_ops stm32_dfsdm_core_pm_ops = {
	SYSTEM_SLEEP_PM_OPS(stm32_dfsdm_core_suspend, stm32_dfsdm_core_resume)
	RUNTIME_PM_OPS(stm32_dfsdm_core_runtime_suspend,
		       stm32_dfsdm_core_runtime_resume,
		       NULL)
};

static struct platform_driver stm32_dfsdm_driver = {
	.probe = stm32_dfsdm_probe,
	.remove_new = stm32_dfsdm_core_remove,
	.driver = {
		.name = "stm32-dfsdm",
		.of_match_table = stm32_dfsdm_of_match,
		.pm = pm_ptr(&stm32_dfsdm_core_pm_ops),
	},
};

module_platform_driver(stm32_dfsdm_driver);

MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@st.com>");
MODULE_DESCRIPTION("STMicroelectronics STM32 dfsdm driver");
MODULE_LICENSE("GPL v2");
