Beispiel #1
0
static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct tegra_runtime_data *prtd = runtime->private_data;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct tegra_pcm_dma_params * dmap;

	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);

	dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
	if (dmap) {
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
			setup_dma_tx_request(&prtd->dma_req[0], dmap);
			setup_dma_tx_request(&prtd->dma_req[1], dmap);
		} else {
			setup_dma_rx_request(&prtd->dma_req[0], dmap);
			setup_dma_rx_request(&prtd->dma_req[1], dmap);
		}
	}
	prtd->dma_req[0].size = params_period_bytes(params);
	prtd->dma_req[1].size = prtd->dma_req[0].size;

	return 0;
}
Beispiel #2
0
static int tegra_pcm_open(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct tegra_runtime_data *prtd;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct tegra_pcm_dma_params * dmap;
	int ret = 0;

	prtd = kzalloc(sizeof(struct tegra_runtime_data), GFP_KERNEL);
	if (prtd == NULL)
		return -ENOMEM;

	runtime->private_data = prtd;
	prtd->substream = substream;

	spin_lock_init(&prtd->lock);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
		setup_dma_tx_request(&prtd->dma_req[0], dmap);
		setup_dma_tx_request(&prtd->dma_req[1], dmap);
	} else {
		dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
		setup_dma_rx_request(&prtd->dma_req[0], dmap);
		setup_dma_rx_request(&prtd->dma_req[1], dmap);
	}

	prtd->dma_req[0].dev = prtd;
	prtd->dma_req[1].dev = prtd;

	prtd->dma_chan = tegra_dma_allocate_channel(TEGRA_DMA_MODE_CONTINUOUS_SINGLE);
	if (prtd->dma_chan == NULL) {
		ret = -ENOMEM;
		goto err;
	}

	/* Set HW params now that initialization is complete */
	snd_soc_set_runtime_hwparams(substream, &tegra_pcm_hardware);

	/* Ensure that buffer size is a multiple of period size */
	ret = snd_pcm_hw_constraint_integer(runtime,
						SNDRV_PCM_HW_PARAM_PERIODS);
	if (ret < 0)
		goto err;

	return 0;

err:
	if (prtd->dma_chan) {
		tegra_dma_free_channel(prtd->dma_chan);
	}

	kfree(prtd);

	return ret;
}
Beispiel #3
0
int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct tegra_runtime_data *prtd = runtime->private_data;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct tegra_pcm_dma_params * dmap;
	int i;

	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);

	/* Limit dma_req_count to period count */
	if (prtd->dma_req_count > params_periods(params))
		prtd->dma_req_count = params_periods(params);
	dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
	if (dmap) {
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
			for (i = 0; i < prtd->dma_req_count; i++)
				setup_dma_tx_request(&prtd->dma_req[i], dmap);
		} else {
			for (i = 0; i < prtd->dma_req_count; i++)
				setup_dma_rx_request(&prtd->dma_req[i], dmap);
		}
	}
	for (i = 0; i < prtd->dma_req_count; i++)
		prtd->dma_req[i].size = params_period_bytes(params);

	return 0;
}
static int tegra_pcm_open(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct tegra_runtime_data *prtd;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct tegra_pcm_dma_params * dmap;
	int ret = 0;

	prtd = kzalloc(sizeof(struct tegra_runtime_data), GFP_KERNEL);
	if (prtd == NULL)
		return -ENOMEM;

	runtime->private_data = prtd;
	prtd->substream = substream;

	spin_lock_init(&prtd->lock);

	dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);

	if (dmap) {
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
			setup_dma_tx_request(&prtd->dma_req[0], dmap);
			setup_dma_tx_request(&prtd->dma_req[1], dmap);
		} else {
			setup_dma_rx_request(&prtd->dma_req[0], dmap);
			setup_dma_rx_request(&prtd->dma_req[1], dmap);
		}

		prtd->dma_req[0].dev = prtd;
		prtd->dma_req[1].dev = prtd;

		prtd->dma_chan = tegra_dma_allocate_channel(
					TEGRA_DMA_MODE_CONTINUOUS_SINGLE,
					"pcm");
		if (prtd->dma_chan == NULL) {
			ret = -ENOMEM;
			goto err;
		}
	}

	/* Set HW params now that initialization is complete */
	snd_soc_set_runtime_hwparams(substream, &tegra_pcm_hardware);

	/* Ensure period size is multiple of 8 */
	ret = snd_pcm_hw_constraint_step(runtime, 0,
		SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 0x8);
	if (ret < 0)
		goto err;

	/* Ensure that buffer size is a multiple of period size */
	ret = snd_pcm_hw_constraint_integer(runtime,
						SNDRV_PCM_HW_PARAM_PERIODS);
	if (ret < 0)
		goto err;

#ifdef CONFIG_HAS_WAKELOCK
	snprintf(prtd->tegra_wake_lock_name, sizeof(prtd->tegra_wake_lock_name),
		"tegra-pcm-%s-%d",
		(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? "out" : "in",
		substream->pcm->device);
	wake_lock_init(&prtd->tegra_wake_lock, WAKE_LOCK_SUSPEND,
		prtd->tegra_wake_lock_name);
#endif

	return 0;

err:
	if (prtd->dma_chan) {
		tegra_dma_free_channel(prtd->dma_chan);
	}

	kfree(prtd);

	return ret;
}
Beispiel #5
0
static int tegra_pcm_open(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct tegra_runtime_data *prtd;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct tegra_pcm_dma_params * dmap;
	int ret = 0;

	prtd = kzalloc(sizeof(struct tegra_runtime_data), GFP_KERNEL);
	if (prtd == NULL)
		return -ENOMEM;

	init_timer(&prtd->pcm_timeout);
	prtd->callback_time = 0;
	
	runtime->private_data = prtd;
	prtd->substream = substream;

	spin_lock_init(&prtd->lock);

	dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);

	if (dmap) {
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
			setup_dma_tx_request(&prtd->dma_req[0], dmap);
			setup_dma_tx_request(&prtd->dma_req[1], dmap);
		} else {
			setup_dma_rx_request(&prtd->dma_req[0], dmap);
			setup_dma_rx_request(&prtd->dma_req[1], dmap);
		}

		prtd->dma_req[0].dev = prtd;
		prtd->dma_req[1].dev = prtd;

		prtd->dma_chan = tegra_dma_allocate_channel(
					TEGRA_DMA_MODE_CONTINUOUS_SINGLE,
					"pcm");
		if (prtd->dma_chan == NULL) {
			ret = -ENOMEM;
			goto err;
		}
	}

	snd_soc_set_runtime_hwparams(substream, &tegra_pcm_hardware);

	ret = snd_pcm_hw_constraint_step(runtime, 0,
		SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 0x8);
	if (ret < 0)
		goto err;

	ret = snd_pcm_hw_constraint_integer(runtime,
						SNDRV_PCM_HW_PARAM_PERIODS);
	if (ret < 0)
		goto err;

	return 0;

err:
	if (prtd->dma_chan) {
		tegra_dma_free_channel(prtd->dma_chan);
	}

	kfree(prtd);

	return ret;
}