On Sun, May 16, 2021 at 4:09 AM Seongyong Park <euphoriccatface@xxxxxxxxx> wrote: > > Current implementation calculates frame delay based on the time of > start of the loop. This inevitably causes the loop delay to be > slightly longer than the actual measurement period, thus skipping a frame > every now and then. > > However, MLX90640 should ideally be working without a frame skip. > Each measurement step updates half of the pixels in the frame > (every other pixel in default "chess mode", and every other row > in "interleave mode"), while additional coefficient data (25th & 26th row) > updates every step. The compensational coefficient data only corresponds > with the pixels updated in the same step. > > In short, if a frame is skipped, then half of a frame loses correction > information and becomes garbage data. This changeset makes sense to me. Guess I got lucky with the timing on my board. Reviewed-by: Matt Ranostay <matt.ranostay@xxxxxxxxxxxx> > > Signed-off-by: Seongyong Park <euphoriccatface@xxxxxxxxx> > --- > drivers/media/i2c/video-i2c.c | 11 ++++++----- > 1 file changed, 6 insertions(+), 5 deletions(-) > > diff --git a/drivers/media/i2c/video-i2c.c b/drivers/media/i2c/video-i2c.c > index 0465832a4..2ccb08335 100644 > --- a/drivers/media/i2c/video-i2c.c > +++ b/drivers/media/i2c/video-i2c.c > @@ -445,14 +445,16 @@ static int video_i2c_thread_vid_cap(void *priv) > struct video_i2c_data *data = priv; > unsigned int delay = mult_frac(HZ, data->frame_interval.numerator, > data->frame_interval.denominator); > + unsigned long end_jiffies = jiffies; > > set_freezable(); > > do { > - unsigned long start_jiffies = jiffies; > struct video_i2c_buffer *vid_cap_buf = NULL; > int schedule_delay; > > + end_jiffies += delay; > + > try_to_freeze(); > > spin_lock(&data->slock); > @@ -477,10 +479,9 @@ static int video_i2c_thread_vid_cap(void *priv) > VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE); > } > > - schedule_delay = delay - (jiffies - start_jiffies); > - > - if (time_after(jiffies, start_jiffies + delay)) > - schedule_delay = delay; > + schedule_delay = end_jiffies - jiffies; > + while (schedule_delay <= 0) > + schedule_delay += delay; > > schedule_timeout_interruptible(schedule_delay); > } while (!kthread_should_stop()); > -- > 2.31.1 >