Re: [PATCH v4 08/14] iio: adc: ad7768: Add per-channel conversion delay

Andy Shevchenko <[email protected]>
Newsgroups org.kernel.vger.linux-iio,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-doc,org.kernel.vger.linux-gpio,org.kernel.vger.linux-kernel
Organization Intel Finland Oy - BIC 0357606-4 - c/o Alberga Business Park, 6 krs, Bertel Jungin Aukio 5, 02600 Espoo
Message-ID <[email protected]>
On Fri, Aug 21, 2026 at 04:07:01PM +0200, Janani Sunil wrote:
> Expose the per-channel synchronization phase offset through the IIO
> conversion-delay attribute.
> 
> Derive the delay resolution from MCLK, power mode and decimation rate.
> Validate the requested delay and program the corresponding phase
> register when applying the active channel configuration.

...

> +static int ad7768_get_convdelay_params(struct ad7768_state *st, unsigned int ch,
> +				       struct ad7768_convdelay_params *params)
> +{
> +	struct ad7768_freq_config f_cfg;
> +	unsigned int dec_rate;
> +	unsigned int mclk_div;
> +	unsigned int mult;
> +	u64 mclk;
> +	int ret;
> +
> +	ret = ad7768_get_freq_cfg(st, st->ch_freq[ch], &f_cfg);
> +	if (ret)
> +		return ret;
> +
> +	dec_rate = ad7768_dec_rate[f_cfg.dec_rate];
> +	switch (dec_rate) {
> +	case 32:
> +		params->shift = 3;
> +		params->max_raw = 31;
> +		mult = 1;
> +		break;
> +	case 64:
> +		params->shift = 2;
> +		params->max_raw = 63;
> +		mult = 1;
> +		break;
> +	case 128:
> +		params->shift = 1;
> +		params->max_raw = 127;
> +		mult = 1;
> +		break;
> +	case 256:
> +		params->shift = 0;
> +		params->max_raw = 255;
> +		mult = 1;
> +		break;
> +	case 512:
> +		params->shift = 0;
> +		params->max_raw = 255;
> +		mult = 2;
> +		break;
> +	case 1024:
> +		params->shift = 0;
> +		params->max_raw = 255;
> +		mult = 4;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}

So, this is just a bit twiddling of the dec_rate.

Can be written like

	/* Optional, perhaps shouldn't appear */
	if (!dec_rate)
		return -EINVAL;

	/* Same? What does table allow to have? */
	if (!is_power_of_two(dec_rate))
		return -EINVAL;

	mult = ilog2(dec_rate);
	if (mult > 10) {
		return -EINVAL;
	} else if (mult > 8) {
		params->shift = 0;
		params->max_raw = 255;
		mult = BIT(mult - 8);
	} else if (mult > 5) {
		params->shift = 8 - mult;
		params->max_raw = dec_rate - 1;
		mult = 1;
	} else {
		return -EINVAL;
	}

TBH, I don't know which looks easier to read. It all depends on what datasheet
says about these parameters and multiplier and what the table allows to have.

> +	mclk = clk_get_rate(st->mclk);
> +	if (!mclk)
> +		return -EINVAL;
> +
> +	mclk_div = ad7768_power_modes[st->power_mode_idx].mclk_div;
> +	params->step_ps = DIV_ROUND_CLOSEST_ULL((u64)mult * PSEC_PER_SEC *
> +						mclk_div, mclk);
> +
> +	return 0;
> +}

-- 
With Best Regards,
Andy Shevchenko
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.