/*
 * Copyright (c) 2016, 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.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_irq.h>
#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/mfd/msm-cdc-supply.h>
#include <linux/regulator/consumer.h>

#define CODEC_DT_MAX_PROP_SIZE 40

static int msm_cdc_dt_parse_vreg_info(struct device *dev,
				      struct cdc_regulator *cdc_vreg,
				      const char *name, bool is_ond)
{
	char prop_name[CODEC_DT_MAX_PROP_SIZE];
	struct device_node *regulator_node = NULL;
	const __be32 *prop;
	int len, rc;
	u32 prop_val;

	/* Parse supply name */
	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "%s-supply", name);

	regulator_node = of_parse_phandle(dev->of_node, prop_name, 0);
	if (!regulator_node) {
		dev_err(dev, "%s: Looking up %s property in node %s failed",
			__func__, prop_name, dev->of_node->full_name);
		rc = -EINVAL;
		goto done;
	}
	cdc_vreg->name = name;
	cdc_vreg->ondemand = is_ond;

	/* Parse supply - voltage */
	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "qcom,%s-voltage", name);
	prop = of_get_property(dev->of_node, prop_name, &len);
	if (!prop || (len != (2 * sizeof(__be32)))) {
		dev_err(dev, "%s: %s %s property\n", __func__,
			prop ? "invalid format" : "no", prop_name);
		rc = -EINVAL;
		goto done;
	} else {
		cdc_vreg->min_uV = be32_to_cpup(&prop[0]);
		cdc_vreg->max_uV = be32_to_cpup(&prop[1]);
	}

	/* Parse supply - current */
	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "qcom,%s-current", name);
	rc = of_property_read_u32(dev->of_node, prop_name, &prop_val);
	if (rc) {
		dev_err(dev, "%s: Looking up %s property in node %s failed",
			__func__, prop_name, dev->of_node->full_name);
		goto done;
	}
	cdc_vreg->optimum_uA = prop_val;

	dev_info(dev, "%s: %s: vol=[%d %d]uV, curr=[%d]uA, ond %d\n",
		 __func__, cdc_vreg->name, cdc_vreg->min_uV, cdc_vreg->max_uV,
		 cdc_vreg->optimum_uA, cdc_vreg->ondemand);

done:
	return rc;
}

static int msm_cdc_parse_supplies(struct device *dev,
				  struct cdc_regulator *cdc_reg,
				  const char *sup_list, int sup_cnt,
				  bool is_ond)
{
	int idx, rc = 0;
	const char *name = NULL;

	for (idx = 0; idx < sup_cnt; idx++) {
		rc = of_property_read_string_index(dev->of_node, sup_list, idx,
						   &name);
		if (rc) {
			dev_err(dev, "%s: read string %s[%d] error (%d)\n",
				__func__, sup_list, idx, rc);
			goto done;
		}

		dev_dbg(dev, "%s: Found cdc supply %s as part of %s\n",
			__func__, name, sup_list);

		rc = msm_cdc_dt_parse_vreg_info(dev, &cdc_reg[idx], name,
						is_ond);
		if (rc) {
			dev_err(dev, "%s: parse %s vreg info failed (%d)\n",
				__func__, name, rc);
			goto done;
		}
	}

done:
	return rc;
}

static int msm_cdc_check_supply_param(struct device *dev,
				      struct cdc_regulator *cdc_vreg,
				      int num_supplies)
{
	if (!dev) {
		pr_err("%s: device is NULL\n", __func__);
		return -ENODEV;
	}

	if (!cdc_vreg || (num_supplies <= 0)) {
		dev_err(dev, "%s: supply check failed: vreg: %pK, num_supplies: %d\n",
			__func__, cdc_vreg, num_supplies);
		return -EINVAL;
	}

	return 0;
}

/*
 * msm_cdc_disable_static_supplies:
 *	Disable codec static supplies
 *
 * @dev: pointer to codec device
 * @supplies: pointer to regulator bulk data
 * @cdc_vreg: pointer to platform regulator data
 * @num_supplies: number of supplies
 *
 * Return error code if supply disable is failed
 */
int msm_cdc_disable_static_supplies(struct device *dev,
				    struct regulator_bulk_data *supplies,
				    struct cdc_regulator *cdc_vreg,
				    int num_supplies)
{
	int rc, i;

	if ((!dev) || (!supplies) || (!cdc_vreg)) {
		pr_err("%s: either dev or supplies or cdc_vreg is NULL\n",
				__func__);
		return -EINVAL;
	}
	/* input parameter validation */
	rc = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies);
	if (rc)
		return rc;

	for (i = 0; i < num_supplies; i++) {
		if (cdc_vreg[i].ondemand)
			continue;

		rc = regulator_disable(supplies[i].consumer);
		if (rc)
			dev_err(dev, "%s: failed to disable supply %s, err:%d\n",
				__func__, supplies[i].supply, rc);
		else
			dev_dbg(dev, "%s: disabled regulator %s\n",
				__func__, supplies[i].supply);
	}

	return rc;
}
EXPORT_SYMBOL(msm_cdc_disable_static_supplies);

/*
 * msm_cdc_release_supplies:
 *	Release codec power supplies
 *
 * @dev: pointer to codec device
 * @supplies: pointer to regulator bulk data
 * @cdc_vreg: pointer to platform regulator data
 * @num_supplies: number of supplies
 *
 * Return error code if supply disable is failed
 */
int msm_cdc_release_supplies(struct device *dev,
			     struct regulator_bulk_data *supplies,
			     struct cdc_regulator *cdc_vreg,
			     int num_supplies)
{
	int rc = 0;
	int i;

	if ((!dev) || (!supplies) || (!cdc_vreg)) {
		pr_err("%s: either dev or supplies or cdc_vreg is NULL\n",
				__func__);
		return -EINVAL;
	}
	/* input parameter validation */
	rc = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies);
	if (rc)
		return rc;

	msm_cdc_disable_static_supplies(dev, supplies, cdc_vreg,
					num_supplies);
	for (i = 0; i < num_supplies; i++) {
		if (regulator_count_voltages(supplies[i].consumer) < 0)
			continue;

		regulator_set_voltage(supplies[i].consumer, 0,
				      cdc_vreg[i].max_uV);
		regulator_set_load(supplies[i].consumer, 0);
		devm_regulator_put(supplies[i].consumer);
		supplies[i].consumer = NULL;
	}
	devm_kfree(dev, supplies);

	return rc;
}
EXPORT_SYMBOL(msm_cdc_release_supplies);

/*
 * msm_cdc_enable_static_supplies:
 *	Enable codec static supplies
 *
 * @dev: pointer to codec device
 * @supplies: pointer to regulator bulk data
 * @cdc_vreg: pointer to platform regulator data
 * @num_supplies: number of supplies
 *
 * Return error code if supply enable is failed
 */
int msm_cdc_enable_static_supplies(struct device *dev,
				   struct regulator_bulk_data *supplies,
				   struct cdc_regulator *cdc_vreg,
				   int num_supplies)
{
	int rc, i;

	if ((!dev) || (!supplies) || (!cdc_vreg)) {
		pr_err("%s: either dev or supplies or cdc_vreg is NULL\n",
				__func__);
		return -EINVAL;
	}
	/* input parameter validation */
	rc = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies);
	if (rc)
		return rc;

	for (i = 0; i < num_supplies; i++) {
		if (cdc_vreg[i].ondemand)
			continue;

		rc = regulator_enable(supplies[i].consumer);
		if (rc) {
			dev_err(dev, "%s: failed to enable supply %s, rc: %d\n",
				__func__, supplies[i].supply, rc);
			break;
		}
	}

	while (rc && i--)
		if (!cdc_vreg[i].ondemand)
			regulator_disable(supplies[i].consumer);

	return rc;
}
EXPORT_SYMBOL(msm_cdc_enable_static_supplies);

/*
 * msm_cdc_init_supplies:
 *	Initialize codec static supplies with regulator get
 *
 * @dev: pointer to codec device
 * @supplies: pointer to regulator bulk data
 * @cdc_vreg: pointer to platform regulator data
 * @num_supplies: number of supplies
 *
 * Return error code if supply init is failed
 */
int msm_cdc_init_supplies(struct device *dev,
			  struct regulator_bulk_data **supplies,
			  struct cdc_regulator *cdc_vreg,
			  int num_supplies)
{
	struct regulator_bulk_data *vsup;
	int rc;
	int i;

	if (!dev || !cdc_vreg) {
		pr_err("%s: device pointer or dce_vreg is NULL\n",
				__func__);
		return -EINVAL;
	}
	/* input parameter validation */
	rc = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies);
	if (rc)
		return rc;

	vsup = devm_kcalloc(dev, num_supplies,
			    sizeof(struct regulator_bulk_data),
			    GFP_KERNEL);
	if (!vsup)
		return -ENOMEM;

	for (i = 0; i < num_supplies; i++) {
		if (!cdc_vreg[i].name) {
			dev_err(dev, "%s: supply name not defined\n",
				__func__);
			rc = -EINVAL;
			goto err_supply;
		}
		vsup[i].supply = cdc_vreg[i].name;
	}

	rc = devm_regulator_bulk_get(dev, num_supplies, vsup);
	if (rc) {
		dev_err(dev, "%s: failed to get supplies (%d)\n",
			__func__, rc);
		goto err_supply;
	}

	/* Set voltage and current on regulators */
	for (i = 0; i < num_supplies; i++) {
		if (regulator_count_voltages(vsup[i].consumer) < 0)
			continue;

		rc = regulator_set_voltage(vsup[i].consumer,
					   cdc_vreg[i].min_uV,
					   cdc_vreg[i].max_uV);
		if (rc) {
			dev_err(dev, "%s: set regulator voltage failed for %s, err:%d\n",
				__func__, vsup[i].supply, rc);
			goto err_set_supply;
		}
		rc = regulator_set_load(vsup[i].consumer,
					cdc_vreg[i].optimum_uA);
		if (rc < 0) {
			dev_err(dev, "%s: set regulator optimum mode failed for %s, err:%d\n",
				__func__, vsup[i].supply, rc);
			goto err_set_supply;
		}
	}

	*supplies = vsup;

	return 0;

err_set_supply:
	for (i = 0; i < num_supplies; i++)
		devm_regulator_put(vsup[i].consumer);
err_supply:
	devm_kfree(dev, vsup);
	return rc;
}
EXPORT_SYMBOL(msm_cdc_init_supplies);

/*
 * msm_cdc_get_power_supplies:
 *	Get codec power supplies from device tree.
 *	Allocate memory to hold regulator data for
 *	all power supplies.
 *
 * @dev: pointer to codec device
 * @cdc_vreg: pointer to codec regulator
 * @total_num_supplies: total number of supplies read from DT
 *
 * Return error code if supply disable is failed
 */
int msm_cdc_get_power_supplies(struct device *dev,
			       struct cdc_regulator **cdc_vreg,
			       int *total_num_supplies)
{
	const char *static_prop_name = "qcom,cdc-static-supplies";
	const char *ond_prop_name = "qcom,cdc-on-demand-supplies";
	const char *cp_prop_name = "qcom,cdc-cp-supplies";
	int static_sup_cnt = 0;
	int ond_sup_cnt = 0;
	int cp_sup_cnt = 0;
	int num_supplies = 0;
	struct cdc_regulator *cdc_reg;
	int rc;

	if (!dev) {
		pr_err("%s: device pointer is NULL\n", __func__);
		return -EINVAL;
	}
	static_sup_cnt = of_property_count_strings(dev->of_node,
						   static_prop_name);
	if (IS_ERR_VALUE(static_sup_cnt)) {
		dev_err(dev, "%s: Failed to get static supplies(%d)\n",
			__func__, static_sup_cnt);
		rc = static_sup_cnt;
		goto err_supply_cnt;
	}
	ond_sup_cnt = of_property_count_strings(dev->of_node, ond_prop_name);
	if (IS_ERR_VALUE(ond_sup_cnt))
		ond_sup_cnt = 0;

	cp_sup_cnt = of_property_count_strings(dev->of_node,
					       cp_prop_name);
	if (IS_ERR_VALUE(cp_sup_cnt))
		cp_sup_cnt = 0;

	num_supplies = static_sup_cnt + ond_sup_cnt + cp_sup_cnt;
	if (num_supplies <= 0) {
		dev_err(dev, "%s: supply count is 0 or negative\n", __func__);
		rc = -EINVAL;
		goto err_supply_cnt;
	}

	cdc_reg = devm_kcalloc(dev, num_supplies,
			       sizeof(struct cdc_regulator),
			       GFP_KERNEL);
	if (!cdc_reg) {
		rc = -ENOMEM;
		goto err_mem_alloc;
	}

	rc = msm_cdc_parse_supplies(dev, cdc_reg, static_prop_name,
				    static_sup_cnt, false);
	if (rc) {
		dev_err(dev, "%s: failed to parse static supplies(%d)\n",
				__func__, rc);
		goto err_sup;
	}

	rc = msm_cdc_parse_supplies(dev, &cdc_reg[static_sup_cnt],
				    ond_prop_name, ond_sup_cnt,
				    true);
	if (rc) {
		dev_err(dev, "%s: failed to parse demand supplies(%d)\n",
				__func__, rc);
		goto err_sup;
	}

	rc = msm_cdc_parse_supplies(dev,
				    &cdc_reg[static_sup_cnt + ond_sup_cnt],
				    cp_prop_name, cp_sup_cnt, true);
	if (rc) {
		dev_err(dev, "%s: failed to parse cp supplies(%d)\n",
				__func__, rc);
		goto err_sup;
	}

	*cdc_vreg = cdc_reg;
	*total_num_supplies = num_supplies;

	return 0;

err_sup:
	devm_kfree(dev, cdc_reg);
err_supply_cnt:
err_mem_alloc:
	return rc;
}
EXPORT_SYMBOL(msm_cdc_get_power_supplies);

