static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *cpu_dai) { struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); int err = 0, play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: mcbsp_data->active++; omap_mcbsp_start(mcbsp_data->bus_id, play, !play); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: omap_mcbsp_stop(mcbsp_data->bus_id, play, !play); mcbsp_data->active--; break; default: err = -EINVAL; } return err; }
static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *cpu_dai) { struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); int err = 0, play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: mcbsp_data->active++; omap_mcbsp_start(mcbsp_data->bus_id, play, !play); #ifdef C_OPP_PATCH /* * Hold min latency constraint. Deeper states * MPU RET/OFF is overhead and consume more power than * savings. * snd_hw_latency check takes care of playback and capture * usecase. */ if (!snd_hw_latency++) { pm_qos_update_request(&pm_qos_handle, SET_MPU_CORE_CONSTRAINT); } #endif break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: #ifdef C_OPP_PATCH /* remove latency constraint */ snd_hw_latency--; if (!snd_hw_latency) { pm_qos_update_request(&pm_qos_handle, CLEAR_MPU_CORE_CONSTRAINT); } #endif omap_mcbsp_stop(mcbsp_data->bus_id, play, !play); mcbsp_data->active--; break; default: err = -EINVAL; } return err; }
static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *cpu_dai) { struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); int err = 0, play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: mcbsp_data->active++; omap_mcbsp_start(mcbsp_data->bus_id, play, !play); if( !play ){ // Sometimes, TX channel is broken. So, I check TX status for 3s, and when TX underflow is occured, I recover McBSP TX channel. spin_lock(&mcbsp_data->tx_retry_spinlock); mcbsp_data->retry_cnt = 0; mcbsp_data->tx_retry_timer.function = mcbsp_retry_timer_expiry; mcbsp_data->tx_retry_timer.data = mcbsp_data; mcbsp_data->tx_retry_timer.expires = jiffies + msecs_to_jiffies(OMAP_MCBSP_TX_RETRY_GAP); add_timer(&mcbsp_data->tx_retry_timer); spin_unlock(&mcbsp_data->tx_retry_spinlock); } break; case SNDRV_PCM_TRIGGER_STOP: // TEMPTEMP FOR DEBUGGING!!! s_buffer[s_buffer_cnt] = omap_mcbsp_get_irqstatus(mcbsp_data->bus_id); s_id[s_buffer_cnt] = mcbsp_data->bus_id; s_buffer_cnt = (s_buffer_cnt+1)%1024; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: spin_lock(&mcbsp_data->tx_retry_spinlock); del_timer(&mcbsp_data->tx_retry_timer); spin_unlock(&mcbsp_data->tx_retry_spinlock); omap_mcbsp_stop(mcbsp_data->bus_id, play, !play); mcbsp_data->active--; break; default: err = -EINVAL; } return err; }
static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); int err = 0, play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); switch (cmd) { case SNDRV_PCM_TRIGGER_RESUME: omap_mcbsp_config(mcbsp_data->bus_id, &mcbsp_data->regs); /* fall through */ case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (cpu_dai->active) omap_mcbsp_dai_set_clks_src(mcbsp_data, mcbsp_data->clk_id); omap_mcbsp_start(mcbsp_data->bus_id, play, !play); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) mcbsp_data->tx_active = 1; else mcbsp_data->rx_active = 1; break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_SUSPEND: if (cpu_dai->active) omap_mcbsp_dai_set_clks_src(mcbsp_data, OMAP_MCBSP_SYSCLK_CLKS_FCLK); omap_mcbsp_stop(mcbsp_data->bus_id, play, !play); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) mcbsp_data->tx_active = 0; else mcbsp_data->rx_active = 0; break; default: err = -EINVAL; } return err; }
/* * HW interface start and stop helper functions */ static int audio_ifc_start(void) { omap_mcbsp_start(AUDIO_MCBSP); return 0; }