static int escore_runtime_suspend(struct device *dev)
{
	struct escore_priv *escore = &escore_priv;
	int ret = 0;
	pr_info("%s(): @@@@@@ Entry #####\n", __func__);
	dev_dbg(dev, "%s()\n", __func__);
	if (escore->dev != dev) {
		dev_dbg(dev, "%s() Invalid device\n", __func__);
		return 0;
	}
	if (!es_ready_to_suspend(escore)) {
		dev_dbg(dev, "%s() - Not ready for suspend\n", __func__);
		return -EBUSY;
	}

	INC_DISABLE_FW_RECOVERY_USE_CNT(escore);
	/*
	 * If the user has selected MP_SLEEP playback mode, the chip will not
	 * enter into normal mode once the stream is shutdown. We need to
	 * bring chip into normal mode to enter into desired runtime suspend
	 * state.
	 */
	if (escore->escore_power_state == ES_SET_POWER_STATE_MP_SLEEP) {
		ret = escore_wakeup(escore);
		if (ret) {
			dev_err(dev, "%s() wakeup failed ret = %d\n",
					__func__, ret);
			goto out;
		}
		escore->escore_power_state = ES_SET_POWER_STATE_NORMAL;
	}

	if (escore->voice_sense &&
		escore->vs_ops.escore_is_voicesense_sleep_enable(escore))
		ret = escore_vs_suspend(dev);
	else
		ret = escore_non_vs_suspend(dev);

	if (ret)
		goto out;

	/* Disable the clocks */
	if (escore->pdata->esxxx_clk_cb)
		escore->pdata->esxxx_clk_cb(0);

	dev_dbg(dev, "%s() complete %d\n", __func__, ret);
	DEC_DISABLE_FW_RECOVERY_USE_CNT(escore);
	pr_info("%s(): @@@@@@ EXIT #####\n", __func__);
	return ret;

out:
	DEC_DISABLE_FW_RECOVERY_USE_CNT(escore);
	ret = escore_fw_recovery(escore, FORCED_FW_RECOVERY_ON);
	if (ret < 0) {
		dev_err(dev, "%s() Firmware recovery failed %d\n",
							__func__, ret);
	}

	return -EAGAIN;
}
static int escore_non_vs_resume(struct device *dev)
{
	struct escore_priv *escore = &escore_priv;
	int ret = 0;

	dev_dbg(dev, "%s()\n", __func__);

	ret = escore_wakeup(escore);
	if (ret) {
		dev_err(dev, "%s() wakeup failed ret = %d\n", __func__, ret);
		goto escore_non_vs_resume_exit;
	}
	escore->escore_power_state = ES_SET_POWER_STATE_NORMAL;

escore_non_vs_resume_exit:
	dev_dbg(dev, "%s() complete %d\n", __func__, ret);

	return ret;
}
示例#3
0
文件: escore-vs.c 项目: qkdang/m462
int escore_vs_wakeup(struct escore_priv *escore)
{
    u32 cmd, rsp;
    int sync_retry = 20;
    int rc;

    dev_dbg(escore->dev, "%s()\n", __func__);

    escore->sleep_abort = 1;

    mutex_lock(&escore_priv.api_mutex);

    rc = escore_wakeup(escore);
    if (rc) {
        dev_err(escore->dev, "%s() wakeup failed rc = %d\n",
                __func__, rc);
        goto vs_wakeup_err;
    }

    escore->escore_power_state = ES_SET_POWER_STATE_VS_OVERLAY;

    //msleep(30);

    /* change power state to Normal*/
    cmd = (ES_SET_POWER_STATE << 16) | ES_SET_POWER_STATE_NORMAL;
    rc = escore->bus.ops.cmd(escore, cmd, &rsp);
    if (rc < 0) {
        dev_err(escore->dev, "%s() - failed sync cmd resume\n",
                __func__);
        escore->pm_state = ES_PM_HOSED;
        goto vs_wakeup_err;
    } else {
        /* Time required for switching from VS to NS mode.
         * This delay should be replaced with GPIO A event */
        msleep(30);

        cmd = ES_SYNC_CMD << 16;
        if (escore->cmd_compl_mode == ES_CMD_COMP_INTR)
            cmd |= ES_RISING_EDGE;

        do {
            rc = escore->bus.ops.cmd(escore, cmd, &rsp);
            if (rc < 0) {
                dev_err(escore->dev, "%s() - failed sync cmd\n",
                        __func__);
            }
            if (cmd != rsp) {
                dev_err(escore->dev, "%s() - failed sync rsp\n",
                        __func__);
                usleep_range(2000, 2050);
                rc = -EIO;
            }

        } while (rc && --sync_retry);

        escore->mode = STANDARD;
        escore->pm_state = ES_PM_NORMAL;
        escore->escore_power_state = ES_SET_POWER_STATE_NORMAL;
    }
vs_wakeup_err:
    mutex_unlock(&escore_priv.api_mutex);
    escore->sleep_abort = 0;
    return rc;
}