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 void afe_send_cal_block(int32_t path, u16 port_id)
{
	int						result = 0;
	struct acdb_cal_block				cal_block;
	struct afe_port_cmd_set_param_no_payload	afe_cal;
	pr_debug("%s: path %d\n", __func__, path);

	get_afe_cal(path, &cal_block);
	if (cal_block.cal_size <= 0) {
		pr_debug("%s: No AFE cal to send!\n", __func__);
		goto done;
	}

	if ((afe_cal_addr[path].cal_paddr != cal_block.cal_paddr) ||
		(cal_block.cal_size > afe_cal_addr[path].cal_size)) {
		if (afe_cal_addr[path].cal_paddr != 0)
			afe_cmd_memory_unmap(
				afe_cal_addr[path].cal_paddr);

		afe_cmd_memory_map(cal_block.cal_paddr, cal_block.cal_size);
		afe_cal_addr[path].cal_paddr = cal_block.cal_paddr;
		afe_cal_addr[path].cal_size = cal_block.cal_size;
	}

	afe_cal.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
	afe_cal.hdr.pkt_size = sizeof(afe_cal);
	afe_cal.hdr.src_port = 0;
	afe_cal.hdr.dest_port = 0;
	afe_cal.hdr.token = 0;
	afe_cal.hdr.opcode = AFE_PORT_CMD_SET_PARAM;
	afe_cal.port_id = port_id;
	afe_cal.payload_size = cal_block.cal_size;
	afe_cal.payload_address = cal_block.cal_paddr;

	pr_debug("%s: AFE cal sent for device port = %d, path = %d, "
		"cal size = %d, cal addr = 0x%x\n", __func__,
		port_id, path, cal_block.cal_size, cal_block.cal_paddr);

	atomic_set(&this_afe.state, 1);
	result = apr_send_pkt(this_afe.apr, (uint32_t *) &afe_cal);
	if (result < 0) {
		pr_err("%s: AFE cal for port %d failed\n",
			__func__, port_id);
	}

	result = wait_event_timeout(this_afe.wait,
				 (atomic_read(&this_afe.state) == 0),
				 msecs_to_jiffies(TIMEOUT_MS));
	if (!result) {
		pr_err("%s: wait_event timeout SET AFE CAL\n", __func__);
		HTC_Q6_BUG();
		goto done;
	}

	pr_debug("%s: AFE cal sent for path %d device!\n", __func__, path);
done:
	return;
}
예제 #3
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(afe_req_mmap_handle(prtd->audio_client));
	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;
	q6afe_audio_client_buf_free_contiguous(dir, prtd->audio_client);
done:
	pr_debug("%s: dai->id =%x\n", __func__, dai->id);
	q6afe_audio_client_free(prtd->audio_client);
	mutex_unlock(&prtd->lock);
	prtd->prepared--;
	kfree(prtd);
	runtime->private_data = NULL;
	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 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) {
		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) {
		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 != NULL) {
		dma_free_coherent(substream->pcm->card->dev,
			runtime->hw.buffer_bytes_max, dma_buf->area,
			dma_buf->addr);
		dma_buf->area = NULL;
	}
done:
	pr_debug("%s: dai->id =%x\n", __func__, dai->id);
	mutex_unlock(&prtd->lock);
	prtd->prepared--;
	kfree(prtd);
	return 0;
}