/*
 * Copyright (C) 2015 Nest Labs
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation version 2.
 *
 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
 * kind, whether express or implied; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/module.h>
#include <linux/clk-provider.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/delay.h>

struct clk_padctl_gate {
	struct clk_hw hw;
	struct pinctrl *pctl;
	struct pinctrl_state *pstate_enabled;
	struct pinctrl_state *pstate_disabled;
};

#define to_clk_padctl_gate(_hw) container_of(_hw, struct clk_padctl_gate, hw)

static int clk_padctl_gate_enable(struct clk_hw *hw)
{
	struct clk_padctl_gate *pg = to_clk_padctl_gate(hw);
	pinctrl_select_state(pg->pctl, pg->pstate_enabled);
	udelay(20);
	return 0;
}

static void clk_padctl_gate_disable(struct clk_hw *hw)
{
	struct clk_padctl_gate *pg = to_clk_padctl_gate(hw);
	pinctrl_select_state(pg->pctl, pg->pstate_disabled);
}

static struct clk_ops clk_padctl_gate_ops = {
	.enable = clk_padctl_gate_enable,
	.disable = clk_padctl_gate_disable,
};

static int padctl_gate_clk_probe(struct platform_device *pdev)
{
	struct clk *clk;
	const char *clk_name;
	const char *parent_name;
	struct clk_padctl_gate *pg;
	struct clk_init_data init;

	/* Use node name unless clock-output-names is specified */
	clk_name = pdev->dev.of_node->name;
	of_property_read_string(pdev->dev.of_node, "clock-output-names", &clk_name);

	/* Look up name of parent clock */
	parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0);
	if (!parent_name)
		return -EINVAL;

	/* Allocate storage for variables */
	pg = devm_kzalloc(&pdev->dev, sizeof(*pg), GFP_KERNEL);
	if (!pg)
		return -ENOMEM;

	platform_set_drvdata(pdev, pg);

	/* Get pin control and settings for enabled and disabled states */
	pg->pctl = devm_pinctrl_get(&pdev->dev);
	if (IS_ERR(pg->pctl)) {
		dev_err(&pdev->dev, "Cannot get pinctrl: %ld\n", PTR_ERR(pg->pctl));
		return PTR_ERR(pg->pctl);
	}

	pg->pstate_enabled = pinctrl_lookup_state(pg->pctl, "active");
	if (IS_ERR(pg->pstate_enabled)) {
		dev_err(&pdev->dev, "Cannot get enabled state: %ld\n", PTR_ERR(pg->pstate_enabled));
		return PTR_ERR(pg->pstate_enabled);
	}

	pg->pstate_disabled = pinctrl_lookup_state(pg->pctl, "default");
	if (IS_ERR(pg->pstate_disabled)) {
		dev_err(&pdev->dev, "Cannot get disabled state: %ld\n", PTR_ERR(pg->pstate_disabled));
		return PTR_ERR(pg->pstate_disabled);
	}

	/* Set up clock initialization values */
	init.name = clk_name;
	init.ops = &clk_padctl_gate_ops;
	init.flags = CLK_IS_BASIC;
	init.parent_names = &parent_name;
	init.num_parents = 1;

	pg->hw.init = &init;

	clk = devm_clk_register(&pdev->dev, &pg->hw);
	if (IS_ERR(clk))
		return PTR_ERR(clk);

	/* Register this DT node as being associated with a clock */
	of_clk_add_provider(pdev->dev.of_node, of_clk_src_simple_get, clk);

	return 0;
}

static int padctl_gate_clk_remove(struct platform_device *pdev)
{
	of_clk_del_provider(pdev->dev.of_node);
	return 0;
}

static const struct of_device_id padctl_gate_clk_of_match[] = {
	{.compatible = "padctl-gate-clock",},
	{},
};
MODULE_DEVICE_TABLE(of, padctl_gate_clk_of_match);

/*
 * Clock driver init functions normally register with CLK_OF_DECLARE
 * and are added to a table processed by of_clk_init.  This function
 * is called by time_init very early in the boot process and certain
 * kernel services like padctrl are not available. Also when clocks
 * are created this way they are not first class devices and device
 * based operations become unavailable.  Given all this, just make
 * this a platform driver instead.
 */

static struct platform_driver padctl_gate_clk_driver = {
	.probe		= padctl_gate_clk_probe,
	.remove		= padctl_gate_clk_remove,
	.driver		= {
		.name	= "clk-padctl-gate",
		.of_match_table = padctl_gate_clk_of_match,
	},
};
module_platform_driver(padctl_gate_clk_driver);

MODULE_AUTHOR("Tim Kryger <tkryger@nestlabs.com>");
MODULE_DESCRIPTION("Pad Control Gate Clock Driver");
MODULE_LICENSE("GPL v2");
