/*
 * Copyright (c) 2014 Tomasz Figa <t.figa@samsung.com>
 *
 * Based on Exynos Audio Subsystem Clock Controller driver:
 *
 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
 * Author: Padmavathi Venna <padma.v@samsung.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * Driver for Audio Subsystem Clock Controller of S5PV210-compatible SoCs.
*/

#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/of_address.h>
#include <linux/syscore_ops.h>
#include <linux/init.h>
#include <linux/platform_device.h>

#include <dt-bindings/clock/s5pv210-audss.h>

static DEFINE_SPINLOCK(lock);
static void __iomem *reg_base;
static struct clk_hw_onecell_data *clk_data;

#define ASS_CLK_SRC 0x0
#define ASS_CLK_DIV 0x4
#define ASS_CLK_GATE 0x8

#ifdef CONFIG_PM_SLEEP
static unsigned long reg_save[][2] = {
	{ASS_CLK_SRC,  0},
	{ASS_CLK_DIV,  0},
	{ASS_CLK_GATE, 0},
};

static int s5pv210_audss_clk_suspend(void)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(reg_save); i++)
		reg_save[i][1] = readl(reg_base + reg_save[i][0]);

	return 0;
}

static void s5pv210_audss_clk_resume(void)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(reg_save); i++)
		writel(reg_save[i][1], reg_base + reg_save[i][0]);
}

static struct syscore_ops s5pv210_audss_clk_syscore_ops = {
	.suspend	= s5pv210_audss_clk_suspend,
	.resume		= s5pv210_audss_clk_resume,
};
#endif /* CONFIG_PM_SLEEP */

/* register s5pv210_audss clocks */
static int s5pv210_audss_clk_probe(struct platform_device *pdev)
{
	int i, ret = 0;
	struct resource *res;
	const char *mout_audss_p[2];
	const char *mout_i2s_p[3];
	const char *hclk_p;
	struct clk_hw **clk_table;
	struct clk *hclk, *pll_ref, *pll_in, *cdclk, *sclk_audio;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	reg_base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(reg_base)) {
		dev_err(&pdev->dev, "failed to map audss registers\n");
		return PTR_ERR(reg_base);
	}

	clk_data = devm_kzalloc(&pdev->dev,
				struct_size(clk_data, hws, AUDSS_MAX_CLKS),
				GFP_KERNEL);

	if (!clk_data)
		return -ENOMEM;

	clk_data->num = AUDSS_MAX_CLKS;
	clk_table = clk_data->hws;

	hclk = devm_clk_get(&pdev->dev, "hclk");
	if (IS_ERR(hclk)) {
		dev_err(&pdev->dev, "failed to get hclk clock\n");
		return PTR_ERR(hclk);
	}

	pll_in = devm_clk_get(&pdev->dev, "fout_epll");
	if (IS_ERR(pll_in)) {
		dev_err(&pdev->dev, "failed to get fout_epll clock\n");
		return PTR_ERR(pll_in);
	}

	sclk_audio = devm_clk_get(&pdev->dev, "sclk_audio0");
	if (IS_ERR(sclk_audio)) {
		dev_err(&pdev->dev, "failed to get sclk_audio0 clock\n");
		return PTR_ERR(sclk_audio);
	}

	/* iiscdclk0 is an optional external I2S codec clock */
	cdclk = devm_clk_get(&pdev->dev, "iiscdclk0");
	pll_ref = devm_clk_get(&pdev->dev, "xxti");

	if (!IS_ERR(pll_ref))
		mout_audss_p[0] = __clk_get_name(pll_ref);
	else
		mout_audss_p[0] = "xxti";
	mout_audss_p[1] = __clk_get_name(pll_in);
	clk_table[CLK_MOUT_AUDSS] = clk_hw_register_mux(NULL, "mout_audss",
				mout_audss_p, ARRAY_SIZE(mout_audss_p),
				CLK_SET_RATE_NO_REPARENT,
				reg_base + ASS_CLK_SRC, 0, 1, 0, &lock);

	mout_i2s_p[0] = "mout_audss";
	if (!IS_ERR(cdclk))
		mout_i2s_p[1] = __clk_get_name(cdclk);
	else
		mout_i2s_p[1] = "iiscdclk0";
	mout_i2s_p[2] = __clk_get_name(sclk_audio);
	clk_table[CLK_MOUT_I2S_A] = clk_hw_register_mux(NULL, "mout_i2s_audss",
				mout_i2s_p, ARRAY_SIZE(mout_i2s_p),
				CLK_SET_RATE_NO_REPARENT,
				reg_base + ASS_CLK_SRC, 2, 2, 0, &lock);

	clk_table[CLK_DOUT_AUD_BUS] = clk_hw_register_divider(NULL,
				"dout_aud_bus", "mout_audss", 0,
				reg_base + ASS_CLK_DIV, 0, 4, 0, &lock);
	clk_table[CLK_DOUT_I2S_A] = clk_hw_register_divider(NULL,
				"dout_i2s_audss", "mout_i2s_audss", 0,
				reg_base + ASS_CLK_DIV, 4, 4, 0, &lock);

	clk_table[CLK_I2S] = clk_hw_register_gate(NULL, "i2s_audss",
				"dout_i2s_audss", CLK_SET_RATE_PARENT,
				reg_base + ASS_CLK_GATE, 6, 0, &lock);

	hclk_p = __clk_get_name(hclk);

	clk_table[CLK_HCLK_I2S] = clk_hw_register_gate(NULL, "hclk_i2s_audss",
				hclk_p, CLK_IGNORE_UNUSED,
				reg_base + ASS_CLK_GATE, 5, 0, &lock);
	clk_table[CLK_HCLK_UART] = clk_hw_register_gate(NULL, "hclk_uart_audss",
				hclk_p, CLK_IGNORE_UNUSED,
				reg_base + ASS_CLK_GATE, 4, 0, &lock);
	clk_table[CLK_HCLK_HWA] = clk_hw_register_gate(NULL, "hclk_hwa_audss",
				hclk_p, CLK_IGNORE_UNUSED,
				reg_base + ASS_CLK_GATE, 3, 0, &lock);
	clk_table[CLK_HCLK_DMA] = clk_hw_register_gate(NULL, "hclk_dma_audss",
				hclk_p, CLK_IGNORE_UNUSED,
				reg_base + ASS_CLK_GATE, 2, 0, &lock);
	clk_table[CLK_HCLK_BUF] = clk_hw_register_gate(NULL, "hclk_buf_audss",
				hclk_p, CLK_IGNORE_UNUSED,
				reg_base + ASS_CLK_GATE, 1, 0, &lock);
	clk_table[CLK_HCLK_RP] = clk_hw_register_gate(NULL, "hclk_rp_audss",
				hclk_p, CLK_IGNORE_UNUSED,
				reg_base + ASS_CLK_GATE, 0, 0, &lock);

	for (i = 0; i < clk_data->num; i++) {
		if (IS_ERR(clk_table[i])) {
			dev_err(&pdev->dev, "failed to register clock %d\n", i);
			ret = PTR_ERR(clk_table[i]);
			goto unregister;
		}
	}

	ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get,
				     clk_data);
	if (ret) {
		dev_err(&pdev->dev, "failed to add clock provider\n");
		goto unregister;
	}

#ifdef CONFIG_PM_SLEEP
	register_syscore_ops(&s5pv210_audss_clk_syscore_ops);
#endif

	return 0;

unregister:
	for (i = 0; i < clk_data->num; i++) {
		if (!IS_ERR(clk_table[i]))
			clk_hw_unregister(clk_table[i]);
	}

	return ret;
}

static const struct of_device_id s5pv210_audss_clk_of_match[] = {
	{ .compatible = "samsung,s5pv210-audss-clock", },
	{},
};

static struct platform_driver s5pv210_audss_clk_driver = {
	.driver	= {
		.name = "s5pv210-audss-clk",
		.suppress_bind_attrs = true,
		.of_match_table = s5pv210_audss_clk_of_match,
	},
	.probe = s5pv210_audss_clk_probe,
};

static int __init s5pv210_audss_clk_init(void)
{
	return platform_driver_register(&s5pv210_audss_clk_driver);
}
core_initcall(s5pv210_audss_clk_init);
