static int msm_dai_q6_dai_mi2s_remove(struct snd_soc_dai *dai) { struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data = dev_get_drvdata(dai->dev); int rc; /* If AFE port is still up, close it */ if (test_bit(STATUS_PORT_STARTED, mi2s_dai_data->rx_dai.status_mask)) { rc = afe_close(MI2S_RX); /* can block */ if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to close MI2S_RX port\n"); clear_bit(STATUS_PORT_STARTED, mi2s_dai_data->rx_dai.status_mask); } if (test_bit(STATUS_PORT_STARTED, mi2s_dai_data->tx_dai.status_mask)) { rc = afe_close(MI2S_TX); /* can block */ if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to close MI2S_TX port\n"); clear_bit(STATUS_PORT_STARTED, mi2s_dai_data->tx_dai.status_mask); } kfree(mi2s_dai_data); snd_soc_unregister_dai(dai->dev); return 0; }
static int msm_dai_q6_dai_auxpcm_remove(struct snd_soc_dai *dai) { struct msm_dai_q6_dai_data *dai_data; int rc; dai_data = dev_get_drvdata(dai->dev); /* If AFE port is still up, close it */ if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { rc = afe_close(dai->id); /* can block */ if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to close AFE port\n"); clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); rc = afe_close(PCM_TX); if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to close AUX PCM TX port\n"); } kfree(dai_data); snd_soc_unregister_dai(dai->dev); return 0; }
static void msm_dai_q6_auxpcm_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); int rc = 0; rc = adm_close(dai->id); if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to close ADM COPP\n"); pr_debug("%s: dai->id = %d", __func__, dai->id); if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { clk_disable(pcm_clk); rc = afe_close(dai->id); /* can block */ if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to close AFE port\n"); pr_debug("%s: dai_data->status_mask = %ld\n", __func__, *dai_data->status_mask); clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); rc = afe_close(PCM_TX); if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to close AUX PCM TX port\n"); } }
int snddev_ecodec_close(struct msm_snddev_info *dev_info) { struct snddev_ecodec_drv_state *drv = &snddev_ecodec_drv; pr_debug("%s: closing %s\n", __func__, dev_info->name); mutex_lock(&drv->dev_lock); if (!dev_info->opened) { pr_err("%s: ERROR: %s is not opened\n", __func__, dev_info->name); mutex_unlock(&drv->dev_lock); return -EPERM; } drv->ref_cnt--; if (drv->ref_cnt == 0) { pr_info("%s: closing all devices\n", __func__); clk_disable_unprepare(drv->ecodec_clk); aux_pcm_gpios_free(); afe_close(PCM_RX); afe_close(PCM_TX); } mutex_unlock(&drv->dev_lock); return 0; }
int snddev_ecodec_close(struct msm_snddev_info *dev_info) { struct snddev_ecodec_drv_state *drv = &snddev_ecodec_drv; #ifdef CONFIG_PANTECH_AUDIO_PRESTO_AUDIENCE2020 // jmlee //int i; struct snddev_ecodec_state *ecodec; #endif pr_debug("%s: closing %s\n", __func__, dev_info->name); mutex_lock(&drv->dev_lock); if (!dev_info->opened) { pr_err("%s: ERROR: %s is not opened\n", __func__, dev_info->name); mutex_unlock(&drv->dev_lock); return -EPERM; } #ifdef CONFIG_PANTECH_AUDIO_PRESTO_AUDIENCE2020 // jmlee /* audience disable */ ecodec = dev_info->private_data; if (ecodec->data->pamp_off && (ecodec_audience_enable)) { ecodec->data->pamp_off(); ecodec_audience_enable = 0; /* Disable mic bias */ // 20110224 jhsong //for (i = 0; i < ecodec->data->pmctl_id_sz; i++) { // pmic_hsed_enable(ecodec->data->pmctl_id[i], // PM_HSED_ENABLE_OFF); //} } #endif drv->ref_cnt--; if (drv->ref_cnt == 0) { pr_info("%s: closing all devices\n", __func__); clk_disable(drv->ecodec_clk); aux_pcm_gpios_free(); afe_close(PCM_RX); afe_close(PCM_TX); } mutex_unlock(&drv->dev_lock); return 0; }
static int msm_dai_q6_dai_auxpcm_remove(struct snd_soc_dai *dai) { struct msm_dai_q6_dai_data *dai_data; int rc; dai_data = dev_get_drvdata(dai->dev); mutex_lock(&aux_pcm_mutex); if (aux_pcm_count == 0) { dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count is 0. clean" " up and return\n", __func__, dai->id); goto done; } aux_pcm_count--; if (aux_pcm_count > 0) { dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count = %d\n", __func__, dai->id, aux_pcm_count); goto done; } else if (aux_pcm_count < 0) { dev_err(dai->dev, "%s(): ERROR: dai->id %d" " aux_pcm_count = %d < 0\n", __func__, dai->id, aux_pcm_count); goto done; } dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count = %d." "closing afe\n", __func__, dai->id, aux_pcm_count); rc = afe_close(PCM_RX); /* can block */ if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to close AUX PCM RX AFE port\n"); rc = afe_close(PCM_TX); if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to close AUX PCM TX AFE port\n"); done: kfree(dai_data); snd_soc_unregister_dai(dai->dev); mutex_unlock(&aux_pcm_mutex); return 0; }
static int snddev_hdmi_close(struct msm_snddev_info *dev_info) { if (!dev_info) { pr_aud_err("msm_snddev_info is null\n"); return -EINVAL; } if (!dev_info->opened) { pr_aud_err("calling close device with out opening the" " device\n"); return -EPERM; } mutex_lock(&snddev_hdmi_lock); if (!snddev_hdmi_active) { pr_aud_err("HDMI snddev not active\n"); mutex_unlock(&snddev_hdmi_lock); return -EPERM; } snddev_hdmi_active = 0; afe_close(HDMI_RX); pr_debug("%s closed\n", dev_info->name); mutex_unlock(&snddev_hdmi_lock); return 0; }
static void msm_dai_q6_mi2s_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data = dev_get_drvdata(dai->dev); struct msm_dai_q6_dai_data *dai_data = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? &mi2s_dai_data->rx_dai : &mi2s_dai_data->tx_dai); u16 port_id = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? MI2S_RX : MI2S_TX); int rc = 0; if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { rc = afe_close(port_id); if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to close AFE port\n"); clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); } if (!test_bit(STATUS_PORT_STARTED, mi2s_dai_data->rx_dai.status_mask) && !test_bit(STATUS_PORT_STARTED, mi2s_dai_data->rx_dai.status_mask)) { mi2s_dai_data->rate_constraint.list = NULL; mi2s_dai_data->bitwidth_constraint.list = NULL; } }
static void msm_dai_q6_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); int rc = 0; if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { switch (dai->id) { case VOICE_PLAYBACK_TX: case VOICE_RECORD_TX: case VOICE_RECORD_RX: pr_debug("%s, stop pseudo port:%d\n", __func__, dai->id); rc = afe_stop_pseudo_port(dai->id); break; default: rc = afe_close(dai->id); /* can block */ break; } if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to close AFE port\n"); pr_debug("%s: dai_data->status_mask = %ld\n", __func__, *dai_data->status_mask); clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); } }
static int snddev_icodec_close_tx(struct snddev_icodec_state *icodec) { struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; pm_qos_update_request(&drv->tx_pm_qos_req, msm_cpuidle_get_deep_idle_latency()); if (drv->snddev_vreg) vreg_mode_vote(drv->snddev_vreg, 0, SNDDEV_HIGH_POWER_MODE); /* Disable ADIE */ if (icodec->adie_path) { adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_OFF); adie_codec_close(icodec->adie_path); icodec->adie_path = NULL; } afe_close(icodec->data->copp_id); clk_disable_unprepare(drv->tx_bitclk); clk_disable_unprepare(drv->tx_osrclk); msm_snddev_tx_mclk_free(); /* Reuse pamp_off for TX platform-specific setup */ if (icodec->data->pamp_off) icodec->data->pamp_off(); icodec->enabled = 0; pm_qos_update_request(&drv->tx_pm_qos_req, PM_QOS_DEFAULT_VALUE); return 0; }
static int pcm_in_release(struct inode *inode, struct file *file) { int rc = 0; struct pcm *pcm = file->private_data; pr_info("[AUD][%s:%s] release session id[%d]\n", __MM_FILE__, __func__, pcm->ac->session); mutex_lock(&pcm->lock); /* remove this session from topology list */ auddev_cfg_tx_copp_topology(pcm->ac->session, DEFAULT_COPP_TOPOLOGY); rc = pcm_in_disable(pcm); hrtimer_cancel(&pcm->hrt); rc = afe_cmd_memory_unmap(pcm->dma_addr); if (rc < 0) pr_err("AFE memory unmap failed\n"); rc = afe_unregister_get_events(RT_PROXY_DAI_001_TX); if (rc < 0) pr_err("AFE unregister for events failed\n"); afe_close(RT_PROXY_DAI_001_TX); pr_debug("release all buffer\n"); q6asm_audio_client_buf_free_contiguous(OUT, pcm->ac); msm_clear_session_id(pcm->ac->session); q6asm_audio_client_free(pcm->ac); mutex_unlock(&pcm->lock); mutex_destroy(&pcm->lock); mutex_destroy(&pcm->read_lock); kfree(pcm); return rc; }
static int msm_dai_q6_dai_remove(struct snd_soc_dai *dai) { struct msm_dai_q6_dai_data *dai_data; int rc; dai_data = dev_get_drvdata(dai->dev); /* If AFE port is still up, close it */ if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { switch (dai->id) { case VOICE_PLAYBACK_TX: case VOICE_RECORD_TX: case VOICE_RECORD_RX: pr_debug("%s, stop pseudo port:%d\n", __func__, dai->id); rc = afe_stop_pseudo_port(dai->id); break; default: rc = afe_close(dai->id); /* can block */ } if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to close AFE port\n"); clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); } kfree(dai_data); snd_soc_unregister_dai(dai->dev); return 0; }
static int snddev_icodec_close_tx(struct snddev_icodec_state *icodec) { struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; wake_lock(&drv->tx_idlelock); if (drv->snddev_vreg) vreg_mode_vote(drv->snddev_vreg, 0, SNDDEV_HIGH_POWER_MODE); /* Disable ADIE */ if (icodec->adie_path) { adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_OFF); adie_codec_close(icodec->adie_path); icodec->adie_path = NULL; } afe_close(icodec->data->copp_id); clk_disable(drv->tx_bitclk); clk_disable(drv->tx_osrclk); msm_snddev_tx_mclk_free(); /* Reuse pamp_off for TX platform-specific setup */ if (icodec->data->pamp_off) icodec->data->pamp_off(); icodec->enabled = 0; wake_unlock(&drv->tx_idlelock); return 0; }
static int snddev_mi2s_close(struct msm_snddev_info *dev_info) { struct snddev_mi2s_drv_state *mi2s_drv = &snddev_mi2s_drv; struct snddev_mi2s_data *snddev_mi2s_data = dev_info->private_data; if (!dev_info) { pr_err("%s: msm_snddev_info is null\n", __func__); return -EINVAL; } if (!dev_info->opened) { pr_err(" %s: calling close device with out opening the" " device\n", __func__); return -EIO; } afe_close(snddev_mi2s_data->copp_id); clk_disable_unprepare(mi2s_drv->tx_bitclk); clk_disable_unprepare(mi2s_drv->tx_osrclk); mi2s_gpios_free(); pr_info("%s:\n", __func__); return 0; }
static void msm_dai_q6_auxpcm_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { int rc = 0; mutex_lock(&aux_pcm_mutex); if (aux_pcm_count == 0) { dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count is 0. Just return\n", __func__, dai->id); mutex_unlock(&aux_pcm_mutex); return; } aux_pcm_count--; if (aux_pcm_count > 0) { dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count = %d\n", __func__, dai->id, aux_pcm_count); mutex_unlock(&aux_pcm_mutex); return; } else if (aux_pcm_count < 0) { dev_err(dai->dev, "%s(): ERROR: dai->id %d aux_pcm_count = %d < 0\n", __func__, dai->id, aux_pcm_count); aux_pcm_count = 0; mutex_unlock(&aux_pcm_mutex); return; } pr_debug("%s: dai->id = %d aux_pcm_count = %d\n", __func__, dai->id, aux_pcm_count); rc = afe_close(PCM_RX); /* can block */ if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to close PCM_RX AFE port\n"); rc = afe_close(PCM_TX); if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to close AUX PCM TX port\n"); clk_disable_unprepare(pcm_branch_clk); clk_disable_unprepare(pcm_oe_branch_clk); mutex_unlock(&aux_pcm_mutex); }
static int snddev_icodec_close_rx(struct snddev_icodec_state *icodec) { struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; struct snddev_icodec_data *data = icodec->data; wake_lock(&drv->rx_idlelock); if (drv->snddev_vreg) vreg_mode_vote(drv->snddev_vreg, 0, SNDDEV_HIGH_POWER_MODE); /* Disable power amplifier */ if (icodec->data->pamp_on) icodec->data->pamp_on(0); if (support_aic3254) { /* Restore default id for A3254 */ if (data->aic3254_id != data->default_aic3254_id) data->aic3254_id = data->default_aic3254_id; /* Disable External Codec A3254 */ if (aic3254_ops->aic3254_set_mode) aic3254_ops->aic3254_set_mode(AIC3254_CONFIG_RX, DOWNLINK_OFF); } if (support_adie) { /* Disable ADIE */ if (icodec->adie_path) { adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_OFF); adie_codec_close(icodec->adie_path); icodec->adie_path = NULL; } } afe_close(icodec->data->copp_id); if (icodec->data->voltage_on) icodec->data->voltage_on(0); clk_disable(drv->rx_bitclk); if (support_aic3254_use_mclk) snddev_icodec_rxclk_enable(icodec, 0); else clk_disable(drv->rx_osrclk); msm_snddev_rx_mclk_free(); icodec->enabled = 0; wake_unlock(&drv->rx_idlelock); return 0; }
static int snddev_hdmi_close(struct msm_snddev_info *dev_info) { struct snddev_hdmi_data *snddev_hdmi_data; if (!dev_info) { pr_err("msm_snddev_info is null\n"); return -EINVAL; } snddev_hdmi_data = dev_info->private_data; if (!dev_info->opened) { pr_err("calling close device with out opening the" " device\n"); return -EPERM; } mutex_lock(&snddev_hdmi_lock); if (!snddev_hdmi_active) { pr_err("HDMI snddev not active\n"); mutex_unlock(&snddev_hdmi_lock); return -EPERM; } snddev_hdmi_active = 0; if (snddev_hdmi_data->on_apps) { pr_debug("%s open done\n", dev_info->name); mutex_unlock(&snddev_hdmi_lock); return 0; } afe_close(HDMI_RX); pr_debug("%s closed\n", dev_info->name); mutex_unlock(&snddev_hdmi_lock); return 0; }
static int msm_dai_q6_hdmi_dai_remove(struct snd_soc_dai *dai) { struct msm_dai_q6_hdmi_dai_data *dai_data; int rc; dai_data = dev_get_drvdata(dai->dev); if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { rc = afe_close(dai->id); if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to close AFE port\n"); clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); } kfree(dai_data); snd_soc_unregister_dai(dai->dev); return 0; }
static void msm_dai_q6_hdmi_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct msm_dai_q6_hdmi_dai_data *dai_data = dev_get_drvdata(dai->dev); int rc = 0; if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { pr_info("%s: afe port not started. dai_data->status_mask" " = %ld\n", __func__, *dai_data->status_mask); return; } rc = afe_close(dai->id); /* can block */ if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to close AFE port\n"); pr_debug("%s: dai_data->status_mask = %ld\n", __func__, *dai_data->status_mask); clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); }
static int snddev_icodec_close_rx(struct snddev_icodec_state *icodec) { struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; pr_info("%s\n", __func__); // pm_qos_update_request(&drv->rx_pm_qos_req, msm_cpuidle_get_deep_idle_latency()); if (drv->snddev_vreg) vreg_mode_vote(drv->snddev_vreg, 0, SNDDEV_HIGH_POWER_MODE); /* Disable power amplifier */ if (icodec->data->pamp_off) icodec->data->pamp_off(); /* Disable ADIE */ if (icodec->adie_path) { adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_OFF); adie_codec_close(icodec->adie_path); icodec->adie_path = NULL; } afe_close(icodec->data->copp_id); if (icodec->data->voltage_off) icodec->data->voltage_off(); clk_disable_unprepare(drv->rx_bitclk); clk_disable_unprepare(drv->rx_osrclk); msm_snddev_rx_mclk_free(); icodec->enabled = 0; pm_qos_update_request(&drv->rx_pm_qos_req, PM_QOS_DEFAULT_VALUE); return 0; }
static int snddev_ecodec_open(struct msm_snddev_info *dev_info) { int rc; struct snddev_ecodec_drv_state *drv = &snddev_ecodec_drv; union afe_port_config afe_config; pr_debug("%s\n", __func__); mutex_lock(&drv->dev_lock); if (dev_info->opened) { pr_err("%s: ERROR: %s already opened\n", __func__, dev_info->name); mutex_unlock(&drv->dev_lock); return -EBUSY; } if (drv->ref_cnt != 0) { pr_debug("%s: opened %s\n", __func__, dev_info->name); drv->ref_cnt++; mutex_unlock(&drv->dev_lock); return 0; } pr_info("%s: opening %s\n", __func__, dev_info->name); rc = aux_pcm_gpios_request(); if (rc < 0) { pr_err("%s: GPIO request failed\n", __func__); return rc; } clk_reset(drv->ecodec_clk, CLK_RESET_ASSERT); afe_config.pcm.mode = AFE_PCM_CFG_MODE_PCM; afe_config.pcm.sync = AFE_PCM_CFG_SYNC_INT; afe_config.pcm.frame = AFE_PCM_CFG_FRM_256BPF; afe_config.pcm.quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD; afe_config.pcm.slot = 0; afe_config.pcm.data = AFE_PCM_CFG_CDATAOE_MASTER; rc = afe_open(PCM_RX, &afe_config, ECODEC_SAMPLE_RATE); if (rc < 0) { pr_err("%s: afe open failed for PCM_RX\n", __func__); goto err_rx_afe; } rc = afe_open(PCM_TX, &afe_config, ECODEC_SAMPLE_RATE); if (rc < 0) { pr_err("%s: afe open failed for PCM_TX\n", __func__); goto err_tx_afe; } rc = clk_set_rate(drv->ecodec_clk, 2048000); if (rc < 0) { pr_err("%s: clk_set_rate failed\n", __func__); goto err_clk; } clk_prepare_enable(drv->ecodec_clk); clk_reset(drv->ecodec_clk, CLK_RESET_DEASSERT); drv->ref_cnt++; mutex_unlock(&drv->dev_lock); return 0; err_clk: afe_close(PCM_TX); err_tx_afe: afe_close(PCM_RX); err_rx_afe: aux_pcm_gpios_free(); mutex_unlock(&drv->dev_lock); return -ENODEV; }
/* This function sends multi-channel HDMI configuration command and AFE * calibration which is only supported by QDSP6 on 8960 and onward. */ int afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate) { struct afe_port_start_command start; struct afe_audioif_config_command config; int ret; // [email protected] : Please refer to QCT case#01306695 regarding AFE recovery #ifdef CONFIG_LGE_AFE_RECOVERY int count = 0; #endif // CONFIG_LGE_AFE_RECOVERY if (!afe_config) { pr_err("%s: Error, no configuration data\n", __func__); ret = -EINVAL; return ret; } pr_debug("%s: %d %d\n", __func__, port_id, rate); if ((port_id == RT_PROXY_DAI_001_RX) || (port_id == RT_PROXY_DAI_002_TX)) { pr_debug("%s: before incrementing pcm_afe_instance %d"\ " port_id %d\n", __func__, pcm_afe_instance[port_id & 0x1], port_id); port_id = VIRTUAL_ID_TO_PORTID(port_id); pcm_afe_instance[port_id & 0x1]++; return 0; } if ((port_id == RT_PROXY_DAI_002_RX) || (port_id == RT_PROXY_DAI_001_TX)) { pr_debug("%s: before incrementing proxy_afe_instance %d"\ " port_id %d\n", __func__, proxy_afe_instance[port_id & 0x1], port_id); if (!afe_close_done[port_id & 0x1]) { /*close pcm dai corresponding to the proxy dai*/ afe_close(port_id - 0x10); pcm_afe_instance[port_id & 0x1]++; pr_debug("%s: reconfigure afe port again\n", __func__); } proxy_afe_instance[port_id & 0x1]++; afe_close_done[port_id & 0x1] = false; port_id = VIRTUAL_ID_TO_PORTID(port_id); } ret = afe_q6_interface_prepare(); if (IS_ERR_VALUE(ret)) return ret; if (port_id == HDMI_RX) { config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); config.hdr.pkt_size = afe_sizeof_cfg_cmd(port_id); config.hdr.src_port = 0; config.hdr.dest_port = 0; config.hdr.token = 0; config.hdr.opcode = AFE_PORT_MULTI_CHAN_HDMI_AUDIO_IF_CONFIG; } else { config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); config.hdr.pkt_size = afe_sizeof_cfg_cmd(port_id); config.hdr.src_port = 0; config.hdr.dest_port = 0; config.hdr.token = 0; switch (port_id) { case SLIMBUS_0_RX: case SLIMBUS_0_TX: case SLIMBUS_1_RX: case SLIMBUS_1_TX: case SLIMBUS_2_RX: case SLIMBUS_2_TX: case SLIMBUS_3_RX: case SLIMBUS_3_TX: case SLIMBUS_4_RX: case SLIMBUS_4_TX: config.hdr.opcode = AFE_PORT_AUDIO_SLIM_SCH_CONFIG; break; case MI2S_TX: case MI2S_RX: case SECONDARY_I2S_RX: case SECONDARY_I2S_TX: case PRIMARY_I2S_RX: case PRIMARY_I2S_TX: /* AFE_PORT_CMD_I2S_CONFIG command is not supported * in the LPASS EL 1.0. So we have to distiguish * which AFE command, AFE_PORT_CMD_I2S_CONFIG or * AFE_PORT_AUDIO_IF_CONFIG to use. If the format * is L-PCM, the AFE_PORT_AUDIO_IF_CONFIG is used * to make the backward compatible. */ pr_debug("%s: afe_config->mi2s.format = %d\n", __func__, afe_config->mi2s.format); if (afe_config->mi2s.format == MSM_AFE_I2S_FORMAT_LPCM) config.hdr.opcode = AFE_PORT_AUDIO_IF_CONFIG; else config.hdr.opcode = AFE_PORT_CMD_I2S_CONFIG; break; default: config.hdr.opcode = AFE_PORT_AUDIO_IF_CONFIG; break; } } if (afe_validate_port(port_id) < 0) { pr_err("%s: Failed : Invalid Port id = %d\n", __func__, port_id); ret = -EINVAL; goto fail_cmd; } config.port_id = port_id; config.port = *afe_config; // [email protected] : Please refer to QCT case#01306695 regarding AFE recovery #ifdef CONFIG_LGE_AFE_RECOVERY send_cfg_cmd: #endif // CONFIG_LGE_AFE_RECOVERY atomic_set(&this_afe.state, 1); atomic_set(&this_afe.status, 0); ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config); if (ret < 0) { pr_err("%s: AFE enable for port %d failed\n", __func__, port_id); ret = -EINVAL; goto fail_cmd; } ret = wait_event_timeout(this_afe.wait, (atomic_read(&this_afe.state) == 0), msecs_to_jiffies(TIMEOUT_MS)); if (!ret) { pr_err("%s: wait_event timeout IF CONFIG\n", __func__); ret = -EINVAL; goto fail_cmd; } if (atomic_read(&this_afe.status) != 0) { pr_err("%s: config cmd failed\n", __func__); // [email protected] : Please refer to QCT case#01306695 regarding AFE recovery #ifdef CONFIG_LGE_AFE_RECOVERY if (count < 2) { afe_close(port_id); count++; goto send_cfg_cmd; } #endif // CONFIG_LGE_AFE_RECOVERY ret = -EINVAL; goto fail_cmd; } /* send AFE cal */ afe_send_cal(port_id); afe_send_hw_delay(port_id, rate); start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); start.hdr.pkt_size = sizeof(start); start.hdr.src_port = 0; start.hdr.dest_port = 0; start.hdr.token = 0; start.hdr.opcode = AFE_PORT_CMD_START; start.port_id = port_id; start.gain = 0x2000; start.sample_rate = rate; atomic_set(&this_afe.state, 1); ret = apr_send_pkt(this_afe.apr, (uint32_t *) &start); if (IS_ERR_VALUE(ret)) { pr_err("%s: AFE enable for port %d failed\n", __func__, port_id); ret = -EINVAL; goto fail_cmd; } ret = wait_event_timeout(this_afe.wait, (atomic_read(&this_afe.state) == 0), msecs_to_jiffies(TIMEOUT_MS)); if (!ret) { pr_err("%s: wait_event timeout PORT START\n", __func__); ret = -EINVAL; goto fail_cmd; } if (this_afe.task != current) this_afe.task = current; pr_debug("task_name = %s pid = %d\n", this_afe.task->comm, this_afe.task->pid); return 0; fail_cmd: return ret; }
int afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate) { struct afe_port_start_command start; struct afe_audioif_config_command config; int ret; if (!afe_config) { pr_err("%s: Error, no configuration data\n", __func__); ret = -EINVAL; return ret; } pr_info("%s: %d %d\n", __func__, port_id, rate); if ((port_id == RT_PROXY_DAI_001_RX) || (port_id == RT_PROXY_DAI_002_TX)) { pr_debug("%s: before incrementing pcm_afe_instance %d"\ " port_id %d\n", __func__, pcm_afe_instance[port_id & 0x1], port_id); port_id = VIRTUAL_ID_TO_PORTID(port_id); pcm_afe_instance[port_id & 0x1]++; return 0; } if ((port_id == RT_PROXY_DAI_002_RX) || (port_id == RT_PROXY_DAI_001_TX)) { pr_debug("%s: before incrementing proxy_afe_instance %d"\ " port_id %d\n", __func__, proxy_afe_instance[port_id & 0x1], port_id); if (!afe_close_done[port_id & 0x1]) { /*close pcm dai corresponding to the proxy dai*/ afe_close(port_id - 0x10); pcm_afe_instance[port_id & 0x1]++; pr_debug("%s: reconfigure afe port again\n", __func__); } proxy_afe_instance[port_id & 0x1]++; afe_close_done[port_id & 0x1] = false; port_id = VIRTUAL_ID_TO_PORTID(port_id); } ret = afe_q6_interface_prepare(); if (IS_ERR_VALUE(ret)) return ret; if (port_id == HDMI_RX) { config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); config.hdr.pkt_size = afe_sizeof_cfg_cmd(port_id); config.hdr.src_port = 0; config.hdr.dest_port = 0; config.hdr.token = 0; config.hdr.opcode = AFE_PORT_MULTI_CHAN_HDMI_AUDIO_IF_CONFIG; } else { config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); config.hdr.pkt_size = afe_sizeof_cfg_cmd(port_id); config.hdr.src_port = 0; config.hdr.dest_port = 0; config.hdr.token = 0; switch (port_id) { case SLIMBUS_0_RX: case SLIMBUS_0_TX: case SLIMBUS_1_RX: case SLIMBUS_1_TX: case SLIMBUS_2_RX: case SLIMBUS_2_TX: case SLIMBUS_3_RX: case SLIMBUS_3_TX: case SLIMBUS_4_RX: case SLIMBUS_4_TX: config.hdr.opcode = AFE_PORT_AUDIO_SLIM_SCH_CONFIG; break; case MI2S_TX: case MI2S_RX: case SECONDARY_I2S_RX: case SECONDARY_I2S_TX: case PRIMARY_I2S_RX: case PRIMARY_I2S_TX: pr_debug("%s: afe_config->mi2s.format = %d\n", __func__, afe_config->mi2s.format); if (afe_config->mi2s.format == MSM_AFE_I2S_FORMAT_LPCM) config.hdr.opcode = AFE_PORT_AUDIO_IF_CONFIG; else config.hdr.opcode = AFE_PORT_CMD_I2S_CONFIG; break; default: config.hdr.opcode = AFE_PORT_AUDIO_IF_CONFIG; break; } } if (afe_validate_port(port_id) < 0) { pr_err("%s: Failed : Invalid Port id = %d\n", __func__, port_id); ret = -EINVAL; goto fail_cmd; } config.port_id = port_id; config.port = *afe_config; atomic_set(&this_afe.state, 1); atomic_set(&this_afe.status, 0); ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config); if (ret < 0) { pr_err("%s: AFE enable for port %d failed\n", __func__, port_id); HTC_Q6_BUG(); ret = -EINVAL; goto fail_cmd; } ret = wait_event_timeout(this_afe.wait, (atomic_read(&this_afe.state) == 0), msecs_to_jiffies(TIMEOUT_MS)); if (!ret) { pr_err("%s: wait_event timeout IF CONFIG\n", __func__); HTC_Q6_BUG(); ret = -EINVAL; goto fail_cmd; } if (atomic_read(&this_afe.status) != 0) { pr_err("%s: config cmd failed\n", __func__); ret = -EINVAL; goto fail_cmd; } afe_send_cal(port_id); start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); start.hdr.pkt_size = sizeof(start); start.hdr.src_port = 0; start.hdr.dest_port = 0; start.hdr.token = 0; start.hdr.opcode = AFE_PORT_CMD_START; start.port_id = port_id; start.gain = 0x2000; start.sample_rate = rate; atomic_set(&this_afe.state, 1); ret = apr_send_pkt(this_afe.apr, (uint32_t *) &start); if (IS_ERR_VALUE(ret)) { pr_err("%s: AFE enable for port %d failed\n", __func__, port_id); ret = -EINVAL; goto fail_cmd; } ret = wait_event_timeout(this_afe.wait, (atomic_read(&this_afe.state) == 0), msecs_to_jiffies(AFE_TIMEOUT_MS)); if (!ret) { pr_err("%s: wait_event timeout PORT START\n", __func__); HTC_Q6_BUG(); ret = -EINVAL; goto fail_cmd; } if (this_afe.task != current) this_afe.task = current; pr_debug("task_name = %s pid = %d\n", this_afe.task->comm, this_afe.task->pid); return 0; fail_cmd: return ret; }
static int snddev_ecodec_open(struct msm_snddev_info *dev_info) { int rc; struct snddev_ecodec_drv_state *drv = &snddev_ecodec_drv; union afe_port_config afe_config; #ifdef CONFIG_PANTECH_AUDIO_PRESTO_AUDIENCE2020 // jmlee struct snddev_ecodec_state *ecodec; //int i; #endif pr_debug("%s\n", __func__); mutex_lock(&drv->dev_lock); if (dev_info->opened) { pr_err("%s: ERROR: %s already opened\n", __func__, dev_info->name); mutex_unlock(&drv->dev_lock); return -EBUSY; } if (drv->ref_cnt != 0) { pr_debug("%s: opened %s\n", __func__, dev_info->name); drv->ref_cnt++; mutex_unlock(&drv->dev_lock); return 0; } pr_info("%s: opening %s\n", __func__, dev_info->name); rc = aux_pcm_gpios_request(); if (rc < 0) { pr_err("%s: GPIO request failed\n", __func__); return rc; } clk_reset(drv->ecodec_clk, CLK_RESET_ASSERT); afe_config.pcm.mode = AFE_PCM_CFG_MODE_PCM; afe_config.pcm.sync = AFE_PCM_CFG_SYNC_INT; afe_config.pcm.frame = AFE_PCM_CFG_FRM_256BPF; afe_config.pcm.quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD; afe_config.pcm.slot = 0; afe_config.pcm.data = AFE_PCM_CFG_CDATAOE_MASTER; rc = afe_open(PCM_RX, &afe_config, ECODEC_SAMPLE_RATE); if (rc < 0) { pr_err("%s: afe open failed for PCM_RX\n", __func__); goto err_rx_afe; } rc = afe_open(PCM_TX, &afe_config, ECODEC_SAMPLE_RATE); if (rc < 0) { pr_err("%s: afe open failed for PCM_TX\n", __func__); goto err_tx_afe; } rc = clk_set_rate(drv->ecodec_clk, 2048000); if (rc < 0) { pr_err("%s: clk_set_rate failed\n", __func__); goto err_clk; } clk_enable(drv->ecodec_clk); clk_reset(drv->ecodec_clk, CLK_RESET_DEASSERT); drv->ref_cnt++; mutex_unlock(&drv->dev_lock); #ifdef CONFIG_PANTECH_AUDIO_PRESTO_AUDIENCE2020 // jmlee /* audience enable */ ecodec = dev_info->private_data; if ((ecodec->data->pamp_on) && (!ecodec_audience_enable)) { ecodec->data->pamp_on(); ecodec_audience_enable = 1; /* Enable mic bias */ //for (i = 0; i < ecodec->data->pmctl_id_sz; i++) { // pmic_hsed_enable(ecodec->data->pmctl_id[i], // PM_HSED_ENABLE_PWM_TCXO); //} } #endif return 0; err_clk: afe_close(PCM_TX); err_tx_afe: afe_close(PCM_RX); err_rx_afe: aux_pcm_gpios_free(); mutex_unlock(&drv->dev_lock); return -ENODEV; }