/* linux/arch/arm/mach-s3c2440/mach-osiris-dvs.c
 *
 * Copyright (c) 2009 Simtec Electronics
 *	http://armlinux.simtec.co.uk/
 *	Ben Dooks <ben@simtec.co.uk>
 *
 * Simtec Osiris Dynamic Voltage Scaling support.
 *
 * 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.
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/cpufreq.h>
#include <linux/gpio.h>

#include <linux/i2c/tps65010.h>

#include <plat/cpu-freq.h>

#define OSIRIS_GPIO_DVS	S3C2410_GPB(5)

static bool dvs_en;

static void osiris_dvs_tps_setdvs(bool on)
{
	unsigned vregs1 = 0, vdcdc2 = 0;

	if (!on) {
		vdcdc2 = TPS_VCORE_DISCH | TPS_LP_COREOFF;
		vregs1 = TPS_LDO1_OFF;	/* turn off in low-power mode */
	}

	dvs_en = on;
	vdcdc2 |= TPS_VCORE_1_3V | TPS_VCORE_LP_1_0V;
	vregs1 |= TPS_LDO2_ENABLE | TPS_LDO1_ENABLE;

	tps65010_config_vregs1(vregs1);
	tps65010_config_vdcdc2(vdcdc2);
}

static bool is_dvs(struct s3c_freq *f)
{
	/* at the moment, we assume ARMCLK = HCLK => DVS */
	return f->armclk == f->hclk;
}

/* keep track of current state */
static bool cur_dvs = false;

static int osiris_dvs_notify(struct notifier_block *nb,
			      unsigned long val, void *data)
{
	struct cpufreq_freqs *cf = data;
	struct s3c_cpufreq_freqs *freqs = to_s3c_cpufreq(cf);
	bool old_dvs = is_dvs(&freqs->old);
	bool new_dvs = is_dvs(&freqs->new);
	int ret = 0;

	if (!dvs_en)
		return 0;

	printk(KERN_DEBUG "%s: old %ld,%ld new %ld,%ld\n", __func__,
	       freqs->old.armclk, freqs->old.hclk,
	       freqs->new.armclk, freqs->new.hclk);

	switch (val) {
	case CPUFREQ_PRECHANGE:
		if (old_dvs & !new_dvs ||
		    cur_dvs & !new_dvs) {
			pr_debug("%s: exiting dvs\n", __func__);
			cur_dvs = false;
			gpio_set_value(OSIRIS_GPIO_DVS, 1);
		}
		break;
	case CPUFREQ_POSTCHANGE:
		if (!old_dvs & new_dvs ||
		    !cur_dvs & new_dvs) {
			pr_debug("entering dvs\n");
			cur_dvs = true;
			gpio_set_value(OSIRIS_GPIO_DVS, 0);
		}
		break;
	}

	return ret;
}

static struct notifier_block osiris_dvs_nb = {
	.notifier_call	= osiris_dvs_notify,
};

static int osiris_dvs_probe(struct platform_device *pdev)
{
	int ret;

	dev_info(&pdev->dev, "initialising\n");

	ret = gpio_request(OSIRIS_GPIO_DVS, "osiris-dvs");
	if (ret) {
		dev_err(&pdev->dev, "cannot claim gpio\n");
		goto err_nogpio;
	}

	/* start with dvs disabled */
	gpio_direction_output(OSIRIS_GPIO_DVS, 1);

	ret = cpufreq_register_notifier(&osiris_dvs_nb,
					CPUFREQ_TRANSITION_NOTIFIER);
	if (ret) {
		dev_err(&pdev->dev, "failed to register with cpufreq\n");
		goto err_nofreq;
	}

	osiris_dvs_tps_setdvs(true);

	return 0;

err_nofreq:
	gpio_free(OSIRIS_GPIO_DVS);

err_nogpio:
	return ret;
}

static int osiris_dvs_remove(struct platform_device *pdev)
{
	dev_info(&pdev->dev, "exiting\n");

	/* disable any current dvs */
	gpio_set_value(OSIRIS_GPIO_DVS, 1);
	osiris_dvs_tps_setdvs(false);

	cpufreq_unregister_notifier(&osiris_dvs_nb,
				    CPUFREQ_TRANSITION_NOTIFIER);

	gpio_free(OSIRIS_GPIO_DVS);

	return 0;
}

/* the CONFIG_PM block is so small, it isn't worth actaully compiling it
 * out if the configuration isn't set. */

static int osiris_dvs_suspend(struct device *dev)
{
	gpio_set_value(OSIRIS_GPIO_DVS, 1);
	osiris_dvs_tps_setdvs(false);
	cur_dvs = false;

	return 0;
}

static int osiris_dvs_resume(struct device *dev)
{
	osiris_dvs_tps_setdvs(true);
	return 0;
}

static const struct dev_pm_ops osiris_dvs_pm = {
	.suspend	= osiris_dvs_suspend,
	.resume		= osiris_dvs_resume,
};

static struct platform_driver osiris_dvs_driver = {
	.probe		= osiris_dvs_probe,
	.remove		= osiris_dvs_remove,
	.driver		= {
		.name	= "osiris-dvs",
		.owner	= THIS_MODULE,
		.pm	= &osiris_dvs_pm,
	},
};

module_platform_driver(osiris_dvs_driver);

MODULE_DESCRIPTION("Simtec OSIRIS DVS support");
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:osiris-dvs");
