How to select OV5693 mode from user space

There are several mode tables in “ov5693_mode_tbls.h”, different mode tables are used in “ov5693_s_stream” depending on “sdata->mode”. How is “sdata->mode” selected from user space, e.g., from a v4l2 program?

Thanks in advance.

Hi yahoo2016
For the v4l2 control program you can trace the v4l2-ctl open source to check the

“–set-fmt-video=width=1920,height=1080”

It appears v4l2-ctl and other v4l2 programs call ioctl function with VIDIOC_S_FMT, but I still could not identify which kernel functions are called to set sdata->mode and other video format related parameters in kernel driver.

We’d like to change video widths/heights/pixel formats of our driver but got error when calling ioctl function with VIDIOC_S_FMT. We could add debug prints if we knew which functions are called.

Hi yahoo2016
VIDIOC_S_FMT is the V4L2 API you may need to reference to V4L2 framework to know the detail calling flow.

I added debug print to ov5693_s_stream function to print out mode, width and height:

static int ov5693_s_stream(struct v4l2_subdev *sd, int enable)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	struct camera_common_data *s_data = to_camera_common_data(client);
	struct ov5693 *priv = (struct ov5693 *)s_data->priv;
	struct v4l2_control control;
	int err;

	dev_info(&client->dev, "%s++\n", __func__);

	if (!enable) {
		ov5693_update_ctrl_range(priv, OV5693_MAX_FRAME_LENGTH);

		return ov5693_write_table(priv,
			mode_table[OV5693_MODE_STOP_STREAM]);
	}

	dev_info(&client->dev, "%s: , write_table mode = %d, %dx%d\n", __func__, s_data->mode, s_data->fmt_width, s_data->fmt_height);
	err = ov5693_write_table(priv, mode_table[s_data->mode]);
	if (err)

But when I used “v4l2-ctl --set-fmt-video=width=xxxx,height=xxxx”, it did not change mode, width or height, see dmesg output:

ubuntu@tegra-ubuntu:~$ sudo v4l2-ctl -d /dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat=RG10 --set-ctrl bypass_mode=0 --stream-mmap --stream-count=1 --stream-to=1920x1080.raw
<
ubuntu@tegra-ubuntu:~$ dmesg | grep ov5693_s_stream
[   46.512776] ov5693 6-0036: ov5693_s_stream++
[   46.512790] ov5693 6-0036: ov5693_s_stream: , write_table mode = 0, 2592x1944
[   46.554177] ov5693 6-0036: ov5693_s_stream--
[   46.788182] ov5693 6-0036: ov5693_s_stream++
[  126.781037] ov5693 6-0036: ov5693_s_stream++
[  126.781048] ov5693 6-0036: ov5693_s_stream: , write_table mode = 0, 2592x1944
[  126.824750] ov5693 6-0036: ov5693_s_stream--
[  127.059384] ov5693 6-0036: ov5693_s_stream++
ubuntu@tegra-ubuntu:~$ sudo v4l2-ctl -d /dev/video0 --set-fmt-video=width=2592,height=1944,pixelformat=RG10 --set-ctrl bypass_mode=0 --stream-mmap --stream-count=1 --stream-to=1920x1080.raw
<
ubuntu@tegra-ubuntu:~$ dmesg | grep ov5693_s_stream
[   46.512776] ov5693 6-0036: ov5693_s_stream++
[   46.512790] ov5693 6-0036: ov5693_s_stream: , write_table mode = 0, 2592x1944
[   46.554177] ov5693 6-0036: ov5693_s_stream--
[   46.788182] ov5693 6-0036: ov5693_s_stream++
[  126.781037] ov5693 6-0036: ov5693_s_stream++
[  126.781048] ov5693 6-0036: ov5693_s_stream: , write_table mode = 0, 2592x1944
[  126.824750] ov5693 6-0036: ov5693_s_stream--
[  127.059384] ov5693 6-0036: ov5693_s_stream++
[  147.391072] ov5693 6-0036: ov5693_s_stream++
[  147.391082] ov5693 6-0036: ov5693_s_stream: , write_table mode = 0, 2592x1944
[  147.437544] ov5693 6-0036: ov5693_s_stream--
[  147.671225] ov5693 6-0036: ov5693_s_stream++
ubuntu@tegra-ubuntu:~$ sudo v4l2-ctl -d /dev/video0 --set-fmt-video=width=1280,height=720,pixelformat=RG10 --set-ctrl bypass_mode=0 --stream-mmap --stream-count=1 --stream-to=1920x1080.raw
<
ubuntu@tegra-ubuntu:~$ dmesg | grep ov5693_s_stream
[   46.512776] ov5693 6-0036: ov5693_s_stream++
[   46.512790] ov5693 6-0036: ov5693_s_stream: , write_table mode = 0, 2592x1944
[   46.554177] ov5693 6-0036: ov5693_s_stream--
[   46.788182] ov5693 6-0036: ov5693_s_stream++
[  126.781037] ov5693 6-0036: ov5693_s_stream++
[  126.781048] ov5693 6-0036: ov5693_s_stream: , write_table mode = 0, 2592x1944
[  126.824750] ov5693 6-0036: ov5693_s_stream--
[  127.059384] ov5693 6-0036: ov5693_s_stream++
[  147.391072] ov5693 6-0036: ov5693_s_stream++
[  147.391082] ov5693 6-0036: ov5693_s_stream: , write_table mode = 0, 2592x1944
[  147.437544] ov5693 6-0036: ov5693_s_stream--
[  147.671225] ov5693 6-0036: ov5693_s_stream++
[  290.729347] ov5693 6-0036: ov5693_s_stream++
[  290.729362] ov5693 6-0036: ov5693_s_stream: , write_table mode = 0, 2592x1944
[  290.771596] ov5693 6-0036: ov5693_s_stream--
[  291.005563] ov5693 6-0036: ov5693_s_stream++
ubuntu@tegra-ubuntu:~$

Is mode selection for ov5693 implemented? I’m using kernel source of L4T 24.2.1.

Thanks

I found there are 2 "ov5693.c"s, The “ov5693.c” in “driver/media/platform/tegra” has “ov5693_ioctl” and “ov5693_set_mode” functions, the “ov5693.c” in “driver/media/i2c” doesn’t.

Is it possible the latest ov5693 driver did not implement “ioctl” and “set_mode” functions?

I think VIDIOC_S_FMT for sensor drivers is implemented by camera_common_s_fmt() in drivers/media/platform/tegra/camera/camera_common.c.

[url]nv-tegra.nvidia Code Review - linux-3.10.git/blob - drivers/media/platform/tegra/camera/camera_common.c

In the sensor driver, you only need to define the list of supported frame formats as done in drivers/media/i2c/ov5693_mode_tbls.h.

[url]nv-tegra.nvidia Code Review - linux-3.10.git/blob - drivers/media/i2c/ov5693_mode_tbls.h

I was testing original L4T 24.2.1 kernel with OV5693 driver, I checked “ov5693_mode_tbls.h” which has 2592x1944, 1920x1080 and 1280x720 tables, but when I used “v4l2-ctl” to set format to 1920x1080 or 1280x720, the debug prints from ov5693_stream did not change mode or resolution, as I posted earlier.

Could it be that camera_common_try_fmt() failed for those formats for some reason? e.g. frame/color format combination not supported by the underlying sensor hardware?

Sorry currently I don’t have a JTX1 board available for experiments, so I can only be guessing here. But anyway this could easily be verified by adding a few debug prints in camera_common_s_fmt() and camera_common_try_fmt().

That’s exactly what I’m doing, I enabled all dev_dbg in camera_common.c and found camera_common_try_fmt failed.

I should be able to find the problems preventing me to change mode.

Thanks