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; }
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; }