/* Copyright (c) 2016-2018, 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 "core.h"
#include "msm-cdc-supply.h"
#include "msm-cdc-pinctrl.h"
#include "pdata.h"
#include "wcd9xxx-irq.h"
#include "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_info(dev, "%s: no power supplies defined for codec\n",
			__func__);
	}

	/* 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;
	}

	pdata->has_buck_vsel_gpio = of_property_read_bool(dev->of_node,
						"qcom,has-buck-vsel-gpio");
	if (pdata->has_buck_vsel_gpio) {
		pdata->buck_vsel_ctl_np = of_parse_phandle(dev->of_node,
				"qcom,buck-vsel-gpio-node", 0);
		if (!pdata->buck_vsel_ctl_np) {
			dev_err(dev, "%s No entry for %s property in node %s\n",
				__func__, "qcom,buck-vsel-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;
	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);
