// 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/platform_device.h>
#include <linux/property.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,
	.determine_rate = clk_hw_determine_rate_no_reparent,
	.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;
	struct lochnagar_clk *lclk;
	struct lochnagar_config *conf;
	int ret, i;

	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 *)device_get_match_data(dev);

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