Exemplo n.º 1
0
static int config_asrc(struct snd_pcm_substream *substream,
					 struct snd_pcm_hw_params *params)
{
	unsigned int rate = params_rate(params);
	unsigned int channel = params_channels(params);
	unsigned int wordwidth = get_format_width(params);
	struct imx_pcm_runtime_data *pcm_data =
				substream->runtime->private_data;
	struct asrc_config config = {0};
	int ret = 0;

	if (rate <= 32000 || rate == asrc_esai_data.output_sample_rate)
		return -EINVAL;

	if (channel != 2)
		return -EINVAL;

	if (wordwidth != 24)
		return -EINVAL;

	ret = asrc_req_pair(channel, &asrc_esai_data.asrc_index);
	if (ret < 0) {
		pr_err("Fail to request asrc pair\n");
		asrc_release_pair(asrc_esai_data.asrc_index);
		asrc_finish_conv(asrc_esai_data.asrc_index);
		return -EINVAL;
	}

	config.pair = asrc_esai_data.asrc_index;
	config.channel_num = channel;
	config.input_sample_rate = rate;
	config.output_sample_rate = asrc_esai_data.output_sample_rate;
	config.inclk = OUTCLK_ASRCK1_CLK;
	config.word_width = wordwidth;
	config.outclk = OUTCLK_ESAI_TX;

	ret = asrc_config_pair(&config);
	if (ret < 0) {
		pr_err("Fail to config asrc\n");
		asrc_release_pair(asrc_esai_data.asrc_index);
		asrc_finish_conv(asrc_esai_data.asrc_index);
		return ret;
	}
	pcm_data->asrc_index = asrc_esai_data.asrc_index;
	pcm_data->asrc_enable = 1;

	return 0;
}
Exemplo n.º 2
0
static long asrc_ioctl_release_pair(struct asrc_pair_params *params,
				void __user *user)
{
	enum asrc_pair_index index;
	unsigned long lock_flags;
	long ret;

	ret = copy_from_user(&index, user, sizeof(index));
	if (ret) {
		dev_err(asrc->dev, "failed to get index from user space: %ld\n", ret);
		return ret;
	}

	/* index might be not valid due to some application failure. */
	if (index < 0)
		return -EINVAL;

	params->asrc_active = 0;

	spin_lock_irqsave(&pair_lock, lock_flags);
	params->pair_hold = 0;
	spin_unlock_irqrestore(&pair_lock, lock_flags);

	if (params->input_dma_channel)
		dma_release_channel(params->input_dma_channel);
	if (params->output_dma_channel)
		dma_release_channel(params->output_dma_channel);
	mxc_free_dma_buf(params);
	asrc_release_pair(index);
	asrc_finish_conv(index);

	return 0;
}
Exemplo n.º 3
0
static void imx_3stack_shutdown(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;

	if (asrc_support) {
		struct snd_soc_dai *codec_dai = rtd->codec_dai;
		struct imx_pcm_runtime_data *pcm_data =
				substream->runtime->private_data;
		if (pcm_data->asrc_enable) {
			asrc_release_pair(asrc_esai_data.asrc_index);
			asrc_finish_conv(asrc_esai_data.asrc_index);
		}
		pcm_data->asrc_enable = 0;
		asrc_esai_data.asrc_index = -1;

		codec_dai->driver->playback.rates =
				asrc_esai_data.codec_dai_rates;
		cpu_dai->driver->playback.rates =
				asrc_esai_data.cpu_dai_rates;
	}

	if (!cpu_dai->active)
		hw_state.hw = 0;
}
Exemplo n.º 4
0
static int imx_3stack_surround_hw_free(struct snd_pcm_substream *substream)
{
    struct imx_pcm_runtime_data *iprtd = substream->runtime->private_data;

    if (iprtd->asrc_enable) {
        if (iprtd->asrc_index != -1) {
            asrc_release_pair(iprtd->asrc_index);
            asrc_finish_conv(iprtd->asrc_index);
        }
        iprtd->asrc_index = -1;
    }

    return 0;
}
Exemplo n.º 5
0
static int mxc_asrc_close(struct inode *inode, struct file *file)
{
	struct asrc_pair_params *params;
	unsigned long lock_flags;

	params = file->private_data;

	if (!params)
		return 0;

	if (params->asrc_active) {
		params->asrc_active = 0;

		dmaengine_terminate_all(params->input_dma_channel);
		dmaengine_terminate_all(params->output_dma_channel);

		asrc_stop_conv(params->index);

		complete(&params->input_complete);
		complete(&params->output_complete);
		complete(&params->lastperiod_complete);
	}

	if (params->pair_hold) {
		spin_lock_irqsave(&pair_lock, lock_flags);
		params->pair_hold = 0;
		spin_unlock_irqrestore(&pair_lock, lock_flags);

		if (params->input_dma_channel)
			dma_release_channel(params->input_dma_channel);
		if (params->output_dma_channel)
			dma_release_channel(params->output_dma_channel);

		mxc_free_dma_buf(params);

		asrc_release_pair(params->index);
		asrc_finish_conv(params->index);
	}

	kfree(params);
	file->private_data = NULL;

	return 0;
}