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

Commit 5e413877 authored by Bala Kishore Pati's avatar Bala Kishore Pati
Browse files

ASoC: bg: avoid delay while passing init params



Schedule cal init workqueue to open bg codec
channel and pass BG init params. This helps to
avoid delay during resume and recovery from BG SSR.

Change-Id: Ib68f2e21b2a5727b71046c936c938c0017e9bf2b
Signed-off-by: default avatarBala Kishore Pati <balakishorepati@codeaurora.org>
parent 70e75ca4
Loading
Loading
Loading
Loading
+60 −92
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ struct bg_cdc_priv {
	bool bg_spk_connected;
	struct regulator *spkr_vreg;
	uint16_t num_sessions;
	uint16_t bg_cal_init_delay;
};

struct codec_ssn_rt_setup_t {
@@ -295,6 +296,8 @@ static void bg_cdc_cal_init(struct work_struct *work)
{
	struct bg_cdc_priv *bg_cdc;
	struct delayed_work *dwork;
	struct bg_hw_params hw_params;
	struct pktzr_cmd_rsp rsp;
	int ret = 0;

	dwork = to_delayed_work(work);
@@ -306,17 +309,48 @@ static void bg_cdc_cal_init(struct work_struct *work)
		if (ret < 0) {
			pr_err("%s: enable_regulator failed %d\n", __func__,
				ret);
		} else {
				goto err;
		}
		/* Send open command */
		rsp.buf_size = sizeof(struct graphite_basic_rsp_result);
		rsp.buf = kzalloc(rsp.buf_size, GFP_KERNEL);
		if (!rsp.buf)
			goto err2;
		memcpy(&hw_params, &bg_cdc->hw_params, sizeof(hw_params));
		/* Send command to BG to start session */
		ret = pktzr_cmd_open(&hw_params, sizeof(hw_params), &rsp);
		if (ret < 0) {
			pr_err("%s: pktzr cmd open failed\n", __func__);
			goto err1;
		}
		ret = bg_cdc_cal(bg_cdc);
		if (ret < 0) {
				bg_cdc_enable_regulator(bg_cdc->spkr_vreg,
							false);
				pr_err("%s: failed to send cal data\n",
					__func__);
			pr_err("%s: calibiration failed\n", __func__);
			goto err1;
		}
		kfree(rsp.buf);
	}
	if (!(snd_card_is_online_state
		(bg_cdc->codec->component.card->snd_card)) &&
		(bg_cdc->adsp_dev_up)) {
		snd_soc_card_change_online_state(bg_cdc->codec->component.card,
						 1);
	}
	mutex_unlock(&bg_cdc->bg_cdc_lock);
	return;
err1:
	kfree(rsp.buf);
err2:
	bg_cdc_enable_regulator(bg_cdc->spkr_vreg, false);
err:
	if (!(snd_card_is_online_state
		(bg_cdc->codec->component.card->snd_card)) &&
		(bg_cdc->adsp_dev_up)) {
		snd_soc_card_change_online_state(bg_cdc->codec->component.card,
						 1);
	}
	mutex_unlock(&bg_cdc->bg_cdc_lock);
	return;
}

static int _bg_codec_hw_params(struct bg_cdc_priv *bg_cdc)
@@ -325,6 +359,8 @@ static int _bg_codec_hw_params(struct bg_cdc_priv *bg_cdc)
	struct pktzr_cmd_rsp rsp;
	int ret = 0;

	if (delayed_work_pending(&bg_cdc->bg_cdc_cal_init_work))
		cancel_delayed_work_sync(&bg_cdc->bg_cdc_cal_init_work);
	mutex_lock(&bg_cdc->bg_cdc_lock);
	if (!bg_cdc->bg_cal_updated) {
		ret = bg_cdc_enable_regulator(bg_cdc->spkr_vreg, true);
@@ -876,8 +912,6 @@ static void bg_cdc_pktzr_init(struct work_struct *work)
	struct bg_glink_ch_cfg ch_info[1] = {
		{"CODEC_CHANNEL", num_of_intents, &size}
	};
	struct bg_hw_params hw_params;
	struct pktzr_cmd_rsp rsp;

	pr_debug("%s\n", __func__);
	dwork = to_delayed_work(work);
@@ -889,65 +923,24 @@ static void bg_cdc_pktzr_init(struct work_struct *work)
		dev_err(bg_cdc->dev, "%s: failed in pktzr_init\n", __func__);
		return;
	}

	/* Send open command */
	rsp.buf_size = sizeof(struct graphite_basic_rsp_result);
	rsp.buf = kzalloc(rsp.buf_size, GFP_KERNEL);
	if (!rsp.buf)
		return;
	memcpy(&hw_params, &bg_cdc->hw_params, sizeof(hw_params));
	/* Send command to BG to start session */
	ret = pktzr_cmd_open(&hw_params, sizeof(hw_params), &rsp);
	if (ret < 0)
		pr_err("pktzr cmd open failed\n");

	if (rsp.buf)
		kzfree(rsp.buf);
	schedule_delayed_work(&bg_cdc->bg_cdc_cal_init_work,
			      msecs_to_jiffies(5000));
			      msecs_to_jiffies(bg_cdc->bg_cal_init_delay));
	bg_cdc->bg_cal_init_delay = 0;
}

static int bg_cdc_bg_device_up(struct bg_cdc_priv *bg_cdc)
{
	struct bg_hw_params hw_params;
	struct pktzr_cmd_rsp rsp;
	int num_of_intents = 1;
	uint32_t size = 4096;
	int ret = 0;
	struct bg_glink_ch_cfg ch_info[1] = {
		{"CODEC_CHANNEL", num_of_intents, &size}
	};
	mutex_lock(&bg_cdc->bg_cdc_lock);
	if (!bg_cdc->bg_cal_updated) {
		bg_cdc_enable_regulator(bg_cdc->spkr_vreg, true);
		ret = pktzr_init(bg_cdc->pdev_child, ch_info, 1, data_cmd_rsp);
		if (ret < 0) {
			dev_err(bg_cdc->dev, "%s: failed in pktzr_init\n",
				__func__);
		}
		/* Send open command */
		rsp.buf_size = sizeof(struct graphite_basic_rsp_result);
		rsp.buf = kzalloc(rsp.buf_size, GFP_KERNEL);
		memcpy(&hw_params, &bg_cdc->hw_params, sizeof(hw_params));
		/* Send command to BG to start session */
		ret = pktzr_cmd_open(&hw_params, sizeof(hw_params), &rsp);
		if (ret < 0)
			pr_err("pktzr cmd open failed\n");
		if (rsp.buf)
			kzfree(rsp.buf);
		bg_cdc_cal(bg_cdc);
	}
	if ((!bg_cdc->bg_dev_up) && (bg_cdc->adsp_dev_up))
		snd_soc_card_change_online_state(bg_cdc->codec->component.card,
						 1);
	mutex_unlock(&bg_cdc->bg_cdc_lock);
	schedule_delayed_work(&bg_cdc->bg_cdc_pktzr_init_work,
			msecs_to_jiffies(0));
	return 0;
}

static int bg_cdc_bg_device_down(struct bg_cdc_priv *bg_cdc)
{
	pktzr_deinit();
	cancel_delayed_work_sync(&bg_cdc->bg_cdc_pktzr_init_work);
	cancel_delayed_work_sync(&bg_cdc->bg_cdc_cal_init_work);
	mutex_lock(&bg_cdc->bg_cdc_lock);
	pktzr_deinit();
	if (bg_cdc->bg_cal_updated) {
		bg_cdc_enable_regulator(bg_cdc->spkr_vreg, false);
		bg_cdc->bg_cal_updated = false;
@@ -977,7 +970,7 @@ static int bg_cdc_adsp_device_up(struct bg_cdc_priv *bg_cdc)
	} else
		dev_err(bg_cdc->dev, "%s:ADSP is ready\n", __func__);

	if ((!bg_cdc->adsp_dev_up) && (bg_cdc->bg_dev_up))
	if (bg_cdc->bg_dev_up)
		snd_soc_card_change_online_state(bg_cdc->codec->component.card,
						 1);
	mutex_unlock(&bg_cdc->bg_cdc_lock);
@@ -1099,6 +1092,10 @@ static int bg_cdc_pm_suspend(struct bg_cdc_priv *bg_cdc)
		pr_debug("audio session in progress don't devote\n");
		return 0;
	}
	if (delayed_work_pending(&bg_cdc->bg_cdc_pktzr_init_work))
		cancel_delayed_work_sync(&bg_cdc->bg_cdc_pktzr_init_work);
	if (delayed_work_pending(&bg_cdc->bg_cdc_cal_init_work))
		cancel_delayed_work_sync(&bg_cdc->bg_cdc_cal_init_work);
	if (bg_cdc->bg_cal_updated) {
		bg_cdc_enable_regulator(bg_cdc->spkr_vreg, false);
		bg_cdc->bg_cal_updated = false;
@@ -1108,39 +1105,8 @@ static int bg_cdc_pm_suspend(struct bg_cdc_priv *bg_cdc)

static int bg_cdc_pm_resume(struct bg_cdc_priv *bg_cdc)
{
	struct bg_hw_params hw_params;
	struct pktzr_cmd_rsp rsp;
	int ret = 0;

	mutex_lock(&bg_cdc->bg_cdc_lock);
	if (!bg_cdc->bg_cal_updated) {
		bg_cdc_enable_regulator(bg_cdc->spkr_vreg, true);
		/* Send open command */
		rsp.buf_size = sizeof(struct graphite_basic_rsp_result);
		rsp.buf = kzalloc(rsp.buf_size, GFP_KERNEL);
		if (!rsp.buf)
			goto err;
		memcpy(&hw_params, &bg_cdc->hw_params, sizeof(hw_params));
		/* Send command to BG to start session */
		ret = pktzr_cmd_open(&hw_params, sizeof(hw_params), &rsp);
		if (ret < 0) {
			pr_err("pktzr cmd open failed\n");
			goto err1;
		}
		ret = bg_cdc_cal(bg_cdc);
		if (ret < 0) {
			pr_err("calibiration failed\n");
			goto err1;
		}
		kfree(rsp.buf);
	}
	mutex_unlock(&bg_cdc->bg_cdc_lock);
	return 0;
err1:
	kfree(rsp.buf);
err:
	bg_cdc_enable_regulator(bg_cdc->spkr_vreg, false);
	mutex_unlock(&bg_cdc->bg_cdc_lock);
	schedule_delayed_work(&bg_cdc->bg_cdc_cal_init_work,
			msecs_to_jiffies(bg_cdc->bg_cal_init_delay));
	return 0;
}

@@ -1232,6 +1198,8 @@ static int bg_cdc_probe(struct platform_device *pdev)

	bg_cdc->dev = &pdev->dev;
	dev_set_drvdata(&pdev->dev, bg_cdc);
	/* 10 sec delay was expected to get HAL up and send cal data */
	bg_cdc->bg_cal_init_delay = 10000;

	if (of_get_property(
		pdev->dev.of_node,