/* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#define pr_fmt(fmt) "%s: " fmt, __func__

#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/mfd/pmic8901.h>

#include "spm.h"

#define FTSMPS_VCTRL_BAND_MASK		0xC0
#define FTSMPS_VCTRL_BAND_1		0x40
#define FTSMPS_VCTRL_BAND_2		0x80
#define FTSMPS_VCTRL_BAND_3		0xC0
#define FTSMPS_VCTRL_VPROG_MASK		0x3F

#define FTSMPS_BAND1_UV_MIN		350000
#define FTSMPS_BAND1_UV_MAX		650000
/* 3 LSB's of program voltage must be 0 in band 1. */
/* Logical step size */
#define FTSMPS_BAND1_UV_LOG_STEP	50000
/* Physical step size */
#define FTSMPS_BAND1_UV_PHYS_STEP	6250

#define FTSMPS_BAND2_UV_MIN		700000
#define FTSMPS_BAND2_UV_MAX		1400000
#define FTSMPS_BAND2_UV_STEP		12500

#define FTSMPS_BAND3_UV_MIN		1400000
#define FTSMPS_BAND3_UV_SET_POINT_MIN	1500000
#define FTSMPS_BAND3_UV_MAX		3300000
#define FTSMPS_BAND3_UV_STEP		50000

struct saw_vreg {
	struct regulator_desc		desc;
	struct regulator_dev		*rdev;
	char				*name;
	int				uV;
	int				last_set_uV;
	unsigned			vlevel;
	bool				online;
};

/* Minimum core operating voltage */
#define MIN_CORE_VOLTAGE		950000

/* Specifies an uninitialized voltage */
#define INVALID_VOLTAGE			-1

/* Specifies the PMIC internal slew rate in uV/us. */
#define REGULATOR_SLEW_RATE		1250

static int saw_get_voltage(struct regulator_dev *rdev)
{
	struct saw_vreg *vreg = rdev_get_drvdata(rdev);

	return vreg->uV;
}

static int _set_voltage(struct regulator_dev *rdev)
{
	struct saw_vreg *vreg = rdev_get_drvdata(rdev);
	int rc;

	rc = msm_spm_set_vdd(rdev_get_id(rdev), vreg->vlevel);
	if (!rc) {
		if (vreg->uV > vreg->last_set_uV) {
			/* Wait for voltage to stabalize. */
			udelay((vreg->uV - vreg->last_set_uV) /
						REGULATOR_SLEW_RATE);
		}
		vreg->last_set_uV = vreg->uV;
	} else {
		pr_err("%s: msm_spm_set_vdd failed %d\n", vreg->name, rc);
		vreg->uV = vreg->last_set_uV;
	}

	return rc;
}

static int saw_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
			   unsigned *selector)
{
	struct saw_vreg *vreg = rdev_get_drvdata(rdev);
	int uV = min_uV;
	u8 vprog, band;

	if (uV < FTSMPS_BAND1_UV_MIN && max_uV >= FTSMPS_BAND1_UV_MIN)
		uV = FTSMPS_BAND1_UV_MIN;

	if (uV < FTSMPS_BAND1_UV_MIN || uV > FTSMPS_BAND3_UV_MAX) {
		pr_err("%s: request v=[%d, %d] is outside possible "
			"v=[%d, %d]\n", vreg->name, min_uV, max_uV,
			FTSMPS_BAND1_UV_MIN, FTSMPS_BAND3_UV_MAX);
		return -EINVAL;
	}

	/* Round up for set points in the gaps between bands. */
	if (uV > FTSMPS_BAND1_UV_MAX && uV < FTSMPS_BAND2_UV_MIN)
		uV = FTSMPS_BAND2_UV_MIN;
	else if (uV > FTSMPS_BAND2_UV_MAX
			&& uV < FTSMPS_BAND3_UV_SET_POINT_MIN)
		uV = FTSMPS_BAND3_UV_SET_POINT_MIN;

	if (uV > FTSMPS_BAND2_UV_MAX) {
		vprog = (uV - FTSMPS_BAND3_UV_MIN + FTSMPS_BAND3_UV_STEP - 1)
			/ FTSMPS_BAND3_UV_STEP;
		band = FTSMPS_VCTRL_BAND_3;
		uV = FTSMPS_BAND3_UV_MIN + vprog * FTSMPS_BAND3_UV_STEP;
	} else if (uV > FTSMPS_BAND1_UV_MAX) {
		vprog = (uV - FTSMPS_BAND2_UV_MIN + FTSMPS_BAND2_UV_STEP - 1)
			/ FTSMPS_BAND2_UV_STEP;
		band = FTSMPS_VCTRL_BAND_2;
		uV = FTSMPS_BAND2_UV_MIN + vprog * FTSMPS_BAND2_UV_STEP;
	} else {
		vprog = (uV - FTSMPS_BAND1_UV_MIN
				+ FTSMPS_BAND1_UV_LOG_STEP - 1)
			/ FTSMPS_BAND1_UV_LOG_STEP;
		uV = FTSMPS_BAND1_UV_MIN + vprog * FTSMPS_BAND1_UV_LOG_STEP;
		vprog *= FTSMPS_BAND1_UV_LOG_STEP / FTSMPS_BAND1_UV_PHYS_STEP;
		band = FTSMPS_VCTRL_BAND_1;
	}

	if (uV > max_uV) {
		pr_err("%s: request v=[%d, %d] cannot be met by any setpoint\n",
			vreg->name, min_uV, max_uV);
		return -EINVAL;
	}

	vreg->vlevel = band | vprog;
	vreg->uV = uV;

	if (!vreg->online)
		return 0;

	return _set_voltage(rdev);
}

static int saw_enable(struct regulator_dev *rdev)
{
	struct saw_vreg *vreg = rdev_get_drvdata(rdev);
	int rc = 0;

	if (vreg->uV != vreg->last_set_uV)
		rc = _set_voltage(rdev);

	if (!rc)
		vreg->online = true;

	return rc;
}

static int saw_disable(struct regulator_dev *rdev)
{
	struct saw_vreg *vreg = rdev_get_drvdata(rdev);

	vreg->online = false;

	return 0;
}

static int saw_is_enabled(struct regulator_dev *rdev)
{
	struct saw_vreg *vreg = rdev_get_drvdata(rdev);

	return vreg->online;
}

static struct regulator_ops saw_ops = {
	.get_voltage = saw_get_voltage,
	.set_voltage = saw_set_voltage,
	.enable	     = saw_enable,
	.disable     = saw_disable,
	.is_enabled  = saw_is_enabled,
};

static int saw_probe(struct platform_device *pdev)
{
	struct regulator_init_data *init_data;
	struct saw_vreg *vreg;
	int rc = 0;

	if (!pdev->dev.platform_data) {
		pr_err("platform data required.\n");
		return -EINVAL;
	}

	init_data = pdev->dev.platform_data;
	if (!init_data->constraints.name) {
		pr_err("regulator name must be specified in constraints.\n");
		return -EINVAL;
	}

	vreg = kzalloc(sizeof(struct saw_vreg), GFP_KERNEL);
	if (!vreg) {
		pr_err("kzalloc failed.\n");
		return -ENOMEM;
	}

	vreg->name = kstrdup(init_data->constraints.name, GFP_KERNEL);
	if (!vreg->name) {
		pr_err("kzalloc failed.\n");
		rc = -ENOMEM;
		goto free_vreg;
	}

	vreg->desc.name	  = vreg->name;
	vreg->desc.id	  = pdev->id;
	vreg->desc.ops	  = &saw_ops;
	vreg->desc.type	  = REGULATOR_VOLTAGE;
	vreg->desc.owner  = THIS_MODULE;
	vreg->uV	  = INVALID_VOLTAGE;
	vreg->last_set_uV = MIN_CORE_VOLTAGE;

	vreg->rdev = regulator_register(&vreg->desc, &pdev->dev,
							init_data, vreg, NULL);
	if (IS_ERR(vreg->rdev)) {
		rc = PTR_ERR(vreg->rdev);
		pr_err("regulator_register failed, rc=%d.\n", rc);
		goto free_name;
	}

	platform_set_drvdata(pdev, vreg);

	pr_info("id=%d, name=%s\n", pdev->id, vreg->name);

	return rc;

free_name:
	kfree(vreg->name);
free_vreg:
	kfree(vreg);

	return rc;
}

static int saw_remove(struct platform_device *pdev)
{
	struct saw_vreg *vreg = platform_get_drvdata(pdev);

	regulator_unregister(vreg->rdev);
	kfree(vreg->name);
	kfree(vreg);
	platform_set_drvdata(pdev, NULL);

	return 0;
}

static struct platform_driver saw_driver = {
	.probe = saw_probe,
	.remove = saw_remove,
	.driver = {
		.name = "saw-regulator",
		.owner = THIS_MODULE,
	},
};

static int __init saw_init(void)
{
	return platform_driver_register(&saw_driver);
}

static void __exit saw_exit(void)
{
	platform_driver_unregister(&saw_driver);
}

postcore_initcall(saw_init);
module_exit(saw_exit);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("SAW regulator driver");
MODULE_ALIAS("platform:saw-regulator");
