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

Commit 929a19d9 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: Correct RCO enable and disable sequence"

parents c2bca4c2 d3a13144
Loading
Loading
Loading
Loading
+57 −25
Original line number Diff line number Diff line
@@ -153,6 +153,13 @@ static struct afe_param_id_cdc_aanc_version tapan_cdc_aanc_version = {
	.aanc_hw_version        = AANC_HW_BLOCK_VERSION_2,
};

enum tapan_codec_type {
	WCD9306,
	WCD9302,
};

static enum tapan_codec_type codec_ver;

enum {
	AIF1_PB = 0,
	AIF1_CAP,
@@ -5455,7 +5462,25 @@ static void tapan_enable_config_rco(struct wcd9xxx *core, bool enable)
	struct wcd9xxx_core_resource *core_res = &core->core_res;

	if (enable) {
		/* Enable RC Oscillator */
		/*
		 * Enable Bandgap
		 * sleep required by codec hardware to enable bandgap
		 */
		wcd9xxx_reg_update(core, WCD9XXX_A_BIAS_CENTRAL_BG_CTL,
				   0x80, 0x80);
		wcd9xxx_reg_update(core, WCD9XXX_A_BIAS_CENTRAL_BG_CTL,
				   0x04, 0x04);
		wcd9xxx_reg_update(core, WCD9XXX_A_BIAS_CENTRAL_BG_CTL,
				   0x01, 0x01);
		usleep_range(1000, 1100);
		wcd9xxx_reg_update(core, WCD9XXX_A_BIAS_CENTRAL_BG_CTL,
				   0x80, 0x00);

		/*
		 * Enable RC Oscillator
		 * Add sleep required by codec hardware after each register
		 * write to enable RC oscillator
		 */
		wcd9xxx_reg_update(core, WCD9XXX_A_RC_OSC_FREQ, 0x10, 0x00);
		wcd9xxx_reg_write(core_res, WCD9XXX_A_BIAS_OSC_BG_CTL, 0x17);
		usleep_range(5, 5);
@@ -5481,29 +5506,39 @@ static void tapan_enable_config_rco(struct wcd9xxx *core, bool enable)
		/*
		 * Disable RC oscillator, reset the registers to their
		 * default values
		 * Add sleep required by codec hardware after each register
		 * write to disable RC oscillator
		 */
		wcd9xxx_reg_write(core_res, WCD9XXX_A_CDC_CLK_MCLK_CTL, 0x00);
		wcd9xxx_reg_write(core_res, WCD9XXX_A_CLK_BUFF_EN2, 0x02);
		wcd9xxx_reg_write(core_res, WCD9XXX_A_CLK_BUFF_EN1, 0x04);
		wcd9xxx_reg_write(core_res, WCD9XXX_A_RC_OSC_TEST, 0x0A);
		wcd9xxx_reg_write(core_res, WCD9XXX_A_RC_OSC_FREQ, 0x46);
		wcd9xxx_reg_update(core, WCD9XXX_A_CLK_BUFF_EN2, 0x04, 0x00);
		usleep_range(50, 100);
		wcd9xxx_reg_update(core, WCD9XXX_A_CLK_BUFF_EN2, 0x02, 0x02);
		wcd9xxx_reg_update(core, WCD9XXX_A_CLK_BUFF_EN1, 0x05, 0x00);
		usleep_range(50, 100);

		wcd9xxx_reg_update(core, WCD9XXX_A_RC_OSC_FREQ, 0x80, 0x00);
		usleep_range(10, 50);
		wcd9xxx_reg_write(core_res, WCD9XXX_A_BIAS_OSC_BG_CTL, 0x16);
		/* Disable Bandgap and wait 100us till it gets disabled */
		wcd9xxx_reg_update(core, WCD9XXX_A_BIAS_CENTRAL_BG_CTL,
				   0x03, 0x00);
		usleep_range(100, 150);
	}

}

static bool tapan_check_wcd9306(struct device *cdc_dev, bool sensed)
static enum tapan_codec_type tapan_get_codec_ver(struct device *cdc_dev,
						 bool sensed)
{
	struct wcd9xxx *core = dev_get_drvdata(cdc_dev->parent);
	u8 reg_val;
	bool ret = true;
	enum tapan_codec_type cdc_type = WCD9306;
	unsigned long timeout;
	bool timedout;
	struct wcd9xxx_core_resource *core_res = &core->core_res;

	if (!core) {
		dev_err(cdc_dev, "%s: core not initialized\n", __func__);
		return -EINVAL;
		return cdc_type;
	}

	tapan_enable_config_rco(core, 1);
@@ -5523,12 +5558,13 @@ static bool tapan_check_wcd9306(struct device *cdc_dev, bool sensed)
	if (wcd9xxx_reg_read(core_res, TAPAN_A_QFUSE_DATA_OUT1) ||
	    wcd9xxx_reg_read(core_res, TAPAN_A_QFUSE_DATA_OUT2)) {
		dev_info(cdc_dev, "%s: wcd9302 detected\n", __func__);
		ret = false;
		cdc_type = WCD9302;
	} else
		dev_info(cdc_dev, "%s: wcd9306 detected\n", __func__);

	tapan_enable_config_rco(core, 0);
	return ret;

	return cdc_type;
};

static int tapan_codec_probe(struct snd_soc_codec *codec)
@@ -5653,7 +5689,7 @@ static int tapan_codec_probe(struct snd_soc_codec *codec)
		tapan_init_slim_slave_cfg(codec);
	}

	if (tapan_check_wcd9306(codec->dev, false) == true) {
	if (codec_ver == WCD9306) {
		snd_soc_add_codec_controls(codec, tapan_9306_snd_controls,
					   ARRAY_SIZE(tapan_9306_snd_controls));
		snd_soc_dapm_new_controls(dapm, tapan_9306_dapm_widgets,
@@ -5678,11 +5714,13 @@ static int tapan_codec_probe(struct snd_soc_codec *codec)

	atomic_set(&kp_tapan_priv, (unsigned long)tapan);
	mutex_lock(&dapm->codec->mutex);
	if (codec_ver == WCD9306) {
		snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
		snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
		snd_soc_dapm_disable_pin(dapm, "ANC HEADPHONE");
		snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
		snd_soc_dapm_disable_pin(dapm, "ANC EAR");
	}
	snd_soc_dapm_sync(dapm);
	mutex_unlock(&dapm->codec->mutex);

@@ -5775,16 +5813,10 @@ static const struct dev_pm_ops tapan_pm_ops = {
static int tapan_probe(struct platform_device *pdev)
{
	int ret = 0;
	bool is_wcd9306;

	is_wcd9306 = tapan_check_wcd9306(&pdev->dev, false);
	if (is_wcd9306 < 0) {
		dev_info(&pdev->dev, "%s: cannot find codec type, default to 9306\n",
			 __func__);
		is_wcd9306 = true;
	}
	codec_ver = tapan_get_codec_ver(&pdev->dev, false);

	if (!is_wcd9306) {
	if (codec_ver == WCD9302) {
		if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
			ret = snd_soc_register_codec(&pdev->dev,
				&soc_codec_dev_tapan,