Пример #1
0
/* Only used for Ideal Ratio mode */
static int asrc_set_clock_ratio(enum asrc_pair_index index,
				int inrate, int outrate)
{
	unsigned long val = 0;
	int integ, i;

	if (outrate == 0) {
		dev_err(asrc->dev, "wrong output sample rate: %d\n", outrate);
		return -EINVAL;
	}

	/* Formula: r = (1 << ASRC_RATIO_DECIMAL_DEPTH) / outrate * inrate; */
	for (integ = 0; inrate >= outrate; integ++)
		inrate -= outrate;

	val |= (integ << ASRC_RATIO_DECIMAL_DEPTH);

	for (i = 1; i <= ASRC_RATIO_DECIMAL_DEPTH; i++) {
		if ((inrate * 2) >= outrate) {
			val |= (1 << (ASRC_RATIO_DECIMAL_DEPTH - i));
			inrate = inrate * 2 - outrate;
		} else
			inrate = inrate << 1;

		if (inrate == 0)
			break;
	}

	regmap_write(asrc->regmap, REG_ASRIDRL(index), val);
	regmap_write(asrc->regmap, REG_ASRIDRH(index), (val >> 24));

	return 0;
}
Пример #2
0
/**
 * Calculate and set the ratio for Ideal Ratio mode only
 *
 * The ratio is a 32-bit fixed point value with 26 fractional bits.
 */
static int fsl_asrc_set_ideal_ratio(struct fsl_asrc_pair *pair,
				    int inrate, int outrate)
{
	struct fsl_asrc *asrc_priv = pair->asrc_priv;
	enum asrc_pair_index index = pair->index;
	unsigned long ratio;
	int i;

	if (!outrate) {
		pair_err("output rate should not be zero\n");
		return -EINVAL;
	}

	/* Calculate the intergal part of the ratio */
	ratio = (inrate / outrate) << IDEAL_RATIO_DECIMAL_DEPTH;

	/* ... and then the 26 depth decimal part */
	inrate %= outrate;

	for (i = 1; i <= IDEAL_RATIO_DECIMAL_DEPTH; i++) {
		inrate <<= 1;

		if (inrate < outrate)
			continue;

		ratio |= 1 << (IDEAL_RATIO_DECIMAL_DEPTH - i);
		inrate -= outrate;

		if (!inrate)
			break;
	}

	regmap_write(asrc_priv->regmap, REG_ASRIDRL(index), ratio);
	regmap_write(asrc_priv->regmap, REG_ASRIDRH(index), ratio >> 24);

	return 0;
}