Can't use ioctl() to control a device owned by kernel module?

Hi!

I failed to use C/C++ to access the image sensor OV5645's register on my system via I2C bus. Below are some information about my system:

1
2
3
4
5
6
    Hardware:
      Dragonboard 410c + 
      96Boards MIPI Adapter with Dual OV5645
      (https://www.ebay.com/itm/96Boards-MIPI-Adapter-with-Dual-OV5645/253645902432?hash=item3b0e795260%25253Ag%25253AL38AAOSwCmNZyJq5%252525EF%252525BC%25252589)
    OS      : 
      Linaro Linux 19.01

As I can use GStreamer to control the two OV5645 to feedback captured images, the hardware connections seems to be fine. Below are some information about the I2C master and OV5645 in my system:

    linaro@linaro-developer:~$ sudo i2cdetect -l
    i2c-3   i2c             QUP I2C adapter                         I2C adapter
    i2c-1   i2c             QUP I2C adapter                         I2C adapter
    i2c-4   i2c             Qualcomm Camera Control Interface       I2C adapter
    i2c-0   i2c             QUP I2C adapter                         I2C adapter

    linaro@linaro-developer:~$ dmesg | grep ov5645
    [   11.825197] ov5645 4-003b: OV5645 detected at address 0x3b
    [   12.290626] ov5645 4-003a: OV5645 detected at address 0x3a

And here is my short program: https://gist.github.com/oliverjungen/6f25e9e77167a17d677e7a3c0678c41e

What it does are simply:

1. Open /dev/i2c-4

file = open(filename, O_RDWR);

2. Set I2C slave address 0x3b

errno = ioctl(file, I2C_SLAVE_FORCE, CAM_REAR_I2C_ADDR);

3. Send 16-bit register address 0x300a to this I2C slave

ret = write(file, &reg, 2);

However, when it runs, I always get:

    Write i2c internal address error: Input/output error


This message was printed by perror() in this program’s Line 54, after writing the register address (0x300a, SENSOR CHIP ID HIGH BYTE) to OV5645.

I found that, when this error occurs, the kernel module i2c-qcom-cci reports error messages like:

    linaro@linaro-developer:~$ dmesg | grep cci
    [ 1280.099448] i2c-qcom-cci 1b0c000.cci: Master 0 error 0x08000000
    [ 1280.099502] i2c-qcom-cci 1b0c000.cci: master 0 queue 0 error -5
    [ 1280.104247] i2c-qcom-cci 1b0c000.cci: cci i2c xfer error -5


These I2C slaves (these OV5645) are actually owned by kernel modules. That's the reason why I use I2C_SLAVE_FORCE instead of I2C_SLAVE as the flag when I set the I2C slave address: errno = ioctl(file, I2C_SLAVE_FORCE, CAM_REAR_I2C_ADDR);

I'm wondering whether I can't use ioctl() to control a device owned by kernel modules?
Last edited on
Is this relevant?
https://discuss.96boards.org/t/warning-to-those-expecting-ov5645-camera-on-dragonboard410/888

> As I can use GStreamer to control the two OV5645 to feedback captured images,
> the hardware connections seems to be fine.
If you've got a program which works, then strace is a good way to find out what it's doing.
https://linux.die.net/man/1/strace

Hi salem c,
First thank you for your reply.
Well, the post:
https://discuss.96boards.org/t/warning-to-those-expecting-ov5645-camera-on-dragonboard410/888
is not relevant. Since I can actually got captured images from those OV5645, that author's concern about the voltage level difference between OV5645 and Dragonboard 410c won't result in any problem.

strace looks quite powerful. I got to study how to use it. Hopefully it can enable me to dig out what went wrong.
Thanks again and I wish you a good day!
The root cause of this symptom is:
OV5645’s kernel module will turn OV5645’s power off (or power-saving?) after initializing it. After turning its power on manually, now it’s OK to access OV5645’s registers.

Hi salem c,
Thanks again for your kind help!
Registered users can post here. Sign in or register to post.