/*
 * Clock driver for Palmas device.
 *
 * Copyright (c) 2013, NVIDIA Corporation.
 * Copyright (c) 2013-2014 Texas Instruments, Inc.
 *
 * Author:	Laxman Dewangan <ldewangan@nvidia.com>
 *		Peter Ujfalusi <peter.ujfalusi@ti.com>
 *
 * 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/clk.h>
#include <linux/clk-provider.h>
#include <linux/mfd/palmas.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#define PALMAS_CLOCK_DT_EXT_CONTROL_ENABLE1	1
#define PALMAS_CLOCK_DT_EXT_CONTROL_ENABLE2	2
#define PALMAS_CLOCK_DT_EXT_CONTROL_NSLEEP	3

struct palmas_clk32k_desc {
	const char *clk_name;
	unsigned int control_reg;
	unsigned int enable_mask;
	unsigned int sleep_mask;
	unsigned int sleep_reqstr_id;
	int delay;
};

struct palmas_clock_info {
	struct device *dev;
	struct clk *clk;
	struct clk_hw hw;
	struct palmas *palmas;
	struct palmas_clk32k_desc *clk_desc;
	int ext_control_pin;
};

static inline struct palmas_clock_info *to_palmas_clks_info(struct clk_hw *hw)
{
	return container_of(hw, struct palmas_clock_info, hw);
}

static unsigned long palmas_clks_recalc_rate(struct clk_hw *hw,
					     unsigned long parent_rate)
{
	return 32768;
}

static int palmas_clks_prepare(struct clk_hw *hw)
{
	struct palmas_clock_info *cinfo = to_palmas_clks_info(hw);
	int ret;

	ret = palmas_update_bits(cinfo->palmas, PALMAS_RESOURCE_BASE,
				 cinfo->clk_desc->control_reg,
				 cinfo->clk_desc->enable_mask,
				 cinfo->clk_desc->enable_mask);
	if (ret < 0)
		dev_err(cinfo->dev, "Reg 0x%02x update failed, %d\n",
			cinfo->clk_desc->control_reg, ret);
	else if (cinfo->clk_desc->delay)
		udelay(cinfo->clk_desc->delay);

	return ret;
}

static void palmas_clks_unprepare(struct clk_hw *hw)
{
	struct palmas_clock_info *cinfo = to_palmas_clks_info(hw);
	int ret;

	/*
	 * Clock can be disabled through external pin if it is externally
	 * controlled.
	 */
	if (cinfo->ext_control_pin)
		return;

	ret = palmas_update_bits(cinfo->palmas, PALMAS_RESOURCE_BASE,
				 cinfo->clk_desc->control_reg,
				 cinfo->clk_desc->enable_mask, 0);
	if (ret < 0)
		dev_err(cinfo->dev, "Reg 0x%02x update failed, %d\n",
			cinfo->clk_desc->control_reg, ret);
}

static int palmas_clks_is_prepared(struct clk_hw *hw)
{
	struct palmas_clock_info *cinfo = to_palmas_clks_info(hw);
	int ret;
	u32 val;

	if (cinfo->ext_control_pin)
		return 1;

	ret = palmas_read(cinfo->palmas, PALMAS_RESOURCE_BASE,
			  cinfo->clk_desc->control_reg, &val);
	if (ret < 0) {
		dev_err(cinfo->dev, "Reg 0x%02x read failed, %d\n",
			cinfo->clk_desc->control_reg, ret);
		return ret;
	}
	return !!(val & cinfo->clk_desc->enable_mask);
}

static struct clk_ops palmas_clks_ops = {
	.prepare	= palmas_clks_prepare,
	.unprepare	= palmas_clks_unprepare,
	.is_prepared	= palmas_clks_is_prepared,
	.recalc_rate	= palmas_clks_recalc_rate,
};

struct palmas_clks_of_match_data {
	struct clk_init_data init;
	struct palmas_clk32k_desc desc;
};

static struct palmas_clks_of_match_data palmas_of_clk32kg = {
	.init = {
		.name = "clk32kg",
		.ops = &palmas_clks_ops,
		.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED,
	},
	.desc = {
		.clk_name = "clk32kg",
		.control_reg = PALMAS_CLK32KG_CTRL,
		.enable_mask = PALMAS_CLK32KG_CTRL_MODE_ACTIVE,
		.sleep_mask = PALMAS_CLK32KG_CTRL_MODE_SLEEP,
		.sleep_reqstr_id = PALMAS_EXTERNAL_REQSTR_ID_CLK32KG,
		.delay = 200,
	},
};

static struct palmas_clks_of_match_data palmas_of_clk32kgaudio = {
	.init = {
		.name = "clk32kgaudio",
		.ops = &palmas_clks_ops,
		.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED,
	},
	.desc = {
		.clk_name = "clk32kgaudio",
		.control_reg = PALMAS_CLK32KGAUDIO_CTRL,
		.enable_mask = PALMAS_CLK32KG_CTRL_MODE_ACTIVE,
		.sleep_mask = PALMAS_CLK32KG_CTRL_MODE_SLEEP,
		.sleep_reqstr_id = PALMAS_EXTERNAL_REQSTR_ID_CLK32KGAUDIO,
		.delay = 200,
	},
};

static const struct of_device_id palmas_clks_of_match[] = {
	{
		.compatible = "ti,palmas-clk32kg",
		.data = &palmas_of_clk32kg,
	},
	{
		.compatible = "ti,palmas-clk32kgaudio",
		.data = &palmas_of_clk32kgaudio,
	},
	{ },
};
MODULE_DEVICE_TABLE(of, palmas_clks_of_match);

static void palmas_clks_get_clk_data(struct platform_device *pdev,
				     struct palmas_clock_info *cinfo)
{
	struct device_node *node = pdev->dev.of_node;
	unsigned int prop;
	int ret;

	ret = of_property_read_u32(node, "ti,external-sleep-control",
				   &prop);
	if (ret)
		return;

	switch (prop) {
	case PALMAS_CLOCK_DT_EXT_CONTROL_ENABLE1:
		prop = PALMAS_EXT_CONTROL_ENABLE1;
		break;
	case PALMAS_CLOCK_DT_EXT_CONTROL_ENABLE2:
		prop = PALMAS_EXT_CONTROL_ENABLE2;
		break;
	case PALMAS_CLOCK_DT_EXT_CONTROL_NSLEEP:
		prop = PALMAS_EXT_CONTROL_NSLEEP;
		break;
	default:
		dev_warn(&pdev->dev, "%s: Invalid ext control option: %u\n",
			 node->name, prop);
		prop = 0;
		break;
	}
	cinfo->ext_control_pin = prop;
}

static int palmas_clks_init_configure(struct palmas_clock_info *cinfo)
{
	int ret;

	ret = palmas_update_bits(cinfo->palmas, PALMAS_RESOURCE_BASE,
				 cinfo->clk_desc->control_reg,
				 cinfo->clk_desc->sleep_mask, 0);
	if (ret < 0) {
		dev_err(cinfo->dev, "Reg 0x%02x update failed, %d\n",
			cinfo->clk_desc->control_reg, ret);
		return ret;
	}

	if (cinfo->ext_control_pin) {
		ret = clk_prepare(cinfo->clk);
		if (ret < 0) {
			dev_err(cinfo->dev, "Clock prep failed, %d\n", ret);
			return ret;
		}

		ret = palmas_ext_control_req_config(cinfo->palmas,
					cinfo->clk_desc->sleep_reqstr_id,
					cinfo->ext_control_pin, true);
		if (ret < 0) {
			dev_err(cinfo->dev, "Ext config for %s failed, %d\n",
				cinfo->clk_desc->clk_name, ret);
			return ret;
		}
	}

	return ret;
}
static int palmas_clks_probe(struct platform_device *pdev)
{
	struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
	struct device_node *node = pdev->dev.of_node;
	struct palmas_clks_of_match_data *match_data;
	const struct of_device_id *match;
	struct palmas_clock_info *cinfo;
	struct clk *clk;
	int ret;

	match = of_match_device(palmas_clks_of_match, &pdev->dev);
	match_data = (struct palmas_clks_of_match_data *)match->data;

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

	palmas_clks_get_clk_data(pdev, cinfo);
	platform_set_drvdata(pdev, cinfo);

	cinfo->dev = &pdev->dev;
	cinfo->palmas = palmas;

	cinfo->clk_desc = &match_data->desc;
	cinfo->hw.init = &match_data->init;
	clk = devm_clk_register(&pdev->dev, &cinfo->hw);
	if (IS_ERR(clk)) {
		ret = PTR_ERR(clk);
		dev_err(&pdev->dev, "Fail to register clock %s, %d\n",
			match_data->desc.clk_name, ret);
		return ret;
	}

	cinfo->clk = clk;
	ret = palmas_clks_init_configure(cinfo);
	if (ret < 0) {
		dev_err(&pdev->dev, "Clock config failed, %d\n", ret);
		return ret;
	}

	ret = of_clk_add_provider(node, of_clk_src_simple_get, cinfo->clk);
	if (ret < 0)
		dev_err(&pdev->dev, "Fail to add clock driver, %d\n", ret);
	return ret;
}

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

static struct platform_driver palmas_clks_driver = {
	.driver = {
		.name = "palmas-clk",
		.of_match_table = palmas_clks_of_match,
	},
	.probe = palmas_clks_probe,
	.remove = palmas_clks_remove,
};

module_platform_driver(palmas_clks_driver);

MODULE_DESCRIPTION("Clock driver for Palmas Series Devices");
MODULE_ALIAS("platform:palmas-clk");
MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
MODULE_LICENSE("GPL v2");
