Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 20cd96d6 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: wcd9xxx: Use common functionality to change micbias voltage"

parents 9c0b0596 13e4ea85
Loading
Loading
Loading
Loading
+69 −16
Original line number Diff line number Diff line
@@ -208,7 +208,7 @@ static int msm8x10_wcd_dt_parse_vreg_info(struct device *dev,
	struct msm8x10_wcd_regulator *vreg,
	const char *vreg_name, bool ondemand);
static int msm8x10_wcd_dt_parse_micbias_info(struct device *dev,
	struct msm8x10_wcd_micbias_setting *micbias);
	struct wcd9xxx_micbias_setting *micbias);
static struct msm8x10_wcd_pdata *msm8x10_wcd_populate_dt_pdata(
	struct device *dev);

@@ -625,12 +625,23 @@ static int msm8x10_wcd_dt_parse_vreg_info(struct device *dev,
}

static int msm8x10_wcd_dt_parse_micbias_info(struct device *dev,
	struct msm8x10_wcd_micbias_setting *micbias)
	struct wcd9xxx_micbias_setting *micbias)
{
	int ret = 0;
	char prop_name[CODEC_DT_MAX_PROP_SIZE];
	u32 prop_val;

	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
		 "qcom,cdc-micbias-ldoh-v");
	ret = of_property_read_u32(dev->of_node, prop_name,
				   &prop_val);
	if (ret) {
		dev_err(dev, "Looking up %s property in node %s failed",
			prop_name, dev->of_node->full_name);
		return -ENODEV;
	}
	micbias->ldoh_v = (u8) prop_val;

	snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
		 "qcom,cdc-micbias-cfilt-mv");
	ret = of_property_read_u32(dev->of_node, prop_name,
@@ -2531,7 +2542,7 @@ static const struct msm8x10_wcd_reg_mask_val msm8x10_wcd_reg_defaults[] = {

	/* Disable internal biasing path which can cause leakage */
	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_BIAS_CURR_CTL_2, 0x04),
	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_MICB_CFILT_1_VAL, 0x60),

	/* Enable pulldown to reduce leakage */
	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_MICB_1_CTL, 0x82),
	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_TX_COM_BIAS, 0xE0),
@@ -3061,6 +3072,41 @@ static const struct wcd9xxx_mbhc_intr cdc_intr_ids = {
	.hs_jack_switch = MSM8X10_WCD_IRQ_MBHC_HS_DET,
};

static int msm8x10_wcd_handle_pdata(struct snd_soc_codec *codec,
	struct msm8x10_wcd_pdata *pdata)
{
	int k1, rc = 0;
	struct msm8x10_wcd_priv *msm8x10_wcd_priv;

	msm8x10_wcd_priv = snd_soc_codec_get_drvdata(codec);

	/* Make sure settings are correct */
	if (pdata->micbias.ldoh_v > WCD9XXX_LDOH_3P0_V ||
	    pdata->micbias.bias1_cfilt_sel > WCD9XXX_CFILT1_SEL) {
		rc = -EINVAL;
		goto done;
	}

	/* figure out k value */
	k1 = wcd9xxx_resmgr_get_k_val(&msm8x10_wcd_priv->resmgr,
				 pdata->micbias.cfilt1_mv);
	if (IS_ERR_VALUE(k1)) {
		rc = -EINVAL;
		goto done;
	}

	/* Set voltage level */
	snd_soc_update_bits(codec, MSM8X10_WCD_A_MICB_CFILT_1_VAL,
			    0xFC, (k1 << 2));

	/* update micbias capless mode */
	snd_soc_update_bits(codec, MSM8X10_WCD_A_MICB_1_CTL, 0x10,
			    pdata->micbias.bias1_cap_mode << 4);

done:
	return rc;
}

static int msm8x10_wcd_codec_probe(struct snd_soc_codec *codec)
{
	struct msm8x10_wcd_priv *msm8x10_wcd_priv;
@@ -3097,12 +3143,18 @@ static int msm8x10_wcd_codec_probe(struct snd_soc_codec *codec)
	INIT_DELAYED_WORK(&msm8x10_wcd_priv->hs_detect_work,
			delayed_hs_detect_fn);

	pdata = dev_get_platdata(msm8x10_wcd->dev);
	if (!pdata) {
		dev_err(msm8x10_wcd->dev, "%s: platform data not found\n",
			__func__);
	}

	/* codec resmgr module init */
	msm8x10_wcd = codec->control_data;
	core_res = &msm8x10_wcd->wcd9xxx_res;
	ret = wcd9xxx_resmgr_init(&msm8x10_wcd_priv->resmgr,
				codec, core_res, NULL, NULL,
				WCD9XXX_CDC_TYPE_HELICON);
				codec, core_res, NULL, &pdata->micbias,
				NULL, WCD9XXX_CDC_TYPE_HELICON);
	if (ret) {
		dev_err(codec->dev,
				"%s: wcd9xxx init failed %d\n",
@@ -3114,16 +3166,6 @@ static int msm8x10_wcd_codec_probe(struct snd_soc_codec *codec)
	msm8x10_wcd_codec_init_reg(codec);
	msm8x10_wcd_update_reg_defaults(codec);

	pdata = dev_get_platdata(msm8x10_wcd->dev);
	if (!pdata) {
		dev_err(msm8x10_wcd->dev, "%s: platform data not found\n",
			__func__);
	}

	/* update micbias capless mode */
	snd_soc_update_bits(codec, MSM8X10_WCD_A_MICB_1_CTL, 0x10,
			    pdata->micbias.bias1_cap_mode << 4);

	msm8x10_wcd_priv->on_demand_list[ON_DEMAND_CP].supply =
				wcd8x10_wcd_codec_find_regulator(
				codec->control_data,
@@ -3140,10 +3182,16 @@ static int msm8x10_wcd_codec_probe(struct snd_soc_codec *codec)
				codec, NULL, &mbhc_cb, &cdc_intr_ids,
				HELICON_MCLK_CLK_9P6MHZ, true);
	if (ret) {
		pr_err("%s: Failed to initialize mbhc\n", __func__);
		dev_err(msm8x10_wcd->dev, "%s: Failed to initialize mbhc\n",
			__func__);
		goto exit_probe;
	}

	/* Handle the Pdata */
	ret = msm8x10_wcd_handle_pdata(codec, pdata);
	if (IS_ERR_VALUE(ret))
		dev_err(msm8x10_wcd->dev, "%s: Bad Pdata\n", __func__);

	registered_codec = codec;
	adsp_state_notifier =
	    subsys_notif_register_notifier("adsp",
@@ -3448,6 +3496,11 @@ static int msm8x10_wcd_i2c_probe(struct i2c_client *client,
		dev_dbg(&client->dev, "%s:Platform data from device tree\n",
			__func__);
		pdata = msm8x10_wcd_populate_dt_pdata(&client->dev);
		if (!pdata) {
			dev_err(&client->dev, "%s: Failed to parse pdata from device tree\n",
				__func__);
			goto rtn;
		}
		client->dev.platform_data = pdata;
	} else {
		dev_dbg(&client->dev, "%s:Platform data from board file\n",
+2 −23
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <sound/jack.h>
#include "wcd9xxx-mbhc.h"
#include "wcd9xxx-resmgr.h"
#include <linux/mfd/wcd9xxx/pdata.h>

#define MSM8X10_WCD_NUM_REGISTERS	0x600
#define MSM8X10_WCD_MAX_REGISTER	(MSM8X10_WCD_NUM_REGISTERS-1)
@@ -113,28 +114,6 @@ enum {
	MSM8X10_WCD_NUM_IRQS,
};

/*
 * Each micbias can be assigned to one of three cfilters
 * Vbatt_min >= .15V + ldoh_v
 * ldoh_v >= .15v + cfiltx_mv
 * If ldoh_v = 1.95 160 mv < cfiltx_mv < 1800 mv
 * If ldoh_v = 2.35 200 mv < cfiltx_mv < 2200 mv
 * If ldoh_v = 2.75 240 mv < cfiltx_mv < 2600 mv
 * If ldoh_v = 2.85 250 mv < cfiltx_mv < 2700 mv
 */
struct msm8x10_wcd_micbias_setting {
	u8 ldoh_v;
	u32 cfilt1_mv; /* in mv */
	/*
	 * Different WCD9xxx series codecs may not
	 * have 4 mic biases. If a codec has fewer
	 * mic biases, some of these properties will
	 * not be used.
	 */
	u8 bias1_cfilt_sel;
	u8 bias1_cap_mode;
};

struct msm8x10_wcd_ocp_setting {
	unsigned int	use_pdata:1; /* 0 - use sys default as recommended */
	unsigned int	num_attempts:4; /* up to 15 attempts */
@@ -158,7 +137,7 @@ struct msm8x10_wcd_pdata {
	int num_irqs;
	int reset_gpio;
	void *msm8x10_wcd_ahb_base_vaddr;
	struct msm8x10_wcd_micbias_setting micbias;
	struct wcd9xxx_micbias_setting micbias;
	struct msm8x10_wcd_ocp_setting ocp;
	struct msm8x10_wcd_regulator regulator[MAX_REGULATOR];
	u32 mclk_rate;
+2 −1
Original line number Diff line number Diff line
@@ -5709,7 +5709,8 @@ static int tapan_codec_probe(struct snd_soc_codec *codec)
	core_res = &wcd9xxx->core_res;
	pdata = dev_get_platdata(codec->dev->parent);
	ret = wcd9xxx_resmgr_init(&tapan->resmgr, codec, core_res, pdata,
				  &tapan_reg_address, WCD9XXX_CDC_TYPE_TAPAN);
				  &pdata->micbias, &tapan_reg_address,
				  WCD9XXX_CDC_TYPE_TAPAN);
	if (ret) {
		pr_err("%s: wcd9xxx init failed %d\n", __func__, ret);
		return ret;
+2 −1
Original line number Diff line number Diff line
@@ -6766,7 +6766,8 @@ static int taiko_codec_probe(struct snd_soc_codec *codec)
	core_res = &wcd9xxx->core_res;
	pdata = dev_get_platdata(codec->dev->parent);
	ret = wcd9xxx_resmgr_init(&taiko->resmgr, codec, core_res, pdata,
				  &taiko_reg_address, WCD9XXX_CDC_TYPE_TAIKO);
				  &pdata->micbias, &taiko_reg_address,
				  WCD9XXX_CDC_TYPE_TAIKO);
	if (ret) {
		pr_err("%s: wcd9xxx init failed %d\n", __func__, ret);
		goto err_init;
+15 −33
Original line number Diff line number Diff line
@@ -263,11 +263,6 @@ static void wcd9xxx_start_hs_polling(struct wcd9xxx_mbhc *mbhc)
static int __wcd9xxx_resmgr_get_k_val(struct wcd9xxx_mbhc *mbhc,
		unsigned int cfilt_mv)
{
	if (mbhc->mbhc_cb &&
			mbhc->mbhc_cb->get_cdc_type() ==
					WCD9XXX_CDC_TYPE_HELICON)
		return 0x18;

	return wcd9xxx_resmgr_get_k_val(mbhc->resmgr, cfilt_mv);
}

@@ -592,41 +587,30 @@ static void wcd9xxx_get_mbhc_micbias_regs(struct wcd9xxx_mbhc *mbhc,
					struct mbhc_micbias_regs *micbias_regs)
{
	unsigned int cfilt;
	struct wcd9xxx_pdata *pdata = mbhc->resmgr->pdata;

	if (mbhc->mbhc_cb &&
			mbhc->mbhc_cb->get_cdc_type() ==
					WCD9XXX_CDC_TYPE_HELICON) {
		micbias_regs->mbhc_reg = WCD9XXX_A_MICB_1_MBHC;
		micbias_regs->int_rbias = WCD9XXX_A_MICB_1_INT_RBIAS;
		micbias_regs->ctl_reg = WCD9XXX_A_MICB_1_CTL;
		micbias_regs->cfilt_val = WCD9XXX_A_MICB_CFILT_1_VAL;
		micbias_regs->cfilt_ctl = WCD9XXX_A_MICB_CFILT_1_CTL;
		mbhc->mbhc_data.micb_mv = 1800;
		return;
	}
	struct wcd9xxx_micbias_setting *micbias_pdata =
		mbhc->resmgr->micbias_pdata;

	switch (mbhc->mbhc_cfg->micbias) {
	case MBHC_MICBIAS1:
		cfilt = pdata->micbias.bias1_cfilt_sel;
		cfilt = micbias_pdata->bias1_cfilt_sel;
		micbias_regs->mbhc_reg = WCD9XXX_A_MICB_1_MBHC;
		micbias_regs->int_rbias = WCD9XXX_A_MICB_1_INT_RBIAS;
		micbias_regs->ctl_reg = WCD9XXX_A_MICB_1_CTL;
		break;
	case MBHC_MICBIAS2:
		cfilt = pdata->micbias.bias2_cfilt_sel;
		cfilt = micbias_pdata->bias2_cfilt_sel;
		micbias_regs->mbhc_reg = WCD9XXX_A_MICB_2_MBHC;
		micbias_regs->int_rbias = WCD9XXX_A_MICB_2_INT_RBIAS;
		micbias_regs->ctl_reg = WCD9XXX_A_MICB_2_CTL;
		break;
	case MBHC_MICBIAS3:
		cfilt = pdata->micbias.bias3_cfilt_sel;
		cfilt = micbias_pdata->bias3_cfilt_sel;
		micbias_regs->mbhc_reg = WCD9XXX_A_MICB_3_MBHC;
		micbias_regs->int_rbias = WCD9XXX_A_MICB_3_INT_RBIAS;
		micbias_regs->ctl_reg = WCD9XXX_A_MICB_3_CTL;
		break;
	case MBHC_MICBIAS4:
		cfilt = pdata->micbias.bias4_cfilt_sel;
		cfilt = micbias_pdata->bias4_cfilt_sel;
		micbias_regs->mbhc_reg = mbhc->resmgr->reg_addr->micb_4_mbhc;
		micbias_regs->int_rbias =
		    mbhc->resmgr->reg_addr->micb_4_int_rbias;
@@ -644,20 +628,17 @@ static void wcd9xxx_get_mbhc_micbias_regs(struct wcd9xxx_mbhc *mbhc,
	case WCD9XXX_CFILT1_SEL:
		micbias_regs->cfilt_val = WCD9XXX_A_MICB_CFILT_1_VAL;
		micbias_regs->cfilt_ctl = WCD9XXX_A_MICB_CFILT_1_CTL;
		mbhc->mbhc_data.micb_mv =
		    mbhc->resmgr->pdata->micbias.cfilt1_mv;
		mbhc->mbhc_data.micb_mv = micbias_pdata->cfilt1_mv;
		break;
	case WCD9XXX_CFILT2_SEL:
		micbias_regs->cfilt_val = WCD9XXX_A_MICB_CFILT_2_VAL;
		micbias_regs->cfilt_ctl = WCD9XXX_A_MICB_CFILT_2_CTL;
		mbhc->mbhc_data.micb_mv =
		    mbhc->resmgr->pdata->micbias.cfilt2_mv;
		mbhc->mbhc_data.micb_mv = micbias_pdata->cfilt2_mv;
		break;
	case WCD9XXX_CFILT3_SEL:
		micbias_regs->cfilt_val = WCD9XXX_A_MICB_CFILT_3_VAL;
		micbias_regs->cfilt_ctl = WCD9XXX_A_MICB_CFILT_3_CTL;
		mbhc->mbhc_data.micb_mv =
		    mbhc->resmgr->pdata->micbias.cfilt3_mv;
		mbhc->mbhc_data.micb_mv = micbias_pdata->cfilt3_mv;
		break;
	}
}
@@ -4115,20 +4096,21 @@ static int wcd9xxx_event_to_cfilt(const enum wcd9xxx_notify_event event)
static int wcd9xxx_get_mbhc_cfilt_sel(struct wcd9xxx_mbhc *mbhc)
{
	int cfilt;
	const struct wcd9xxx_pdata *pdata = mbhc->resmgr->pdata;
	const struct wcd9xxx_micbias_setting *mb_pdata =
		mbhc->resmgr->micbias_pdata;

	switch (mbhc->mbhc_cfg->micbias) {
	case MBHC_MICBIAS1:
		cfilt = pdata->micbias.bias1_cfilt_sel;
		cfilt = mb_pdata->bias1_cfilt_sel;
		break;
	case MBHC_MICBIAS2:
		cfilt = pdata->micbias.bias2_cfilt_sel;
		cfilt = mb_pdata->bias2_cfilt_sel;
		break;
	case MBHC_MICBIAS3:
		cfilt = pdata->micbias.bias3_cfilt_sel;
		cfilt = mb_pdata->bias3_cfilt_sel;
		break;
	case MBHC_MICBIAS4:
		cfilt = pdata->micbias.bias4_cfilt_sel;
		cfilt = mb_pdata->bias4_cfilt_sel;
		break;
	default:
		cfilt = MBHC_MICBIAS_INVALID;
Loading