Beispiel #1
0
static int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params,
				 snd_pcm_hw_param_t var, unsigned int val,
				 int dir)
{
	int changed;
	if (hw_is_mask(var)) {
		struct snd_mask *m = hw_param_mask(params, var);
		if (val == 0 && dir < 0) {
			changed = -EINVAL;
			snd_mask_none(m);
		} else {
			if (dir > 0)
				val++;
			else if (dir < 0)
				val--;
			changed = snd_mask_refine_set(
					hw_param_mask(params, var), val);
		}
	} else if (hw_is_interval(var)) {
		struct snd_interval *i = hw_param_interval(params, var);
		if (val == 0 && dir < 0) {
			changed = -EINVAL;
			snd_interval_none(i);
		} else if (dir == 0)
			changed = snd_interval_refine_set(i, val);
		else {
			struct snd_interval t;
			t.openmin = 1;
			t.openmax = 1;
			t.empty = 0;
			t.integer = 0;
			if (dir < 0) {
				t.min = val - 1;
				t.max = val;
			} else {
				t.min = val;
				t.max = val+1;
			}
			changed = snd_interval_refine(i, &t);
		}
	} else {
		return -EINVAL;
	}
	if (changed) {
		params->cmask |= 1 << var;
		params->rmask |= 1 << var;
	}
	return changed;
}
static void compr_config_hw_params(struct snd_pcm_hw_params *params,
                                   struct snd_compr_params *compr_params)
{
    u64 fmt;
    int acodec_rate = 48000;

    pr_debug("%s\n", __func__);

    fmt = ffs(SNDRV_PCM_FMTBIT_S16_LE) - 1;
    snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), fmt);

    hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min = 16;
    hw_param_interval(params, SNDRV_PCM_HW_PARAM_FRAME_BITS)->min = 32;
    hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min = 2;

#ifdef CONFIG_SND_ESA_SA_EFFECT
    acodec_rate = esa_compr_get_sample_rate();
    if (!acodec_rate)
        acodec_rate = 48000;
#endif

    pr_info("%s input_SR %d PCM_HW_PARAM_RATE %d \n", __func__,
            compr_params->codec.sample_rate, acodec_rate);
    hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min = acodec_rate;
}
static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
				struct snd_pcm_hw_params *params) {

	struct imx_priv *priv = &card_priv;

	hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min = priv->fe_output_rate;
	hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max = priv->fe_output_rate;
	snd_mask_none(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT));
	if (priv->fe_output_width == 16)
		snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
							SNDRV_PCM_FORMAT_S16_LE);
	else
		snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
							SNDRV_PCM_FORMAT_S24_LE);
	return 0;
}
Beispiel #4
0
static int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params,
								 snd_pcm_hw_param_t var, unsigned int val,
								 int dir)
{
	int changed;
	int open = 0;
	if (dir)
	{
		if (dir > 0)
		{
			open = 1;
		}
		else if (dir < 0)
		{
			if (val > 0)
			{
				open = 1;
				val--;
			}
		}
	}
	if (hw_is_mask(var))
		changed = snd_mask_refine_min(hw_param_mask(params, var), val + !!open);
	else if (hw_is_interval(var))
		changed = snd_interval_refine_min(hw_param_interval(params, var), val, open);
	else
		return -EINVAL;
	if (changed)
	{
		params->cmask |= 1 << var;
		params->rmask |= 1 << var;
	}
	return changed;
}
Beispiel #5
0
static int snd_pmac_hw_rule_format(struct snd_pcm_hw_params *params,
				   struct snd_pcm_hw_rule *rule)
{
	struct snd_pmac *chip = rule->private;
	struct pmac_stream *rec = snd_pmac_get_stream(chip, rule->deps[0]);

	if (! rec)
		return -EINVAL;
	return snd_mask_refine_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
				   rec->cur_formats);
}
Beispiel #6
0
static int _snd_pcm_hw_param_mask(struct snd_pcm_hw_params *params,
								  snd_pcm_hw_param_t var,
								  const struct snd_mask *val)
{
	int changed;
	changed = snd_mask_refine(hw_param_mask(params, var), val);
	if (changed)
	{
		params->cmask |= 1 << var;
		params->rmask |= 1 << var;
	}
	return changed;
}
Beispiel #7
0
static int rule_format(struct snd_pcm_hw_params *params,
		       struct snd_pcm_hw_rule *rule)
{

	struct snd_pcm_hardware *hw = rule->private;
	struct snd_mask *maskp = hw_param_mask(params, rule->var);

	maskp->bits[0] &= (u_int32_t)hw->formats;
	maskp->bits[1] &= (u_int32_t)(hw->formats >> 32);
	memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX-64) / 8); 
	if (! maskp->bits[0] && ! maskp->bits[1])
		return -EINVAL;
	return 0;
}
Beispiel #8
0
static int sdm845_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
				struct snd_pcm_hw_params *params)
{
	struct snd_interval *rate = hw_param_interval(params,
					SNDRV_PCM_HW_PARAM_RATE);
	struct snd_interval *channels = hw_param_interval(params,
					SNDRV_PCM_HW_PARAM_CHANNELS);
	struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);

	rate->min = rate->max = DEFAULT_SAMPLE_RATE_48K;
	channels->min = channels->max = 2;
	snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);

	return 0;
}
Beispiel #9
0
static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
			      struct snd_pcm_hw_params *params)
{
	struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
	struct snd_interval *rate;
	struct snd_mask *mask;

	rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
	rate->max = rate->min = priv->asrc_rate;

	mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
	snd_mask_none(mask);
	snd_mask_set(mask, priv->asrc_format);

	return 0;
}
Beispiel #10
0
static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
				struct snd_pcm_hw_params *params) {

	struct imx_priv *priv = &card_priv;
	struct snd_interval *rate;
	struct snd_mask *mask;

	if (!priv->asrc_pdev)
		return -EINVAL;

	rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
	rate->max = rate->min = priv->asrc_rate;

	mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
	snd_mask_none(mask);
	snd_mask_set(mask, priv->asrc_format);

	return 0;
}
static int snd_pcm_ioplug_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
{
	int change = 0, change1, change2, err;
	ioplug_priv_t *io = pcm->private_data;
	struct snd_ext_parm *p;
	unsigned int i;

	/* access, format */
	for (i = SND_PCM_IOPLUG_HW_ACCESS; i <= SND_PCM_IOPLUG_HW_FORMAT; i++) {
		err = snd_ext_parm_mask_refine(hw_param_mask(params, hw_params_type[i]),
					       io->params, i);
		if (err < 0)
			return err;
		change |= err;
	}
	/* channels, rate */
	for (; i <= SND_PCM_IOPLUG_HW_RATE; i++) {
		err = snd_ext_parm_interval_refine(hw_param_interval(params, hw_params_type[i]),
						   io->params, i);
		if (err < 0)
			return err;
		change |= err;
	}

	if (params->rmask & ((1 << SND_PCM_HW_PARAM_ACCESS) |
			     (1 << SND_PCM_HW_PARAM_FORMAT) |
			     (1 << SND_PCM_HW_PARAM_SUBFORMAT) |
			     (1 << SND_PCM_HW_PARAM_CHANNELS) |
			     (1 << SND_PCM_HW_PARAM_RATE))) {
		err = snd_pcm_hw_refine_soft(pcm, params);
		if (err < 0)
			return err;
		change |= err;
	}

	change1 = refine_time_and_size(params, SND_PCM_HW_PARAM_PERIOD_TIME,
				       SND_PCM_HW_PARAM_PERIOD_SIZE,
				       SND_PCM_HW_PARAM_PERIOD_BYTES);
	if (change1 < 0)
		return change1;
	err = snd_ext_parm_interval_refine(hw_param_interval(params, SND_PCM_HW_PARAM_PERIOD_BYTES),
					   io->params, SND_PCM_IOPLUG_HW_PERIOD_BYTES);
	if (err < 0)
		return err;
	change1 |= err;
	if (change1) {
		change |= change1;
		err = refine_back_time_and_size(params, SND_PCM_HW_PARAM_PERIOD_TIME,
						SND_PCM_HW_PARAM_PERIOD_SIZE,
						SND_PCM_HW_PARAM_PERIOD_BYTES);
		if (err < 0)
			return err;
	}

	change1 = refine_time_and_size(params, SND_PCM_HW_PARAM_BUFFER_TIME,
				       SND_PCM_HW_PARAM_BUFFER_SIZE,
				       SND_PCM_HW_PARAM_BUFFER_BYTES);
	if (change1 < 0)
		return change1;
	change |= change1;

	do {
		change2 = 0;
		err = snd_ext_parm_interval_refine(hw_param_interval(params, SND_PCM_HW_PARAM_BUFFER_BYTES),
						   io->params, SND_PCM_IOPLUG_HW_BUFFER_BYTES);
		if (err < 0)
			return err;
		change2 |= err;
		/* periods = buffer_bytes / period_bytes */
		err = rule_div(params, SND_PCM_HW_PARAM_PERIODS,
			       SND_PCM_HW_PARAM_BUFFER_BYTES,
			       SND_PCM_HW_PARAM_PERIOD_BYTES);
		if (err < 0)
			return err;
		change2 |= err;
		err = snd_ext_parm_interval_refine(hw_param_interval(params, SND_PCM_HW_PARAM_PERIODS),
						   io->params, SND_PCM_IOPLUG_HW_PERIODS);
		if (err < 0)
			return err;
		change2 |= err;
		/* buffer_bytes = periods * period_bytes */
		err = rule_mul(params, SND_PCM_HW_PARAM_BUFFER_BYTES,
			       SND_PCM_HW_PARAM_PERIOD_BYTES,
			       SND_PCM_HW_PARAM_PERIODS);
		if (err < 0)
			return err;
		change2 |= err;
		change1 |= change2;
	} while (change2);
	change |= change1;

	if (change1) {
		err = refine_back_time_and_size(params, SND_PCM_HW_PARAM_BUFFER_TIME,
						SND_PCM_HW_PARAM_BUFFER_SIZE,
						SND_PCM_HW_PARAM_BUFFER_BYTES);
		if (err < 0)
			return err;
	}

	/* period_bytes = buffer_bytes / periods */
	err = rule_div(params, SND_PCM_HW_PARAM_PERIOD_BYTES,
		       SND_PCM_HW_PARAM_BUFFER_BYTES,
		       SND_PCM_HW_PARAM_PERIODS);
	if (err < 0)
		return err;
	if (err) {
		/* update period_size and period_time */
		change |= err;
		err = snd_ext_parm_interval_refine(hw_param_interval(params, SND_PCM_HW_PARAM_PERIOD_BYTES),
						   io->params, SND_PCM_IOPLUG_HW_PERIOD_BYTES);
		if (err < 0)
			return err;
		err = refine_back_time_and_size(params, SND_PCM_HW_PARAM_PERIOD_TIME,
						SND_PCM_HW_PARAM_PERIOD_SIZE,
						SND_PCM_HW_PARAM_PERIOD_BYTES);
		if (err < 0)
			return err;
	}

	params->info = SND_PCM_INFO_BLOCK_TRANSFER;
	p = &io->params[SND_PCM_IOPLUG_HW_ACCESS];
	if (p->active) {
		for (i = 0; i < p->num_list; i++)
			switch (p->list[i]) {
			case SND_PCM_ACCESS_MMAP_INTERLEAVED:
			case SND_PCM_ACCESS_RW_INTERLEAVED:
				params->info |= SND_PCM_INFO_INTERLEAVED;
				break;
			case SND_PCM_ACCESS_MMAP_NONINTERLEAVED:
			case SND_PCM_ACCESS_RW_NONINTERLEAVED:
				params->info |= SND_PCM_INFO_NONINTERLEAVED;
				break;
			}
	}
	if (io->data->callback->pause)
		params->info |= SND_PCM_INFO_PAUSE;
	if (io->data->callback->resume)
		params->info |= SND_PCM_INFO_RESUME;

#if 0
	fprintf(stderr, "XXX\n");
	dump_parm(params);
#endif
	return change;
}