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

Commit 4894eefa authored by Phani Kumar Uppalapati's avatar Phani Kumar Uppalapati
Browse files

ASoC: wcd9xxx: Handle codec specific clock enable post ssr



Clock enablement depends on the codec type. Handle the
clock enablement after subsystem-restart depending on the
type of the codec.

Change-Id: Ic0b5504c02f816488fe2f33837200783520b6993
Signed-off-by: default avatarPhani Kumar Uppalapati <phaniu@codeaurora.org>
parent ac6fe126
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3344,7 +3344,7 @@ static int msm8x10_wcd_codec_probe(struct snd_soc_codec *codec)
	core_res = &msm8x10_wcd->wcd9xxx_res;
	ret = wcd9xxx_resmgr_init(&msm8x10_wcd_priv->resmgr,
				codec, core_res, NULL, &pdata->micbias,
				NULL, WCD9XXX_CDC_TYPE_HELICON);
				NULL, NULL, WCD9XXX_CDC_TYPE_HELICON);
	if (ret) {
		dev_err(codec->dev,
				"%s: wcd9xxx init failed %d\n",
+1 −1
Original line number Diff line number Diff line
@@ -6401,7 +6401,7 @@ static int tapan_codec_probe(struct snd_soc_codec *codec)
	pdata = dev_get_platdata(codec->dev->parent);
	ret = wcd9xxx_resmgr_init(&tapan->resmgr, codec, core_res, pdata,
				  &pdata->micbias, &tapan_reg_address,
				  WCD9XXX_CDC_TYPE_TAPAN);
				  NULL, WCD9XXX_CDC_TYPE_TAPAN);
	if (ret) {
		pr_err("%s: wcd9xxx init failed %d\n", __func__, ret);
		return ret;
+1 −1
Original line number Diff line number Diff line
@@ -7359,7 +7359,7 @@ static int taiko_codec_probe(struct snd_soc_codec *codec)
	pdata = dev_get_platdata(codec->dev->parent);
	ret = wcd9xxx_resmgr_init(&taiko->resmgr, codec, core_res, pdata,
				  &pdata->micbias, &taiko_reg_address,
				  WCD9XXX_CDC_TYPE_TAIKO);
				  NULL, WCD9XXX_CDC_TYPE_TAIKO);
	if (ret) {
		pr_err("%s: wcd9xxx init failed %d\n", __func__, ret);
		goto err_init;
+5 −1
Original line number Diff line number Diff line
@@ -8479,6 +8479,10 @@ static int tomtom_codec_vote_max_bw(struct snd_soc_codec *codec,
			bw_ops, true);
}

static const struct wcd9xxx_resmgr_cb resmgr_cb = {
	.cdc_rco_ctrl = tomtom_codec_internal_rco_ctrl,
};

static const struct wcd_cpe_cdc_cb cpe_cb = {
	.cdc_clk_en = tomtom_codec_internal_rco_ctrl,
	.cpe_clk_en = tomtom_codec_fll_enable,
@@ -8556,7 +8560,7 @@ static int tomtom_codec_probe(struct snd_soc_codec *codec)
	pdata = dev_get_platdata(codec->dev->parent);
	ret = wcd9xxx_resmgr_init(&tomtom->resmgr, codec, core_res, pdata,
				  &pdata->micbias, &tomtom_reg_address,
				  WCD9XXX_CDC_TYPE_TOMTOM);
				  &resmgr_cb, WCD9XXX_CDC_TYPE_TOMTOM);
	if (ret) {
		pr_err("%s: wcd9xxx init failed %d\n", __func__, ret);
		goto err_nomem_slimch;
+34 −2
Original line number Diff line number Diff line
@@ -234,6 +234,25 @@ static void wcd9xxx_disable_clock_block(struct wcd9xxx_resmgr *resmgr)
	pr_debug("%s: leave\n", __func__);
}

static void wcd9xxx_resmgr_cdc_specific_get_clk(struct wcd9xxx_resmgr *resmgr,
						int clk_users)
{
	/* Caller of this funcion should have acquired
	 *  BG_CLK lock
	 */
	WCD9XXX_BG_CLK_UNLOCK(resmgr);
	if (clk_users) {
		if (resmgr->resmgr_cb &&
		    resmgr->resmgr_cb->cdc_rco_ctrl) {
			while (clk_users--)
				resmgr->resmgr_cb->cdc_rco_ctrl(resmgr->codec,
								true);
		}
	}
	/* Acquire BG_CLK lock before return */
	WCD9XXX_BG_CLK_LOCK(resmgr);
}

void wcd9xxx_resmgr_post_ssr(struct wcd9xxx_resmgr *resmgr)
{
	int old_bg_audio_users, old_bg_mbhc_users;
@@ -270,9 +289,12 @@ void wcd9xxx_resmgr_post_ssr(struct wcd9xxx_resmgr *resmgr)
			wcd9xxx_resmgr_get_clk_block(resmgr, WCD9XXX_CLK_MCLK);
	}

	if (old_clk_rco_users) {
	if (resmgr->codec_type == WCD9XXX_CDC_TYPE_TOMTOM) {
		wcd9xxx_resmgr_cdc_specific_get_clk(resmgr, old_clk_rco_users);
	} else if (old_clk_rco_users) {
		while (old_clk_rco_users--)
			wcd9xxx_resmgr_get_clk_block(resmgr, WCD9XXX_CLK_RCO);
			wcd9xxx_resmgr_get_clk_block(resmgr,
					WCD9XXX_CLK_RCO);
	}
	WCD9XXX_BG_CLK_UNLOCK(resmgr);
	pr_debug("%s: leave\n", __func__);
@@ -645,6 +667,8 @@ void wcd9xxx_resmgr_get_clk_block(struct wcd9xxx_resmgr *resmgr,
			   resmgr->clk_type == WCD9XXX_CLK_RCO) {
			/* RCO to MCLK switch, with RCO still powered on */
			if (resmgr->codec_type == WCD9XXX_CDC_TYPE_TOMTOM) {
				wcd9xxx_resmgr_notifier_call(resmgr,
						WCD9XXX_EVENT_PRE_MCLK_ON);
				snd_soc_update_bits(codec,
						WCD9XXX_A_BIAS_CENTRAL_BG_CTL,
						0x40, 0x00);
@@ -655,6 +679,8 @@ void wcd9xxx_resmgr_get_clk_block(struct wcd9xxx_resmgr *resmgr,
				snd_soc_update_bits(codec,
						WCD9XXX_A_CLK_BUFF_EN1,
						0x08, 0x00);
				wcd9xxx_resmgr_notifier_call(resmgr,
						WCD9XXX_EVENT_POST_MCLK_ON);
			} else {
				/* if RCO is enabled, switch from it */
				WARN_ON(!(snd_soc_read(resmgr->codec,
@@ -741,12 +767,16 @@ void wcd9xxx_resmgr_put_clk_block(struct wcd9xxx_resmgr *resmgr,
							WCD9XXX_A_CLK_BUFF_EN1,
							0x01, 0x00);
				} else {
					wcd9xxx_resmgr_notifier_call(resmgr,
						WCD9XXX_EVENT_PRE_MCLK_OFF);
					snd_soc_update_bits(codec,
							WCD9XXX_A_CLK_BUFF_EN1,
							0x08, 0x08);
					snd_soc_update_bits(codec,
							WCD9XXX_A_CLK_BUFF_EN1,
							0x01, 0x00);
					wcd9xxx_resmgr_notifier_call(resmgr,
						WCD9XXX_EVENT_POST_MCLK_OFF);
				}
			} else {
				/* disable clock */
@@ -1034,6 +1064,7 @@ int wcd9xxx_resmgr_init(struct wcd9xxx_resmgr *resmgr,
			struct wcd9xxx_pdata *pdata,
			struct wcd9xxx_micbias_setting *micbias_pdata,
			struct wcd9xxx_reg_address *reg_addr,
			const struct wcd9xxx_resmgr_cb *resmgr_cb,
			enum wcd9xxx_cdc_type cdc_type)
{
	WARN(ARRAY_SIZE(wcd9xxx_event_string) != WCD9XXX_EVENT_LAST + 1,
@@ -1048,6 +1079,7 @@ int wcd9xxx_resmgr_init(struct wcd9xxx_resmgr *resmgr,
	resmgr->pdata = pdata;
	resmgr->micbias_pdata = micbias_pdata;
	resmgr->reg_addr = reg_addr;
	resmgr->resmgr_cb = resmgr_cb;

	INIT_LIST_HEAD(&resmgr->update_bit_cond_h);

Loading