Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #5
0
/*
 * HW interface start and stop helper functions
 */
static int audio_ifc_start(void)
{
	omap_mcbsp_start(AUDIO_MCBSP);
	return 0;
}