[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <175969431602.1246375.2429212814766056041@ping.linuxembedded.co.uk>
Date: Sun, 05 Oct 2025 20:58:36 +0100
From: Kieran Bingham <kieran.bingham@...asonboard.com>
To: Aliaksandr Smirnou <asmirnou@...efeat.co.uk>
Cc: asmirnou@...efeat.co.uk, conor+dt@...nel.org, devicetree@...r.kernel.org, hverkuil@...all.nl, jacopo.mondi@...asonboard.com, krzk+dt@...nel.org, linux-kernel@...r.kernel.org, linux-media@...r.kernel.org, mchehab@...nel.org, robh@...nel.org
Subject: Re: [PATCH v5 2/2] media: i2c: Pinefeat cef168 lens control board driver
Quoting Aliaksandr Smirnou (2025-10-05 19:00:25)
> Hi Kieran,
>
> On Sun, 05 Oct 2025 15:32:45 +0100, Kieran Bingham wrote:
> > I'm really looking forward to trying this device out sometime. Very
> > interesting piece of kit - Thank you for working directly to upstream
> > the support! That's really awesome.
>
> Thanks! I appreciate that. It's been interesting work, and it's great
> to see the device getting some attention. I'm looking forward to hearing
> your impressions once you get a chance to try it out.
>
> > > + rx_data->focus_distance_min = le16_to_cpup((__le16 *)&rx_data->focus_distance_min);
> > > + rx_data->focus_distance_max = le16_to_cpup((__le16 *)&rx_data->focus_distance_max);
> >
> > What is the focus distance in this case? Is it a measured distance that
> > could be applied to focus?
>
> The focus distance reported by the lens is the distance between the
> camera's sensor and the subject currently in focus, measured in meters.
> It correlates with the focus position - higher positions correspond to
> greater distances - but the relationship is non-linear.
What's measuring this distance ? Something in the lens, rather than the
sensor?
>
> Libcamera's autofocus algorithm works in dioptres, which are the inverse
> of distance. In the driver, reading the distance from the lens allows
> the creation of a piecewise linear (PWL) function that maps inverse
> distance to the hardware lens setting.
>
> > > + case CEF168_V4L2_CID_CUSTOM(calibrate):
> > > + return cef168_i2c_write(dev, INP_CALIBRATE, 0);
> >
> > Is there any documentation on how to use this control?
>
> The control performs a calibration action operated by the controller
> to determine the total number of focus steps. The action is invoked
> by the calibration utility, which moves the lens, reads the changing
> focus distance, and finally generates a PWL function to be included
> in the Libcamera tuning file.
>
> End users are not expected to trigger this control manually through
> the V4L2 API, as it is intended for use by the calibration tool during
> system setup. For this reason, separate user-facing documentation for
> the control has not been added.
>
> In other use cases, calibration can be performed simply by toggling
> the AF/MF switch on the lens three times within 15 seconds.
>
> > > + case CEF168_V4L2_CID_CUSTOM(focus_range):
> > > + ctrl->p_new.p_u32[0] = ((u32)data.focus_position_min << 16) |
> > > + (u32)data.focus_position_max;
> >
> > Is this really a custom control ? Is there any way to convey this
> > through the min/max of the FOCUS_ABSOLUTE control ?
>
> We aimed to minimize the use of custom controls, but in this case one
> is necessary.
>
> When the driver is already loaded and initialized, the focus range of
> the lens may vary depending on the lens state and configuration
> options. Because the control's operational range is defined during
> driver probe, the Linux V4L2 API does not allow the minimum and
> maximum values to be changed while the driver is running.
Have you tried with __v4l2_ctrl_modify_range() ?
We should make sure this also generates an event that libcamera can
subscribe to to make sure it knows there's been an update.
> The maximum focus position is not known until calibration is
> performed, so initially the position is set to zero. The focus range
> may vary slightly between calibration runs, as it is derived from
> counting motor steps, and its precision depends on the lens's focusing
> mechanics.
>
> Additionally, some lenses provide a two-position switch that changes
> the minimum focusing distance, significantly reducing the focus range
> - for example, from 2100 to 800.
I see, so a user interaction can update it too. Does the driver have to
poll to get this update? Or does it just find out on the next read ?
>
> > > + case CEF168_V4L2_CID_CUSTOM(lens_id):
> > > + ctrl->p_new.p_u8[0] = data.lens_id;
> > > + return 0;
> >
> > Is this a specific individual ID value for the connected lens (i.e.
> > every lens has a custom id?) or is it a reference to the lens
> > model/type?
> >
> > Is this something we could use in libcamera for instance to select an
> > appropriate tuning file per lens (type) ?
>
> It represents the ID of the lens model/type. Correct, it's purpose to
> assist in selecting the appropriate autofocus algorithm settings.
We're also pushing for a core control for this I think. That's something
we 'need' in libcamera globally for all cameras. Unfortunately I can't
point you at an existing control yet ;-(
> For calibrated lenses, the controller stores the focus range in EEPROM,
> allowing lenses to be swapped without repeating calibration. The
> Libcamera tuning file includes an autofocus algorithm section that is
> linked to the lens's focus range, focus distance, and focusing speed.
> Therefore, reading the lens ID when loading the corresponding tuning
> file after a lens swap is both convenient and necessary.
>
> It can be read as follows:
>
> v4l2-ctl -d /dev/v4l-subdev3 -C lens_id
I'll see if I can find time to order a kit, and get a compatible lens. I
have a Nikon DSLR though so I don't have lenses to match this yet :-(
--
Kieran
Powered by blists - more mailing lists