// SPDX-License-Identifier: GPL-2.0
/*
 * Lochnagar clock control
 *
 * Copyright (c) 2017-2018 Cirrus Logic, Inc. and
 *                         Cirrus Logic International Semiconductor Ltd.
 *
 * Author: Charles Keepax <ckeepax@opensource.cirrus.com>
 */

#include <linux/clk-provider.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

#include <linux/mfd/lochnagar1_regs.h>
#include <linux/mfd/lochnagar2_regs.h>

#include <dt-bindings/clock/lochnagar.h>

#define LOCHNAGAR_NUM_CLOCKS	(LOCHNAGAR_SPDIF_CLKOUT + 1)

struct lochnagar_clk {
	const char * const name;
	struct clk_hw hw;

	struct lochnagar_clk_priv *priv;

	u16 cfg_reg;
	u16 ena_mask;

	u16 src_reg;
	u16 src_mask;
};

struct lochnagar_clk_priv {
	struct device *dev;
	struct regmap *regmap;

	struct lochnagar_clk lclks[LOCHNAGAR_NUM_CLOCKS];
};

#define LN_PARENT(NAME) { .name = NAME, .fw_name = NAME }

static const struct clk_parent_data lochnagar1_clk_parents[] = {
	LN_PARENT("ln-none"),
	LN_PARENT("ln-spdif-mclk"),
	LN_PARENT("ln-psia1-mclk"),
	LN_PARENT("ln-psia2-mclk"),
	LN_PARENT("ln-cdc-clkout"),
	LN_PARENT("ln-dsp-clkout"),
	LN_PARENT("ln-pmic-32k"),
	LN_PARENT("ln-gf-mclk1"),
	LN_PARENT("ln-gf-mclk3"),
	LN_PARENT("ln-gf-mclk2"),
	LN_PARENT("ln-gf-mclk4"),
};

static const struct clk_parent_data lochnagar2_clk_parents[] = {
	LN_PARENT("ln-none"),
	LN_PARENT("ln-cdc-clkout"),
	LN_PARENT("ln-dsp-clkout"),
	LN_PARENT("ln-pmic-32k"),
	LN_PARENT("ln-spdif-mclk"),
	LN_PARENT("ln-clk-12m"),
	LN_PARENT("ln-clk-11m"),
	LN_PARENT("ln-clk-24m"),
	LN_PARENT("ln-clk-22m"),
	LN_PARENT("ln-clk-8m"),
	LN_PARENT("ln-usb-clk-24m"),
	LN_PARENT("ln-gf-mclk1"),
	LN_PARENT("ln-gf-mclk3"),
	LN_PARENT("ln-gf-mclk2"),
	LN_PARENT("ln-psia1-mclk"),
	LN_PARENT("ln-psia2-mclk"),
	LN_PARENT("ln-spdif-clkout"),
	LN_PARENT("ln-adat-mclk"),
	LN_PARENT("ln-usb-clk-12m"),
};

#define LN1_CLK(ID, NAME, REG) \
	[LOCHNAGAR_##ID] = { \
		.name = NAME, \
		.cfg_reg = LOCHNAGAR1_##REG, \
		.ena_mask = LOCHNAGAR1_##ID##_ENA_MASK, \
		.src_reg = LOCHNAGAR1_##ID##_SEL, \
		.src_mask = LOCHNAGAR1_SRC_MASK, \
	}

#define LN2_CLK(ID, NAME) \
	[LOCHNAGAR_##ID] = { \
		.name = NAME, \
		.cfg_reg = LOCHNAGAR2_##ID##_CTRL, \
		.src_reg = LOCHNAGAR2_##ID##_CTRL, \
		.ena_mask = LOCHNAGAR2_CLK_ENA_MASK, \
		.src_mask = LOCHNAGAR2_CLK_SRC_MASK, \
	}

static const struct lochnagar_clk lochnagar1_clks[LOCHNAGAR_NUM_CLOCKS] = {
	LN1_CLK(CDC_MCLK1,      "ln-cdc-mclk1",  CDC_AIF_CTRL2),
	LN1_CLK(CDC_MCLK2,      "ln-cdc-mclk2",  CDC_AIF_CTRL2),
	LN1_CLK(DSP_CLKIN,      "ln-dsp-clkin",  DSP_AIF),
	LN1_CLK(GF_CLKOUT1,     "ln-gf-clkout1", GF_AIF1),
};

static const struct lochnagar_clk lochnagar2_clks[LOCHNAGAR_NUM_CLOCKS] = {
	LN2_CLK(CDC_MCLK1,      "ln-cdc-mclk1"),
	LN2_CLK(CDC_MCLK2,      "ln-cdc-mclk2"),
	LN2_CLK(DSP_CLKIN,      "ln-dsp-clkin"),
	LN2_CLK(GF_CLKOUT1,     "ln-gf-clkout1"),
	LN2_CLK(GF_CLKOUT2,     "ln-gf-clkout2"),
	LN2_CLK(PSIA1_MCLK,     "ln-psia1-mclk"),
	LN2_CLK(PSIA2_MCLK,     "ln-psia2-mclk"),
	LN2_CLK(SPDIF_MCLK,     "ln-spdif-mclk"),
	LN2_CLK(ADAT_MCLK,      "ln-adat-mclk"),
	LN2_CLK(SOUNDCARD_MCLK, "ln-soundcard-mclk"),
};

struct lochnagar_config {
	const struct clk_parent_data *parents;
	int nparents;
	const struct lochnagar_clk *clks;
};

static const struct lochnagar_config lochnagar1_conf = {
	.parents = lochnagar1_clk_parents,
	.nparents = ARRAY_SIZE(lochnagar1_clk_parents),
	.clks = lochnagar1_clks,
};

static const struct lochnagar_config lochnagar2_conf = {
	.parents = lochnagar2_clk_parents,
	.nparents = ARRAY_SIZE(lochnagar2_clk_parents),
	.clks = lochnagar2_clks,
};

static inline struct lochnagar_clk *lochnagar_hw_to_lclk(struct clk_hw *hw)
{
	return container_of(hw, struct lochnagar_clk, hw);
}

static int lochnagar_clk_prepare(struct clk_hw *hw)
{
	struct lochnagar_clk *lclk = lochnagar_hw_to_lclk(hw);
	struct lochnagar_clk_priv *priv = lclk->priv;
	struct regmap *regmap = priv->regmap;
	int ret;

	ret = regmap_update_bits(regmap, lclk->cfg_reg,
				 lclk->ena_mask, lclk->ena_mask);
	if (ret < 0)
		dev_dbg(priv->dev, "Failed to prepare %s: %d\n",
			lclk->name, ret);

	return ret;
}

static void lochnagar_clk_unprepare(struct clk_hw *hw)
{
	struct lochnagar_clk *lclk = lochnagar_hw_to_lclk(hw);
	struct lochnagar_clk_priv *priv = lclk->priv;
	struct regmap *regmap = priv->regmap;
	int ret;

	ret = regmap_update_bits(regmap, lclk->cfg_reg, lclk->ena_mask, 0);
	if (ret < 0)
		dev_dbg(priv->dev, "Failed to unprepare %s: %d\n",
			lclk->name, ret);
}

static int lochnagar_clk_set_parent(struct clk_hw *hw, u8 index)
{
	struct lochnagar_clk *lclk = lochnagar_hw_to_lclk(hw);
	struct lochnagar_clk_priv *priv = lclk->priv;
	struct regmap *regmap = priv->regmap;
	int ret;

	ret = regmap_update_bits(regmap, lclk->src_reg, lclk->src_mask, index);
	if (ret < 0)
		dev_dbg(priv->dev, "Failed to reparent %s: %d\n",
			lclk->name, ret);

	return ret;
}

static u8 lochnagar_clk_get_parent(struct clk_hw *hw)
{
	struct lochnagar_clk *lclk = lochnagar_hw_to_lclk(hw);
	struct lochnagar_clk_priv *priv = lclk->priv;
	struct regmap *regmap = priv->regmap;
	unsigned int val;
	int ret;

	ret = regmap_read(regmap, lclk->src_reg, &val);
	if (ret < 0) {
		dev_dbg(priv->dev, "Failed to read parent of %s: %d\n",
			lclk->name, ret);
		return clk_hw_get_num_parents(hw);
	}

	val &= lclk->src_mask;

	return val;
}

static const struct clk_ops lochnagar_clk_ops = {
	.prepare = lochnagar_clk_prepare,
	.unprepare = lochnagar_clk_unprepare,
	.set_parent = lochnagar_clk_set_parent,
	.get_parent = lochnagar_clk_get_parent,
};

static struct clk_hw *
lochnagar_of_clk_hw_get(struct of_phandle_args *clkspec, void *data)
{
	struct lochnagar_clk_priv *priv = data;
	unsigned int idx = clkspec->args[0];

	if (idx >= ARRAY_SIZE(priv->lclks)) {
		dev_err(priv->dev, "Invalid index %u\n", idx);
		return ERR_PTR(-EINVAL);
	}

	return &priv->lclks[idx].hw;
}

static const struct of_device_id lochnagar_of_match[] = {
	{ .compatible = "cirrus,lochnagar1-clk", .data = &lochnagar1_conf },
	{ .compatible = "cirrus,lochnagar2-clk", .data = &lochnagar2_conf },
	{}
};
MODULE_DEVICE_TABLE(of, lochnagar_of_match);

static int lochnagar_clk_probe(struct platform_device *pdev)
{
	struct clk_init_data clk_init = {
		.ops = &lochnagar_clk_ops,
	};
	struct device *dev = &pdev->dev;
	struct lochnagar_clk_priv *priv;
	const struct of_device_id *of_id;
	struct lochnagar_clk *lclk;
	struct lochnagar_config *conf;
	int ret, i;

	of_id = of_match_device(lochnagar_of_match, dev);
	if (!of_id)
		return -EINVAL;

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

	priv->dev = dev;
	priv->regmap = dev_get_regmap(dev->parent, NULL);
	conf = (struct lochnagar_config *)of_id->data;

	memcpy(priv->lclks, conf->clks, sizeof(priv->lclks));

	clk_init.parent_data = conf->parents;
	clk_init.num_parents = conf->nparents;

	for (i = 0; i < ARRAY_SIZE(priv->lclks); i++) {
		lclk = &priv->lclks[i];

		if (!lclk->name)
			continue;

		clk_init.name = lclk->name;

		lclk->priv = priv;
		lclk->hw.init = &clk_init;

		ret = devm_clk_hw_register(dev, &lclk->hw);
		if (ret) {
			dev_err(dev, "Failed to register %s: %d\n",
				lclk->name, ret);
			return ret;
		}
	}

	ret = devm_of_clk_add_hw_provider(dev, lochnagar_of_clk_hw_get, priv);
	if (ret < 0)
		dev_err(dev, "Failed to register provider: %d\n", ret);

	return ret;
}

static struct platform_driver lochnagar_clk_driver = {
	.driver = {
		.name = "lochnagar-clk",
		.of_match_table = lochnagar_of_match,
	},
	.probe = lochnagar_clk_probe,
};
module_platform_driver(lochnagar_clk_driver);

MODULE_AUTHOR("Charles Keepax <ckeepax@opensource.cirrus.com>");
MODULE_DESCRIPTION("Clock driver for Cirrus Logic Lochnagar Board");
MODULE_LICENSE("GPL v2");
