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;
}
Пример #2
0
static int msm_compr_playback_close(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
	struct compr_audio *compr = runtime->private_data;
	struct msm_audio *prtd = &compr->prtd;
	int dir = 0;
	int rc = 0;
	pr_debug("[AUD] %s +++\n", __func__);

	/*
	If routing is still enabled, we need to issue EOS to
	the DSP
	To issue EOS to dsp, we need to be run state otherwise
	EOS is not honored.
	*/
	if (msm_routing_check_backend_enabled(soc_prtd->dai_link->be_id)) {
		rc = q6asm_run(prtd->audio_client,0,0,0);
		atomic_set(&prtd->pending_buffer, 0);
		prtd->cmd_ack = 0;
		q6asm_cmd_nowait(prtd->audio_client, CMD_EOS);
		pr_debug("%s ++\n", __func__);
		rc = wait_event_timeout(the_locks.eos_wait,
			prtd->cmd_ack, 3 * HZ);
		pr_debug("%s --\n", __func__);
		if (rc <= 0)
			pr_err("EOS cmd timeout\n");
		prtd->pcm_irq_pos = 0;
	}


	dir = IN;
	atomic_set(&prtd->pending_buffer, 0);
	q6asm_cmd(prtd->audio_client, CMD_CLOSE);
	q6asm_audio_client_buf_free_contiguous(dir,
				prtd->audio_client);

	msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id,
	SNDRV_PCM_STREAM_PLAYBACK);
	q6asm_audio_client_free(prtd->audio_client);
	kfree(prtd);
	pr_debug("[AUD] %s ---\n", __func__);
	return 0;
}
static int msm_compr_playback_close(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
	struct compr_audio *compr = runtime->private_data;
	struct msm_audio *prtd = &compr->prtd;
	int dir = 0;

	pr_debug("%s\n", __func__);

	dir = IN;
	atomic_set(&prtd->pending_buffer, 0);
	q6asm_cmd(prtd->audio_client, CMD_CLOSE);
	q6asm_audio_client_buf_free_contiguous(dir,
				prtd->audio_client);

	msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id,
	SNDRV_PCM_STREAM_PLAYBACK);
	q6asm_audio_client_free(prtd->audio_client);
	kfree(prtd);
	return 0;
}
Пример #4
0
static int msm_afe_close(struct snd_pcm_substream *substream)
{
	int rc = 0;
	struct snd_dma_buffer *dma_buf;
	struct snd_pcm_runtime *runtime;
	struct pcm_afe_info *prtd;
	struct snd_soc_pcm_runtime *rtd = NULL;
	struct snd_soc_dai *dai = NULL;
	int dir = IN;
	int ret = 0;

	pr_debug("%s\n", __func__);
	if (substream == NULL) {
		pr_err("substream is NULL\n");
		return -EINVAL;
	}
	rtd = substream->private_data;
	dai = rtd->cpu_dai;
	runtime = substream->runtime;
	prtd = runtime->private_data;

	mutex_lock(&prtd->lock);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		dir = IN;
		ret =  afe_unregister_get_events(dai->id);
		if (ret < 0)
			pr_err("AFE unregister for events failed\n");
	} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
		dir = OUT;
		ret =  afe_unregister_get_events(dai->id);
		if (ret < 0)
			pr_err("AFE unregister for events failed\n");
	}
	hrtimer_cancel(&prtd->hrt);

	rc = afe_cmd_memory_unmap(runtime->dma_addr);
	if (rc < 0)
		pr_err("AFE memory unmap failed\n");

	pr_debug("release all buffer\n");
	dma_buf = &substream->dma_buffer;
	if (dma_buf == NULL) {
		pr_debug("dma_buf is NULL\n");
			goto done;
	}

	if (dma_buf->area) {
			dma_buf->area = NULL;
		}

	q6asm_audio_client_buf_free_contiguous(dir,
				prtd->audio_client);
done:
	pr_debug("%s: dai->id =%x\n", __func__, dai->id);
	q6asm_audio_client_free(prtd->audio_client);
	mutex_unlock(&prtd->lock);
	prtd->prepared--;
	kfree(prtd);
	return 0;
}
static int msm_compr_free(struct snd_compr_stream *cstream)
{
	struct snd_compr_runtime *runtime = cstream->runtime;
	struct msm_compr_audio *prtd = runtime->private_data;
	struct snd_soc_pcm_runtime *soc_prtd = cstream->private_data;
	struct msm_compr_pdata *pdata =
			snd_soc_platform_get_drvdata(soc_prtd->platform);
	struct audio_client *ac = prtd->audio_client;
	int dir = IN, ret = 0, stream_id;
	unsigned long flags;

	pr_debug("%s\n", __func__);
	pdata->cstream[soc_prtd->dai_link->be_id] = NULL;
	if (cstream->direction == SND_COMPRESS_PLAYBACK) {
		if (atomic_read(&pdata->audio_ocmem_req) > 1)
			atomic_dec(&pdata->audio_ocmem_req);
		else if (atomic_cmpxchg(&pdata->audio_ocmem_req, 1, 0))
			audio_ocmem_process_req(AUDIO, false);

		msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id,
						SNDRV_PCM_STREAM_PLAYBACK);
	}

	pr_debug("%s: ocmem_req: %d\n", __func__,
		atomic_read(&pdata->audio_ocmem_req));

	if (atomic_read(&prtd->eos)) {
		ret = wait_event_timeout(prtd->eos_wait,
					 prtd->cmd_ack, 5 * HZ);
		if (!ret)
			pr_err("%s: CMD_EOS failed\n", __func__);
	}
	if (atomic_read(&prtd->close)) {
		prtd->cmd_ack = 0;
		atomic_set(&prtd->wait_on_close, 1);
		ret = wait_event_timeout(prtd->close_wait,
					prtd->cmd_ack, 5 * HZ);
		if (!ret)
			pr_err("%s: CMD_CLOSE failed\n", __func__);
	}

	spin_lock_irqsave(&prtd->lock, flags);
	stream_id = ac->stream_id;
	if (prtd->gapless_state.stream_opened[stream_id^1]) {
		spin_unlock_irqrestore(&prtd->lock, flags);
		q6asm_stream_cmd(ac, CMD_CLOSE, stream_id^1);
		spin_lock_irqsave(&prtd->lock, flags);
	}
	if (prtd->gapless_state.stream_opened[stream_id]) {
		spin_unlock_irqrestore(&prtd->lock, flags);
		q6asm_stream_cmd(ac, CMD_CLOSE, stream_id);
		spin_lock_irqsave(&prtd->lock, flags);
	}
	spin_unlock_irqrestore(&prtd->lock, flags);

	/* client buf alloc was with stream id 0, so free with the same */
	ac->stream_id = 0;
	q6asm_audio_client_buf_free_contiguous(dir, ac);

	q6asm_audio_client_free(ac);

	kfree(pdata->audio_effects[soc_prtd->dai_link->be_id]);
	kfree(prtd);

	return 0;
}