// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 */

#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_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;
	}

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

	pdata->has_micb_supply_en_gpio = of_property_read_bool(dev->of_node,
					   "qcom,has-micbias-supply-en-gpio");
	if (pdata->has_micb_supply_en_gpio) {
		pdata->micb_en_ctl = of_parse_phandle(dev->of_node,
				"qcom,micbias-supply-en-gpio-node", 0);
		if (!pdata->micb_en_ctl) {
			dev_err(dev, "%s No entry for %s property in node %s\n",
				__func__, "qcom,micbias-supply-en-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_debug("%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);
