static enum hrtimer_restart afe_hrtimer_callback(struct hrtimer *hrt) { struct pcm_afe_info *prtd = container_of(hrt, struct pcm_afe_info, hrt); struct snd_pcm_substream *substream = prtd->substream; struct snd_pcm_runtime *runtime = substream->runtime; u32 mem_map_handle = 0; mem_map_handle = afe_req_mmap_handle(prtd->audio_client); if (!mem_map_handle) pr_err("%s: mem_map_handle is NULL\n", __func__); if (prtd->start) { pr_debug("sending frame to DSP: poll_time: %d\n", prtd->poll_time); if (prtd->dsp_cnt == runtime->periods) prtd->dsp_cnt = 0; pr_debug("%s: mem_map_handle 0x%x\n", __func__, mem_map_handle); afe_rt_proxy_port_write( (prtd->dma_addr + (prtd->dsp_cnt * snd_pcm_lib_period_bytes(prtd->substream))), mem_map_handle, snd_pcm_lib_period_bytes(prtd->substream)); prtd->dsp_cnt++; hrtimer_forward_now(hrt, ns_to_ktime(prtd->poll_time * 1000)); return HRTIMER_RESTART; } else return HRTIMER_NORESTART; }
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; }