@@ -238,25 +238,6 @@ int32_t IpaBase::configure(const IPACameraSensorInfo &sensorInfo, const ConfigPa
238238 agcStatus.analogueGain = defaultAnalogueGain;
239239 applyAGC (&agcStatus, ctrls);
240240
241- /*
242- * Set the lens to the default (typically hyperfocal) position
243- * on first start.
244- */
245- if (lensPresent_) {
246- RPiController::AfAlgorithm *af =
247- dynamic_cast <RPiController::AfAlgorithm *>(controller_.getAlgorithm (" af" ));
248-
249- if (af) {
250- float defaultPos =
251- ipaAfControls.at (&controls::LensPosition).def ().get <float >();
252- ControlList lensCtrl (lensCtrls_);
253- int32_t hwpos;
254-
255- af->setLensPosition (defaultPos, &hwpos);
256- lensCtrl.set (V4L2_CID_FOCUS_ABSOLUTE, hwpos);
257- result->lensControls = std::move (lensCtrl);
258- }
259- }
260241 }
261242
262243 result->sensorControls = std::move (ctrls);
@@ -286,8 +267,20 @@ int32_t IpaBase::configure(const IPACameraSensorInfo &sensorInfo, const ConfigPa
286267 ctrlMap.merge (ControlInfoMap::Map (ipaColourControls));
287268
288269 /* Declare Autofocus controls, only if we have a controllable lens */
289- if (lensPresent_)
270+ if (lensPresent_) {
290271 ctrlMap.merge (ControlInfoMap::Map (ipaAfControls));
272+ RPiController::AfAlgorithm *af =
273+ dynamic_cast <RPiController::AfAlgorithm *>(controller_.getAlgorithm (" af" ));
274+ if (af) {
275+ double min, max, dflt;
276+ af->getLensLimits (min, max);
277+ dflt = af->getDefaultLensPosition ();
278+ ctrlMap[&controls::LensPosition] =
279+ ControlInfo (static_cast <float >(min),
280+ static_cast <float >(max),
281+ static_cast <float >(dflt));
282+ }
283+ }
291284
292285 result->controlInfo = ControlInfoMap (std::move (ctrlMap), controls::controls);
293286
@@ -325,6 +318,26 @@ void IpaBase::start(const ControlList &controls, StartResult *result)
325318 /* Make a note of this as it tells us the HDR status of the first few frames. */
326319 hdrStatus_ = agcStatus.hdr ;
327320
321+ /*
322+ * AF: If no lens position was specified, drive lens to a default position.
323+ * This had to be deferred (not initialised by a constructor) until here
324+ * to ensure that exactly ONE starting position is sent to the lens driver.
325+ * It should be the static API default, not dependent on AF range or mode.
326+ */
327+ if (firstStart_ && lensPresent_) {
328+ RPiController::AfAlgorithm *af = dynamic_cast <RPiController::AfAlgorithm *>(
329+ controller_.getAlgorithm (" af" ));
330+ if (af && !af->getLensPosition ()) {
331+ int32_t hwpos;
332+ double pos = af->getDefaultLensPosition ();
333+ if (af->setLensPosition (pos, &hwpos, true )) {
334+ ControlList lensCtrls (lensCtrls_);
335+ lensCtrls.set (V4L2_CID_FOCUS_ABSOLUTE, hwpos);
336+ setLensControls.emit (lensCtrls);
337+ }
338+ }
339+ }
340+
328341 /*
329342 * Initialise frame counts, and decide how many frames must be hidden or
330343 * "mistrusted", which depends on whether this is a startup from cold,
0 commit comments