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