Skip to content

Commit 9de7bc2

Browse files
ukleineknunojsa
authored andcommitted
iio: adc: ad_pulsar: Specify PWM parameters in nanoseconds
With the reference clock running at less than 1 GHz two different settings for the used PWM differ by more than 1 ns. So there is no advantage to differ from the upstream pwm subsystem and give the illusion of pico second resolution. With the goal to drop support for time_unit, don't explicitly set .time_unit = PWM_UNIT_NSEC but rely on this being the default. Also improve precision in the period calculation by not multiplying the result of two divisions but a single (reduced) division. Further use up-rounding instead of round-to-nearest to make the driver robust to rounding changes in the axi-pwmgen driver and to make freq a hard upper limit on sample frequency. Upstream pwm drivers are expected to round down requested values in pwm_apply_state(). There is a potential error introduced by changing the rounding here until the axi-pwmgen driver is aligned to mainline requirements. This error is however in the same order as the already existing one that is introduced by the integer divisions. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
1 parent eeeebf8 commit 9de7bc2

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

drivers/iio/adc/ad_pulsar.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -423,28 +423,30 @@ static int ad_pulsar_reg_access(struct iio_dev *indio_dev, unsigned int reg,
423423

424424
static int ad_pulsar_set_samp_freq(struct ad_pulsar_adc *adc, int freq)
425425
{
426-
unsigned long long target, ref_clk_period_ps;
426+
unsigned long long ref_clk_period_ns;
427427
struct pwm_state cnv_state;
428428
int ret;
429429

430+
/*
431+
* The objective here is to configure the PWM such that we don't have
432+
* more than $freq periods per second and duty_cycle and phase should be
433+
* their minimal positive value.
434+
*/
430435
freq = clamp(freq, 1, adc->info->max_rate);
431-
target = DIV_ROUND_CLOSEST_ULL(adc->ref_clk_rate, freq);
432-
ref_clk_period_ps = DIV_ROUND_CLOSEST_ULL(1000000000000,
433-
adc->ref_clk_rate);
436+
ref_clk_period_ns = DIV_ROUND_UP(NSEC_PER_SEC, adc->ref_clk_rate);
434437

435438
cnv_state = (struct pwm_state){
436-
.period = ref_clk_period_ps * target,
437-
.duty_cycle = ref_clk_period_ps,
438-
.phase = ref_clk_period_ps,
439-
.time_unit = PWM_UNIT_PSEC,
439+
.period = DIV_ROUND_UP(NSEC_PER_SEC, freq),
440+
.duty_cycle = ref_clk_period_ns,
441+
.phase = ref_clk_period_ns,
440442
.enabled = true,
441443
};
442444

443445
ret = pwm_apply_state(adc->cnv, &cnv_state);
444446
if (ret)
445447
return ret;
446448

447-
adc->samp_freq = DIV_ROUND_CLOSEST_ULL(adc->ref_clk_rate, target);
449+
adc->samp_freq = freq;
448450

449451
return ret;
450452
}

0 commit comments

Comments
 (0)