Okay, progress
In the csi2_fops.c code, where we start streaming (csi2_start_streaming) I se the csi_lanes = 1 and this forced the capture to 1 lane.
In other drivers, normally in this streaming code it would make a call to “g_mbus_config” which is not happening here. In the Raspberry Pi version of this code, it is happening there, so I need to figure out how I can make that call to get the same setup happening (or at least, get a call into tc358743_num_csi_lanes_in_use to find out how many lanes. If we do that, I think we can get it dynamically switching.
EDIT
Success!
I am not sure if this code is done in the correct way, but my v4l calls and setting new timings are all working now.
In csi2_fops.c, I added (after TEST):
(beginning of function)
struct v4l2_mbus_config mbus_config = { 0 };
int ret;
(later in function)
csi_port = !chan->pg_mode ? port->csi_port : port->stream_id;
csi_lanes = port->lanes;
// - TEST
ret = v4l2_subdev_call(chan->sensor_sd,video,g_mbus_config,&mbus_config);
csi_lanes = (mbus_config.flags & V4L2_MBUS_CSI2_LANE_MASK) >> __ffs(V4L2_MBUS_CSI2_LANE_MASK);
I also added this define above the function:
#define V4L2_MBUS_CSI2_LANE_MASK (0xf << 10)
Over in tc358743, I added to make look like this:
#define V4L2_MBUS_CSI2_LANE_MASK (0xf << 10)
static int tc358743_g_mbus_config(struct v4l2_subdev *sd,
struct v4l2_mbus_config *cfg)
{
u32 mask = V4L2_MBUS_CSI2_LANE_MASK;
v4l2_info(sd, “Calling %s\n”, FUNCTION);
cfg->type = V4L2_MBUS_CSI2;
cfg->flags = (tc358743_num_csi_lanes_in_use(sd) << __ffs(mask)) & mask;
/* In DT mode, only report the number of active lanes */
if (sd->dev->of_node)
return 0;
Finally, search for the following set (only happens in one place in the driver) and set to 374 to match the reference driver.
state->pdata.fifo_level = 374;
I’ve only tested 640x480 at the moment, but this should work for all single lane variants from what I can tell.
EDIT 2
Upon further inspection, I am getting empty frames in the buffer and sometimes there is tearing in frame 0.
Doing some reading in other threads, this has been seen when the line counts don’t match, between what the device is sending and what is being expected. Although I am not seeing any errors thrown in DMESG. So still digging deeper. Getting closer anyways.
640x480p = Only writes into buffer 0, all other buffers empty
720x480p = Only writes into buffer 0, all other buffers empty
800x600p = Works
1024x768 = Works
EDIT
Okay, found the problem. When the number of lines is 480 and the height is 525, it’s sending 1 less line for some reason. I hacked the code to subtract 1 whole line and it works now for 640x480. Very strange.