Cannot manually control ArduCAM 64MP focus on Raspberry Pi 4 via v4l2

Hi, I’m trying to manually adjust the focus on my ArduCAM 64MP camera and I just can’t get it to work.

My setup:

  • Camera: ArduCAM 64MP
  • Board: Raspberry Pi 4
  • Driver: 64mp_pi_hawk_eye_kernel_driver
  • I2C bus: 10 (the same bus used by install_privariety_pkgs.sh)
  • The required configuration is written into /boot/config.txt

I tried two approaches to control focus:

  1. v4l2-ctl setting focus_absolute
  2. ArduCAM’s provided focuser script (Arducam-Pivariety-V4L2-Driver/focus at master · ArduCAM/Arducam-Pivariety-V4L2-Driver · GitHub)

Both just fail with no reason reported.

Running:
i2cset -y 10 0x0c 0x02 0x00

gives me:
Error: Could not set address to 0x0c: Device or resource busy

And after I ran the “switch channel” commands, I can’t even take photos with libcamera-still anymore:
Failed to start streaming: Input/output error
ERROR: *** failed to start camera ***

v4l2-ctl -l doesn’t even list the focus_absolute control, and shows no error even in verbose mode. Weirdly, the camera CAN auto-focus on its own via libcamera-still --autofocus. Any idea what’s going on?

Thanks for all the detail. Let’s narrow this down. Can you send me:

  1. Which program is running when the error shows up
  2. A screenshot of the error message
  3. The output of cat /boot/config.txt

Also, can you confirm the I2C bus you’re using is definitely bus 10? That’s the bus the driver installer sets up, so it should match.

One thing to keep in mind: there’s been a change in libcamera recently. It is no longer exposed through /dev/video*, so the control path via v4l2 may not apply the way it used to. Let’s confirm your config before we go further.

Bus is definitely 10, that matches the installer.

Here’s cat /boot/config.txt:
dtparam=i2c_vc=on
dtparam=i2c_arm=on
dtoverlay=…
(the required lines are there, I wrote them in following the example)

I ran v4l2-ctl -l and also with verbose — no error, but focus_absolute is simply not in the list.

Then I followed Arducam’s focuser example (RaspberryPi/Motorized_Focus_Camera at master · ArduCAM/RaspberryPi · GitHub) and got:
OSError: [Errno 25] Inappropriate ioctl for device

thrown right at this line:
fcntl.ioctl(fd, v4l2.VIDIOC_QUERYCTRL, queryctrl)

Also, PrintCamera has no value stored when the driver was installed. There’s no other program running — same error after a fresh reboot. The python script only runs the command that’s printed on the output.

Okay, that helps a lot. A couple of things stand out here.

First, the directories/scripts you’re running don’t look like they match the ones in the link I sent. Please double-check you’re using exactly those files.

Second, I suspect something is off with your config.txt. The specific step for enabling i2c may not have actually been performed — and that step needs a reboot afterward to take effect.

We’ve updated the script to fix the issue. You can reference the updated page here:
https://www.arducam.com/docs/cameras-for-raspberry-pi/64mp-camera-for-raspberry-pi/how-to-use-arducam-64mp-camera-on-rapberry-pi/#manual-focus-adjustment

Please try that, and also test whether the cameras work fine when set at the lowest resolution, so we can rule out any issue with the cameras themselves.

I did the config.txt step and rebooted, but it’s the same. i2cset -y 10 0x0c 0x02 0x00 still gives ‘Device or resource busy’.

But now I’m confused. You told me there’s been a change in libcamera, it is no longer from /dev/video*, so the control of v4l2 is no longer used. Yet the updated script you gave me still relies on v4l2 control. Which approach is actually correct to control the device?

Auto-focus still works fine via libcamera-still --autofocus, so the camera itself seems okay.

Good question, let me clear that up.

Because of the libcamera change, the v4l2 control is deprecated now — you need to control the focus through libcamera instead. The libcamera-based control program is here:

For the i2c side, please make sure the config.txt step to enable i2c is applied, then reboot and try again.

If it’s still failing after that, we can do an online remote session. I’ve sent you the remote support details privately, please check your messages.

Tried everything again with the updated script and after a reboot. Still no luck:

  • i2cset: “Error: Could not set address to 0x0c: Device or resource busy”
  • focuser script: “OSError: [Errno 25] Inappropriate ioctl for device” at the VIDIOC_QUERYCTRL line
  • focus_absolute is still not listed in v4l2-ctl -l

What else can I check on my side? I can join the remote session, just let me know what to prepare.

For the i2c channel switching, run these:

Set to single channel 0

i2cset -y 10 0x24 0x24 0x02

Set to single channel 1

i2cset -y 10 0x24 0x24 0x12

Set to single channel 2

i2cset -y 10 0x24 0x24 0x22

Set to single channel 3

i2cset -y 10 0x24 0x24 0x32

Set to double channel (single channel 0 and single channel 1)

i2cset -y 10 0x24 0x24 0x01

Set to double channel (single channel 2 and single channel 3)

i2cset -y 10 0x24 0x24 0x11

Set to four in one mode (Default)

i2cset -y 10 0x24 0x24 0x00

And yes, bus 10 is the correct bus — it’s the one the driver installer (install_privariety_pkgs.sh) sets up, matching your configuration.

Then do the config.txt step to enable i2c, reboot, and try again.

To help us further, please provide:

  1. Which program is running
  2. A screenshot of the error message
  3. cat /boot/config.txt

Where we stand: auto-focus works via libcamera-still --autofocus, but manual focus fails both through v4l2 (focus_absolute not listed) and via the Arducam focuser script (Inappropriate ioctl for device at VIDIOC_QUERYCTRL). Arducam confirms the libcamera change — it’s no longer /dev/video*, so v4l2 control is deprecated and you should use the libcamera-based program (RaspberryPi/Motorized_Focus_Camera at master · ArduCAM/RaspberryPi · GitHub). We’ve also updated the focuser script and the matching reference page. If it still fails after applying the config.txt i2c step and rebooting, we’ll go ahead with the remote session.