/* Copyright (c) 2016-2017, 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_gpio.h>
#include <linux/of_irq.h>
#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/regmap.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/mfd/core.h>
#include <linux/mfd/wcd9xxx/pdata.h>
#include <linux/mfd/wcd9xxx/core.h>
#include <linux/mfd/wcd9xxx/wcd9xxx-irq.h>
#include <linux/mfd/msm-cdc-supply.h>
#include <linux/mfd/msm-cdc-pinctrl.h>
#include <linux/mfd/wcd9xxx/wcd9xxx-utils.h>

#define REG_BYTES 2
#define VAL_BYTES 1
/*
 * Page Register Address that APP Proc uses to
 * access WCD9335 Codec registers is identified
 * as 0x00
 */
#define PAGE_REG_ADDR 0x00

static enum wcd9xxx_intf_status wcd9xxx_intf = -1;

static struct mfd_cell tavil_devs[] = {
	{
		.name = "qcom-wcd-pinctrl",
		.of_compatible = "qcom,wcd-pinctrl",
	},
	{
		.name = "tavil_codec",
	},
};

static struct mfd_cell tasha_devs[] = {
	{
		.name = "tasha_codec",
	},
};

static struct mfd_cell tomtom_devs[] = {
	{
		.name = "tomtom_codec",
	},
};

static int wcd9xxx_read_of_property_u32(struct device *dev, const char *name,
					u32 *val)
{
	int rc = 0;

	rc = of_property_read_u32(dev->of_node, name, val);
	if (rc)
		dev_err(dev, "%s: Looking up %s property in node %s failed",
			__func__, name, dev->of_node->full_name);

	return rc;
}

static void wcd9xxx_dt_parse_micbias_info(struct device *dev,
					  struct wcd9xxx_micbias_setting *mb)
{
	u32 prop_val;
	int rc;

	if (of_find_property(dev->of_node, "qcom,cdc-micbias-ldoh-v", NULL)) {
		rc = wcd9xxx_read_of_property_u32(dev,
						  "qcom,cdc-micbias-ldoh-v",
						  &prop_val);
		if (!rc)
			mb->ldoh_v  =  (u8)prop_val;
	}

	/* MB1 */
	if (of_find_property(dev->of_node, "qcom,cdc-micbias-cfilt1-mv",
			     NULL)) {
		rc = wcd9xxx_read_of_property_u32(dev,
						  "qcom,cdc-micbias-cfilt1-mv",
						   &prop_val);
		if (!rc)
			mb->cfilt1_mv = prop_val;

		rc = wcd9xxx_read_of_property_u32(dev,
						"qcom,cdc-micbias1-cfilt-sel",
						&prop_val);
		if (!rc)
			mb->bias1_cfilt_sel = (u8)prop_val;

	} else if (of_find_property(dev->of_node, "qcom,cdc-micbias1-mv",
				    NULL)) {
		rc = wcd9xxx_read_of_property_u32(dev,
						  "qcom,cdc-micbias1-mv",
						  &prop_val);
		if (!rc)
			mb->micb1_mv = prop_val;
	} else {
		dev_info(dev, "%s: Micbias1 DT property not found\n",
			__func__);
	}

	/* MB2 */
	if (of_find_property(dev->of_node, "qcom,cdc-micbias-cfilt2-mv",
			     NULL)) {
		rc = wcd9xxx_read_of_property_u32(dev,
						  "qcom,cdc-micbias-cfilt2-mv",
						   &prop_val);
		if (!rc)
			mb->cfilt2_mv = prop_val;

		rc = wcd9xxx_read_of_property_u32(dev,
						"qcom,cdc-micbias2-cfilt-sel",
						&prop_val);
		if (!rc)
			mb->bias2_cfilt_sel = (u8)prop_val;

	} else if (of_find_property(dev->of_node, "qcom,cdc-micbias2-mv",
				    NULL)) {
		rc = wcd9xxx_read_of_property_u32(dev,
						  "qcom,cdc-micbias2-mv",
						  &prop_val);
		if (!rc)
			mb->micb2_mv = prop_val;
	} else {
		dev_info(dev, "%s: Micbias2 DT property not found\n",
			__func__);
	}

	/* MB3 */
	if (of_find_property(dev->of_node, "qcom,cdc-micbias-cfilt3-mv",
			     NULL)) {
		rc = wcd9xxx_read_of_property_u32(dev,
						  "qcom,cdc-micbias-cfilt3-mv",
						   &prop_val);
		if (!rc)
			mb->cfilt3_mv = prop_val;

		rc = wcd9xxx_read_of_property_u32(dev,
						"qcom,cdc-micbias3-cfilt-sel",
						&prop_val);
		if (!rc)
			mb->bias3_cfilt_sel = (u8)prop_val;

	} else if (of_find_property(dev->of_node, "qcom,cdc-micbias3-mv",
				    NULL)) {
		rc = wcd9xxx_read_of_property_u32(dev,
						  "qcom,cdc-micbias3-mv",
						  &prop_val);
		if (!rc)
			mb->micb3_mv = prop_val;
	} else {
		dev_info(dev, "%s: Micbias3 DT property not found\n",
			__func__);
	}

	/* MB4 */
	if (of_find_property(dev->of_node, "qcom,cdc-micbias4-cfilt-sel",
			     NULL)) {
		rc = wcd9xxx_read_of_property_u32(dev,
						"qcom,cdc-micbias4-cfilt-sel",
						&prop_val);
		if (!rc)
			mb->bias4_cfilt_sel = (u8)prop_val;

	} else if (of_find_property(dev->of_node, "qcom,cdc-micbias4-mv",
				    NULL)) {
		rc = wcd9xxx_read_of_property_u32(dev,
						  "qcom,cdc-micbias4-mv",
						  &prop_val);
		if (!rc)
			mb->micb4_mv = prop_val;
	} else {
		dev_info(dev, "%s: Micbias4 DT property not found\n",
			__func__);
	}

	mb->bias1_cap_mode =
	   (of_property_read_bool(dev->of_node, "qcom,cdc-micbias1-ext-cap") ?
	 MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP);
	mb->bias2_cap_mode =
	   (of_property_read_bool(dev->of_node, "qcom,cdc-micbias2-ext-cap") ?
	    MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP);
	mb->bias3_cap_mode =
	   (of_property_read_bool(dev->of_node, "qcom,cdc-micbias3-ext-cap") ?
	    MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP);
	mb->bias4_cap_mode =
	   (of_property_read_bool(dev->of_node, "qcom,cdc-micbias4-ext-cap") ?
	    MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP);

	mb->bias2_is_headset_only =
		of_property_read_bool(dev->of_node,
				      "qcom,cdc-micbias2-headset-only");

	/* Print micbias info */
	dev_dbg(dev, "%s: ldoh_v  %u cfilt1_mv %u cfilt2_mv %u cfilt3_mv %u",
		__func__, (u32)mb->ldoh_v, (u32)mb->cfilt1_mv,
		(u32)mb->cfilt2_mv, (u32)mb->cfilt3_mv);

	dev_dbg(dev, "%s: micb1_mv %u micb2_mv %u micb3_mv %u micb4_mv %u",
		__func__, mb->micb1_mv, mb->micb2_mv,
		mb->micb3_mv, mb->micb4_mv);

	dev_dbg(dev, "%s: bias1_cfilt_sel %u bias2_cfilt_sel %u\n",
		__func__, (u32)mb->bias1_cfilt_sel, (u32)mb->bias2_cfilt_sel);

	dev_dbg(dev, "%s: bias3_cfilt_sel %u bias4_cfilt_sel %u\n",
		__func__, (u32)mb->bias3_cfilt_sel, (u32)mb->bias4_cfilt_sel);

	dev_dbg(dev, "%s: bias1_ext_cap %d bias2_ext_cap %d\n",
		__func__, mb->bias1_cap_mode, mb->bias2_cap_mode);

	dev_dbg(dev, "%s: bias3_ext_cap %d bias4_ext_cap %d\n",
		__func__, mb->bias3_cap_mode, mb->bias4_cap_mode);

	dev_dbg(dev, "%s: bias2_is_headset_only %d\n",
		__func__, mb->bias2_is_headset_only);
}

/*
 * wcd9xxx_validate_dmic_sample_rate:
 *	Given the dmic_sample_rate and mclk rate, validate the
 *	dmic_sample_rate. If dmic rate is found to be invalid,
 *	assign the dmic rate as undefined, so individual codec
 *	drivers can use their own defaults
 * @dev: the device for which the dmic is to be configured
 * @dmic_sample_rate: The input dmic_sample_rate
 * @mclk_rate: The input codec mclk rate
 * @dmic_rate_type: String to indicate the type of dmic sample
 *		    rate, used for debug/error logging.
 */
static u32 wcd9xxx_validate_dmic_sample_rate(struct device *dev,
		u32 dmic_sample_rate, u32 mclk_rate,
		const char *dmic_rate_type)
{
	u32 div_factor;

	if (dmic_sample_rate == WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED ||
	    mclk_rate % dmic_sample_rate != 0)
		goto undefined_rate;

	div_factor = mclk_rate / dmic_sample_rate;

	switch (div_factor) {
	case 2:
	case 3:
	case 4:
	case 8:
	case 16:
		/* Valid dmic DIV factors */
		dev_dbg(dev, "%s: DMIC_DIV = %u, mclk_rate = %u\n",
			__func__, div_factor, mclk_rate);
		break;
	case 6:
		/*
		 * DIV 6 is valid for both 9.6MHz and 12.288MHz
		 * MCLK on Tavil. Older codecs support DIV6 only
		 * for 12.288MHz MCLK.
		 */
		if ((mclk_rate == WCD9XXX_MCLK_CLK_9P6HZ) &&
		    (of_device_is_compatible(dev->of_node,
					     "qcom,tavil-slim-pgd")))
			dev_dbg(dev, "%s: DMIC_DIV = %u, mclk_rate = %u\n",
				__func__, div_factor, mclk_rate);
		else if (mclk_rate != WCD9XXX_MCLK_CLK_12P288MHZ)
			goto undefined_rate;
		break;
	default:
		/* Any other DIV factor is invalid */
		goto undefined_rate;
	}

	return dmic_sample_rate;

undefined_rate:
	dev_dbg(dev, "%s: Invalid %s = %d, for mclk %d\n",
		 __func__, dmic_rate_type, dmic_sample_rate, mclk_rate);
	dmic_sample_rate = WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED;

	return dmic_sample_rate;
}

/*
 * wcd9xxx_populate_dt_data:
 *	Parse device tree properties for the given codec device
 *
 * @dev: pointer to codec device
 *
 * Returns pointer to the platform data resulting from parsing
 * device tree.
 */
struct wcd9xxx_pdata *wcd9xxx_populate_dt_data(struct device *dev)
{
	struct wcd9xxx_pdata *pdata;
	u32 dmic_sample_rate = WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED;
	u32 mad_dmic_sample_rate = WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED;
	u32 ecpp_dmic_sample_rate = WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED;
	u32 dmic_clk_drive = WCD9XXX_DMIC_CLK_DRIVE_UNDEFINED;
	u32 prop_val;
	int rc = 0;

	if (!dev || !dev->of_node)
		return NULL;

	pdata = devm_kzalloc(dev, sizeof(struct wcd9xxx_pdata),
			     GFP_KERNEL);
	if (!pdata)
		return NULL;

	/* Parse power supplies */
	msm_cdc_get_power_supplies(dev, &pdata->regulator,
				   &pdata->num_supplies);
	if (!pdata->regulator || (pdata->num_supplies <= 0)) {
		dev_err(dev, "%s: no power supplies defined for codec\n",
			__func__);
		goto err_power_sup;
	}

	/* Parse micbias info */
	wcd9xxx_dt_parse_micbias_info(dev, &pdata->micbias);

	pdata->wcd_rst_np = of_parse_phandle(dev->of_node,
					     "qcom,wcd-rst-gpio-node", 0);
	if (!pdata->wcd_rst_np) {
		dev_err(dev, "%s: Looking up %s property in node %s failed\n",
			__func__, "qcom,wcd-rst-gpio-node",
			dev->of_node->full_name);
		goto err_parse_dt_prop;
	}

	if (!(wcd9xxx_read_of_property_u32(dev, "qcom,cdc-mclk-clk-rate",
					   &prop_val)))
		pdata->mclk_rate = prop_val;

	if (pdata->mclk_rate != WCD9XXX_MCLK_CLK_9P6HZ &&
	    pdata->mclk_rate != WCD9XXX_MCLK_CLK_12P288MHZ) {
		dev_err(dev, "%s: Invalid mclk_rate = %u\n", __func__,
			pdata->mclk_rate);
		goto err_parse_dt_prop;
	}

	if (!(wcd9xxx_read_of_property_u32(dev, "qcom,cdc-dmic-sample-rate",
					   &prop_val)))
		dmic_sample_rate = prop_val;

	pdata->dmic_sample_rate = wcd9xxx_validate_dmic_sample_rate(dev,
							dmic_sample_rate,
							pdata->mclk_rate,
							"audio_dmic_rate");
	if (!(wcd9xxx_read_of_property_u32(dev, "qcom,cdc-mad-dmic-rate",
					   &prop_val)))
		mad_dmic_sample_rate = prop_val;

	pdata->mad_dmic_sample_rate = wcd9xxx_validate_dmic_sample_rate(dev,
							mad_dmic_sample_rate,
							pdata->mclk_rate,
							"mad_dmic_rate");

	if (of_find_property(dev->of_node, "qcom,cdc-ecpp-dmic-rate", NULL)) {
		rc = wcd9xxx_read_of_property_u32(dev,
						  "qcom,cdc-ecpp-dmic-rate",
						  &prop_val);
		if (!rc)
			ecpp_dmic_sample_rate = prop_val;
	}

	pdata->ecpp_dmic_sample_rate = wcd9xxx_validate_dmic_sample_rate(dev,
							ecpp_dmic_sample_rate,
							pdata->mclk_rate,
							"ecpp_dmic_rate");

	if (!(of_property_read_u32(dev->of_node,
				   "qcom,cdc-dmic-clk-drv-strength",
				   &prop_val))) {
		dmic_clk_drive = prop_val;

		if (dmic_clk_drive != 2 && dmic_clk_drive != 4 &&
		    dmic_clk_drive != 8 && dmic_clk_drive != 16)
			dev_err(dev, "Invalid cdc-dmic-clk-drv-strength %d\n",
				dmic_clk_drive);
	}

	pdata->dmic_clk_drv = dmic_clk_drive;

	return pdata;

err_parse_dt_prop:
	devm_kfree(dev, pdata->regulator);
	pdata->regulator = NULL;
	pdata->num_supplies = 0;
err_power_sup:
	devm_kfree(dev, pdata);
	return NULL;
}
EXPORT_SYMBOL(wcd9xxx_populate_dt_data);

static bool is_wcd9xxx_reg_power_down(struct wcd9xxx *wcd9xxx, u16 rreg)
{
	bool ret = false;
	int i;
	struct wcd9xxx_power_region *wcd9xxx_pwr;

	if (!wcd9xxx)
		return ret;

	for (i = 0; i < WCD9XXX_MAX_PWR_REGIONS; i++) {
		wcd9xxx_pwr = wcd9xxx->wcd9xxx_pwr[i];
		if (!wcd9xxx_pwr)
			continue;
		if (((wcd9xxx_pwr->pwr_collapse_reg_min == 0) &&
		     (wcd9xxx_pwr->pwr_collapse_reg_max == 0)) ||
		    (wcd9xxx_pwr->power_state ==
		     WCD_REGION_POWER_COLLAPSE_REMOVE))
			ret = false;
		else if (((wcd9xxx_pwr->power_state ==
			   WCD_REGION_POWER_DOWN) ||
			  (wcd9xxx_pwr->power_state ==
			   WCD_REGION_POWER_COLLAPSE_BEGIN)) &&
			 (rreg >= wcd9xxx_pwr->pwr_collapse_reg_min) &&
			 (rreg <= wcd9xxx_pwr->pwr_collapse_reg_max))
			ret = true;
	}
	return ret;
}

/*
 * wcd9xxx_page_write:
 *	Retrieve page number from register and
 *	write that page number to the page address.
 *	Called under io_lock acquisition.
 *
 * @wcd9xxx: pointer to wcd9xxx
 * @reg: Register address from which page number is retrieved
 *
 * Returns 0 for success and negative error code for failure.
 */
int wcd9xxx_page_write(struct wcd9xxx *wcd9xxx, unsigned short *reg)
{
	int ret = 0;
	unsigned short c_reg, reg_addr;
	u8 pg_num, prev_pg_num;

	if (wcd9xxx->type != WCD9335 && wcd9xxx->type != WCD934X)
		return ret;

	c_reg = *reg;
	pg_num = c_reg >> 8;
	reg_addr = c_reg & 0xff;
	if (wcd9xxx->prev_pg_valid) {
		prev_pg_num = wcd9xxx->prev_pg;
		if (prev_pg_num != pg_num) {
			ret = wcd9xxx->write_dev(
					wcd9xxx, PAGE_REG_ADDR, 1,
					(void *) &pg_num, false);
			if (ret < 0)
				pr_err("page write error, pg_num: 0x%x\n",
					pg_num);
			else {
				wcd9xxx->prev_pg = pg_num;
				dev_dbg(wcd9xxx->dev, "%s: Page 0x%x Write to 0x00\n",
					__func__, pg_num);
			}
		}
	} else {
		ret = wcd9xxx->write_dev(
				wcd9xxx, PAGE_REG_ADDR, 1, (void *) &pg_num,
				false);
		if (ret < 0)
			pr_err("page write error, pg_num: 0x%x\n", pg_num);
		else {
			wcd9xxx->prev_pg = pg_num;
			wcd9xxx->prev_pg_valid = true;
			dev_dbg(wcd9xxx->dev, "%s: Page 0x%x Write to 0x00\n",
				__func__, pg_num);
		}
	}
	*reg = reg_addr;
	return ret;
}
EXPORT_SYMBOL(wcd9xxx_page_write);

static int regmap_bus_read(void *context, const void *reg, size_t reg_size,
			   void *val, size_t val_size)
{
	struct device *dev = context;
	struct wcd9xxx *wcd9xxx = dev_get_drvdata(dev);
	unsigned short c_reg, rreg;
	int ret, i;

	if (!wcd9xxx) {
		dev_err(dev, "%s: wcd9xxx is NULL\n", __func__);
		return -EINVAL;
	}
	if (!reg || !val) {
		dev_err(dev, "%s: reg or val is NULL\n", __func__);
		return -EINVAL;
	}

	if (reg_size != REG_BYTES) {
		dev_err(dev, "%s: register size %zd bytes, not supported\n",
			__func__, reg_size);
		return -EINVAL;
	}

	mutex_lock(&wcd9xxx->io_lock);
	c_reg = *(u16 *)reg;
	rreg = c_reg;

	if (is_wcd9xxx_reg_power_down(wcd9xxx, rreg)) {
		ret = 0;
		for (i = 0; i < val_size; i++)
			((u8 *)val)[i] = 0;
		goto err;
	}
	ret = wcd9xxx_page_write(wcd9xxx, &c_reg);
	if (ret)
		goto err;
	ret = wcd9xxx->read_dev(wcd9xxx, c_reg, val_size, val, false);
	if (ret < 0)
		dev_err(dev, "%s: Codec read failed (%d), reg: 0x%x, size:%zd\n",
			__func__, ret, rreg, val_size);
	else {
		for (i = 0; i < val_size; i++)
			dev_dbg(dev, "%s: Read 0x%02x from 0x%x\n",
				__func__, ((u8 *)val)[i], rreg + i);
	}
err:
	mutex_unlock(&wcd9xxx->io_lock);

	return ret;
}

static int regmap_bus_gather_write(void *context,
				   const void *reg, size_t reg_size,
				   const void *val, size_t val_size)
{
	struct device *dev = context;
	struct wcd9xxx *wcd9xxx = dev_get_drvdata(dev);
	unsigned short c_reg, rreg;
	int ret, i;

	if (!wcd9xxx) {
		dev_err(dev, "%s: wcd9xxx is NULL\n", __func__);
		return -EINVAL;
	}
	if (!reg || !val) {
		dev_err(dev, "%s: reg or val is NULL\n", __func__);
		return -EINVAL;
	}
	if (reg_size != REG_BYTES) {
		dev_err(dev, "%s: register size %zd bytes, not supported\n",
			__func__, reg_size);
		return -EINVAL;
	}
	mutex_lock(&wcd9xxx->io_lock);
	c_reg = *(u16 *)reg;
	rreg = c_reg;

	if (is_wcd9xxx_reg_power_down(wcd9xxx, rreg)) {
		ret = 0;
		goto err;
	}
	ret = wcd9xxx_page_write(wcd9xxx, &c_reg);
	if (ret)
		goto err;

	for (i = 0; i < val_size; i++)
		dev_dbg(dev, "Write %02x to 0x%x\n", ((u8 *)val)[i],
			rreg + i);

	ret = wcd9xxx->write_dev(wcd9xxx, c_reg, val_size, (void *) val,
				 false);
	if (ret < 0)
		dev_err(dev, "%s: Codec write failed (%d), reg:0x%x, size:%zd\n",
			__func__, ret, rreg, val_size);

err:
	mutex_unlock(&wcd9xxx->io_lock);
	return ret;
}

static int regmap_bus_write(void *context, const void *data, size_t count)
{
	struct device *dev = context;
	struct wcd9xxx *wcd9xxx = dev_get_drvdata(dev);

	if (!wcd9xxx)
		return -EINVAL;

	WARN_ON(count < REG_BYTES);

	if (count > (REG_BYTES + VAL_BYTES)) {
		if (wcd9xxx->multi_reg_write)
			return wcd9xxx->multi_reg_write(wcd9xxx,
							data, count);
	} else
		return regmap_bus_gather_write(context, data, REG_BYTES,
					       data + REG_BYTES,
					       count - REG_BYTES);

	dev_err(dev, "%s: bus multi reg write failure\n", __func__);

	return -EINVAL;
}

static struct regmap_bus regmap_bus_config = {
	.write = regmap_bus_write,
	.gather_write = regmap_bus_gather_write,
	.read = regmap_bus_read,
	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
};

/*
 * wcd9xxx_regmap_init:
 *	Initialize wcd9xxx register map
 *
 * @dev: pointer to wcd device
 * @config: pointer to register map config
 *
 * Returns pointer to regmap structure for success
 * or NULL in case of failure.
 */
struct regmap *wcd9xxx_regmap_init(struct device *dev,
				   const struct regmap_config *config)
{
	return devm_regmap_init(dev, &regmap_bus_config, dev, config);
}
EXPORT_SYMBOL(wcd9xxx_regmap_init);

/*
 * wcd9xxx_reset:
 *	Reset wcd9xxx codec
 *
 * @dev: pointer to wcd device
 *
 * Returns 0 for success or negative error code in case of failure
 */
int wcd9xxx_reset(struct device *dev)
{
	struct wcd9xxx *wcd9xxx;
	int rc;
	int value;

	if (!dev)
		return -ENODEV;

	wcd9xxx = dev_get_drvdata(dev);
	if (!wcd9xxx)
		return -EINVAL;

	if (!wcd9xxx->wcd_rst_np) {
		dev_err(dev, "%s: reset gpio device node not specified\n",
			__func__);
		return -EINVAL;
	}

	value = msm_cdc_pinctrl_get_state(wcd9xxx->wcd_rst_np);
	if (value > 0) {
		wcd9xxx->avoid_cdc_rstlow = 1;
		return 0;
	}

	rc = msm_cdc_pinctrl_select_sleep_state(wcd9xxx->wcd_rst_np);
	if (rc) {
		dev_err(dev, "%s: wcd sleep state request fail!\n",
			__func__);
		return rc;
	}

	/* 20ms sleep required after pulling the reset gpio to LOW */
	msleep(20);

	rc = msm_cdc_pinctrl_select_active_state(wcd9xxx->wcd_rst_np);
	if (rc) {
		dev_err(dev, "%s: wcd active state request fail!\n",
			__func__);
		return rc;
	}
	msleep(20);

	return rc;
}
EXPORT_SYMBOL(wcd9xxx_reset);

/*
 * wcd9xxx_reset_low:
 *	Pull the wcd9xxx codec reset_n to low
 *
 * @dev: pointer to wcd device
 *
 * Returns 0 for success or negative error code in case of failure
 */
int wcd9xxx_reset_low(struct device *dev)
{
	struct wcd9xxx *wcd9xxx;
	int rc;

	if (!dev)
		return -ENODEV;

	wcd9xxx = dev_get_drvdata(dev);
	if (!wcd9xxx)
		return -EINVAL;

	if (!wcd9xxx->wcd_rst_np) {
		dev_err(dev, "%s: reset gpio device node not specified\n",
			__func__);
		return -EINVAL;
	}
	if (wcd9xxx->avoid_cdc_rstlow) {
		wcd9xxx->avoid_cdc_rstlow = 0;
		dev_dbg(dev, "%s: avoid pull down of reset GPIO\n", __func__);
		return 0;
	}

	rc = msm_cdc_pinctrl_select_sleep_state(wcd9xxx->wcd_rst_np);
	if (rc)
		dev_err(dev, "%s: wcd sleep state request fail!\n",
			__func__);

	return rc;
}
EXPORT_SYMBOL(wcd9xxx_reset_low);

/*
 * wcd9xxx_bringup:
 *	Toggle reset analog and digital cores of wcd9xxx codec
 *
 * @dev: pointer to wcd device
 *
 * Returns 0 for success or negative error code in case of failure
 */
int wcd9xxx_bringup(struct device *dev)
{
	struct wcd9xxx *wcd9xxx;
	int rc;
	codec_bringup_fn cdc_bup_fn;

	if (!dev)
		return -ENODEV;

	wcd9xxx = dev_get_drvdata(dev);
	if (!wcd9xxx)
		return -EINVAL;

	cdc_bup_fn = wcd9xxx_bringup_fn(wcd9xxx->type);
	if (!cdc_bup_fn) {
		dev_err(dev, "%s: Codec bringup fn NULL!\n",
			__func__);
		return -EINVAL;
	}
	rc = cdc_bup_fn(wcd9xxx);
	if (rc)
		dev_err(dev, "%s: Codec bringup error, rc: %d\n",
			__func__, rc);

	return rc;
}
EXPORT_SYMBOL(wcd9xxx_bringup);

/*
 * wcd9xxx_bringup:
 *	Set analog and digital cores of wcd9xxx codec in reset state
 *
 * @dev: pointer to wcd device
 *
 * Returns 0 for success or negative error code in case of failure
 */
int wcd9xxx_bringdown(struct device *dev)
{
	struct wcd9xxx *wcd9xxx;
	int rc;
	codec_bringdown_fn cdc_bdown_fn;

	if (!dev)
		return -ENODEV;

	wcd9xxx = dev_get_drvdata(dev);
	if (!wcd9xxx)
		return -EINVAL;

	cdc_bdown_fn = wcd9xxx_bringdown_fn(wcd9xxx->type);
	if (!cdc_bdown_fn) {
		dev_err(dev, "%s: Codec bring down fn NULL!\n",
			__func__);
		return -EINVAL;
	}
	rc = cdc_bdown_fn(wcd9xxx);
	if (rc)
		dev_err(dev, "%s: Codec bring down error, rc: %d\n",
			__func__, rc);

	return rc;
}
EXPORT_SYMBOL(wcd9xxx_bringdown);

/*
 * wcd9xxx_get_codec_info:
 *	Fill codec specific information like interrupts, version
 *
 * @dev: pointer to wcd device
 *
 * Returns 0 for success or negative error code in case of failure
 */
int wcd9xxx_get_codec_info(struct device *dev)
{
	struct wcd9xxx *wcd9xxx;
	int rc;
	codec_type_fn cdc_type_fn;
	struct wcd9xxx_codec_type *cinfo;

	if (!dev)
		return -ENODEV;

	wcd9xxx = dev_get_drvdata(dev);
	if (!wcd9xxx)
		return -EINVAL;

	cdc_type_fn = wcd9xxx_get_codec_info_fn(wcd9xxx->type);
	if (!cdc_type_fn) {
		dev_err(dev, "%s: Codec fill type fn NULL!\n",
			__func__);
		return -EINVAL;
	}

	cinfo = wcd9xxx->codec_type;
	if (!cinfo)
		return -EINVAL;

	rc = cdc_type_fn(wcd9xxx, cinfo);
	if (rc) {
		dev_err(dev, "%s: Codec type fill failed, rc:%d\n",
			__func__, rc);
		return rc;

	}

	switch (wcd9xxx->type) {
	case WCD934X:
		cinfo->dev = tavil_devs;
		cinfo->size = ARRAY_SIZE(tavil_devs);
		break;
	case WCD9335:
		cinfo->dev = tasha_devs;
		cinfo->size = ARRAY_SIZE(tasha_devs);
		break;
	case WCD9330:
		cinfo->dev = tomtom_devs;
		cinfo->size = ARRAY_SIZE(tomtom_devs);
		break;
	default:
		cinfo->dev = NULL;
		cinfo->size = 0;
		break;
	}

	return rc;
}
EXPORT_SYMBOL(wcd9xxx_get_codec_info);

/*
 * wcd9xxx_core_irq_init:
 *	Initialize wcd9xxx codec irq instance
 *
 * @wcd9xxx_core_res: pointer to wcd core resource
 *
 * Returns 0 for success or negative error code in case of failure
 */
int wcd9xxx_core_irq_init(
	struct wcd9xxx_core_resource *wcd9xxx_core_res)
{
	int ret = 0;

	if (!wcd9xxx_core_res)
		return -EINVAL;

	if (wcd9xxx_core_res->irq != 1) {
		ret = wcd9xxx_irq_init(wcd9xxx_core_res);
		if (ret)
			pr_err("IRQ initialization failed\n");
	}

	return ret;
}
EXPORT_SYMBOL(wcd9xxx_core_irq_init);

/*
 * wcd9xxx_assign_irq:
 *	Assign irq and irq_base to wcd9xxx core resource
 *
 * @wcd9xxx_core_res: pointer to wcd core resource
 * @irq: irq number
 * @irq_base: base irq number
 *
 * Returns 0 for success or negative error code in case of failure
 */
int wcd9xxx_assign_irq(
	struct wcd9xxx_core_resource *wcd9xxx_core_res,
	unsigned int irq,
	unsigned int irq_base)
{
	if (!wcd9xxx_core_res)
		return -EINVAL;

	wcd9xxx_core_res->irq = irq;
	wcd9xxx_core_res->irq_base = irq_base;

	return 0;
}
EXPORT_SYMBOL(wcd9xxx_assign_irq);

/*
 * wcd9xxx_core_res_init:
 *	Initialize wcd core resource instance
 *
 * @wcd9xxx_core_res: pointer to wcd core resource
 * @num_irqs: number of irqs for wcd9xxx core
 * @num_irq_regs: number of irq registers
 * @wcd_regmap: pointer to the wcd register map
 *
 * Returns 0 for success or negative error code in case of failure
 */
int wcd9xxx_core_res_init(
	struct wcd9xxx_core_resource *wcd9xxx_core_res,
	int num_irqs, int num_irq_regs, struct regmap *wcd_regmap)
{
	if (!wcd9xxx_core_res || !wcd_regmap)
		return -EINVAL;

	mutex_init(&wcd9xxx_core_res->pm_lock);
	wcd9xxx_core_res->wlock_holders = 0;
	wcd9xxx_core_res->pm_state = WCD9XXX_PM_SLEEPABLE;
	init_waitqueue_head(&wcd9xxx_core_res->pm_wq);
	pm_qos_add_request(&wcd9xxx_core_res->pm_qos_req,
				PM_QOS_CPU_DMA_LATENCY,
				PM_QOS_DEFAULT_VALUE);

	wcd9xxx_core_res->num_irqs = num_irqs;
	wcd9xxx_core_res->num_irq_regs = num_irq_regs;
	wcd9xxx_core_res->wcd_core_regmap = wcd_regmap;

	pr_info("%s: num_irqs = %d, num_irq_regs = %d\n",
			__func__, wcd9xxx_core_res->num_irqs,
			wcd9xxx_core_res->num_irq_regs);

	return 0;
}
EXPORT_SYMBOL(wcd9xxx_core_res_init);

/*
 * wcd9xxx_core_res_deinit:
 *	Deinit wcd core resource instance
 *
 * @wcd9xxx_core_res: pointer to wcd core resource
 */
void wcd9xxx_core_res_deinit(struct wcd9xxx_core_resource *wcd9xxx_core_res)
{
	if (!wcd9xxx_core_res)
		return;

	pm_qos_remove_request(&wcd9xxx_core_res->pm_qos_req);
	mutex_destroy(&wcd9xxx_core_res->pm_lock);
}
EXPORT_SYMBOL(wcd9xxx_core_res_deinit);

/*
 * wcd9xxx_pm_cmpxchg:
 *	Check old state and exchange with pm new state
 *	if old state matches with current state
 *
 * @wcd9xxx_core_res: pointer to wcd core resource
 * @o: pm old state
 * @n: pm new state
 *
 * Returns old state
 */
enum wcd9xxx_pm_state wcd9xxx_pm_cmpxchg(
		struct wcd9xxx_core_resource *wcd9xxx_core_res,
		enum wcd9xxx_pm_state o,
		enum wcd9xxx_pm_state n)
{
	enum wcd9xxx_pm_state old;

	if (!wcd9xxx_core_res)
		return o;

	mutex_lock(&wcd9xxx_core_res->pm_lock);
	old = wcd9xxx_core_res->pm_state;
	if (old == o)
		wcd9xxx_core_res->pm_state = n;
	mutex_unlock(&wcd9xxx_core_res->pm_lock);

	return old;
}
EXPORT_SYMBOL(wcd9xxx_pm_cmpxchg);

/*
 * wcd9xxx_core_res_suspend:
 *	Suspend callback function for wcd9xxx core
 *
 * @wcd9xxx_core_res: pointer to wcd core resource
 * @pm_message_t: pm message
 *
 * Returns 0 for success or negative error code for failure/busy
 */
int wcd9xxx_core_res_suspend(
	struct wcd9xxx_core_resource *wcd9xxx_core_res,
	pm_message_t pmesg)
{
	int ret = 0;

	pr_debug("%s: enter\n", __func__);
	/*
	 * pm_qos_update_request() can be called after this suspend chain call
	 * started. thus suspend can be called while lock is being held
	 */
	mutex_lock(&wcd9xxx_core_res->pm_lock);
	if (wcd9xxx_core_res->pm_state == WCD9XXX_PM_SLEEPABLE) {
		pr_debug("%s: suspending system, state %d, wlock %d\n",
			 __func__, wcd9xxx_core_res->pm_state,
			 wcd9xxx_core_res->wlock_holders);
		wcd9xxx_core_res->pm_state = WCD9XXX_PM_ASLEEP;
	} else if (wcd9xxx_core_res->pm_state == WCD9XXX_PM_AWAKE) {
		/*
		 * unlock to wait for pm_state == WCD9XXX_PM_SLEEPABLE
		 * then set to WCD9XXX_PM_ASLEEP
		 */
		pr_debug("%s: waiting to suspend system, state %d, wlock %d\n",
			 __func__, wcd9xxx_core_res->pm_state,
			 wcd9xxx_core_res->wlock_holders);
		mutex_unlock(&wcd9xxx_core_res->pm_lock);
		if (!(wait_event_timeout(wcd9xxx_core_res->pm_wq,
					 wcd9xxx_pm_cmpxchg(wcd9xxx_core_res,
						  WCD9XXX_PM_SLEEPABLE,
						  WCD9XXX_PM_ASLEEP) ==
							WCD9XXX_PM_SLEEPABLE,
					 HZ))) {
			pr_debug("%s: suspend failed state %d, wlock %d\n",
				 __func__, wcd9xxx_core_res->pm_state,
				 wcd9xxx_core_res->wlock_holders);
			ret = -EBUSY;
		} else {
			pr_debug("%s: done, state %d, wlock %d\n", __func__,
				 wcd9xxx_core_res->pm_state,
				 wcd9xxx_core_res->wlock_holders);
		}
		mutex_lock(&wcd9xxx_core_res->pm_lock);
	} else if (wcd9xxx_core_res->pm_state == WCD9XXX_PM_ASLEEP) {
		pr_warn("%s: system is already suspended, state %d, wlock %dn",
			__func__, wcd9xxx_core_res->pm_state,
			wcd9xxx_core_res->wlock_holders);
	}
	mutex_unlock(&wcd9xxx_core_res->pm_lock);

	return ret;
}
EXPORT_SYMBOL(wcd9xxx_core_res_suspend);

/*
 * wcd9xxx_core_res_resume:
 *	Resume callback function for wcd9xxx core
 *
 * @wcd9xxx_core_res: pointer to wcd core resource
 *
 * Returns 0 for success or negative error code for failure/busy
 */
int wcd9xxx_core_res_resume(
	struct wcd9xxx_core_resource *wcd9xxx_core_res)
{
	int ret = 0;

	pr_debug("%s: enter\n", __func__);
	mutex_lock(&wcd9xxx_core_res->pm_lock);
	if (wcd9xxx_core_res->pm_state == WCD9XXX_PM_ASLEEP) {
		pr_debug("%s: resuming system, state %d, wlock %d\n", __func__,
				wcd9xxx_core_res->pm_state,
				wcd9xxx_core_res->wlock_holders);
		wcd9xxx_core_res->pm_state = WCD9XXX_PM_SLEEPABLE;
	} else {
		pr_warn("%s: system is already awake, state %d wlock %d\n",
				__func__, wcd9xxx_core_res->pm_state,
				wcd9xxx_core_res->wlock_holders);
	}
	mutex_unlock(&wcd9xxx_core_res->pm_lock);
	wake_up_all(&wcd9xxx_core_res->pm_wq);

	return ret;
}
EXPORT_SYMBOL(wcd9xxx_core_res_resume);

/*
 * wcd9xxx_get_intf_type:
 *	Get interface type of wcd9xxx core
 *
 * Returns interface type
 */
enum wcd9xxx_intf_status wcd9xxx_get_intf_type(void)
{
	return wcd9xxx_intf;
}
EXPORT_SYMBOL(wcd9xxx_get_intf_type);

/*
 * wcd9xxx_set_intf_type:
 *	Set interface type of wcd9xxx core
 *
 */
void wcd9xxx_set_intf_type(enum wcd9xxx_intf_status intf_status)
{
	wcd9xxx_intf = intf_status;
}
EXPORT_SYMBOL(wcd9xxx_set_intf_type);

/*
 * wcd9xxx_set_power_state: set power state for the region
 * @wcd9xxx: handle to wcd core
 * @state: power state to be set
 * @region: region index
 *
 * Returns error code in case of failure or 0 for success
 */
int wcd9xxx_set_power_state(struct wcd9xxx *wcd9xxx,
			    enum codec_power_states state,
			    enum wcd_power_regions region)
{
	if (!wcd9xxx) {
		pr_err("%s: wcd9xxx is NULL\n", __func__);
		return -EINVAL;
	}

	if ((region < 0) || (region >= WCD9XXX_MAX_PWR_REGIONS)) {
		dev_err(wcd9xxx->dev, "%s: region index %d out of bounds\n",
			__func__, region);
		return -EINVAL;
	}
	if (!wcd9xxx->wcd9xxx_pwr[region]) {
		dev_err(wcd9xxx->dev, "%s: memory not created for region: %d\n",
			__func__, region);
		return -EINVAL;
	}
	mutex_lock(&wcd9xxx->io_lock);
	wcd9xxx->wcd9xxx_pwr[region]->power_state = state;
	mutex_unlock(&wcd9xxx->io_lock);

	return 0;
}
EXPORT_SYMBOL(wcd9xxx_set_power_state);

/*
 * wcd9xxx_get_current_power_state: Get power state of the region
 * @wcd9xxx: handle to wcd core
 * @region: region index
 *
 * Returns current power state of the region or error code for failure
 */
int wcd9xxx_get_current_power_state(struct wcd9xxx *wcd9xxx,
				    enum wcd_power_regions region)
{
	int state;

	if (!wcd9xxx) {
		pr_err("%s: wcd9xxx is NULL\n", __func__);
		return -EINVAL;
	}

	if ((region < 0) || (region >= WCD9XXX_MAX_PWR_REGIONS)) {
		dev_err(wcd9xxx->dev, "%s: region index %d out of bounds\n",
			__func__, region);
		return -EINVAL;
	}
	if (!wcd9xxx->wcd9xxx_pwr[region]) {
		dev_err(wcd9xxx->dev, "%s: memory not created for region: %d\n",
			__func__, region);
		return -EINVAL;
	}

	mutex_lock(&wcd9xxx->io_lock);
	state = wcd9xxx->wcd9xxx_pwr[region]->power_state;
	mutex_unlock(&wcd9xxx->io_lock);

	return state;
}
EXPORT_SYMBOL(wcd9xxx_get_current_power_state);
