Custom MIPI CSI-2 Sensor Integration Issues

I am attempting to integrate a MIPI CSI-2 sensor to be able to ingest the feed into a gstreamer pipeline. The stream has the following properties:

  • Active width = 1280
  • Active height = 1024
  • Line length = 1688
  • Pixel clock = 54MHz
  • Data type = Raw 12 bit Greyscale (Y12)
  • Discontinuous clock = No
  • Number of lanes = 2
  • Frame rate = 30 Hz

The sensor is externally powered and clocked, and continually streams MIPI data into the CSI port via a Seeed A603 carrier board into the Orin Nano 8GB.

My current driver implementation:

/*
 * nv_custom_sensor.c - custom_sensor sensor driver
 *
 */

#include <nvidia/conftest.h>

#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>

#include <media/tegra_v4l2_camera.h>
#include <media/tegracam_core.h>

#include "custom_sensor_mode_tbls.h"

/* custom_sensor sensor register address */
#define CUSTSENS_MODEL_ID_ADDR_MSB		0x7E
#define CUSTSENS_MODEL_ID_ADDR_LSB		0x7F

static const struct of_device_id custom_sensor_of_match[] = {
    { .compatible = "custom,custom_sensor", },
    { },
};
MODULE_DEVICE_TABLE(of, custom_sensor_of_match);

static const u32 ctrl_cid_list[] = {
    TEGRA_CAMERA_CID_SENSOR_MODE_ID,
};

struct custom_sensor {
    struct i2c_client			*i2c_client;
    struct v4l2_subdev			*subdev;
    u16							fine_integ_time;
    u32							frame_length;
    struct camera_common_data	*s_data;
    struct tegracam_device		*tc_dev;
};

static const struct regmap_config sensor_regmap_config = {
    .reg_bits = 8,
    .val_bits = 8,
    .cache_type = REGCACHE_RBTREE,
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)
    .use_single_rw = true,
#else
    .use_single_read = true,
    .use_single_write = true,
#endif
};

static inline int custom_sensor_read_reg(struct camera_common_data *s_data,
    u16 addr, u8 *val)
{
    int err = 0;
    u32 reg_val = 0;

    err = regmap_read(s_data->regmap, addr, &reg_val);
    *val = reg_val & 0xff;

    return err;
}

static inline int custom_sensor_write_reg(struct camera_common_data *s_data,
    u16 addr, u8 val)
{
    int err = 0;

    err = regmap_write(s_data->regmap, addr, val);
    if (err)
        dev_err(s_data->dev, "%s: i2c write failed, 0x%x = %x",
            __func__, addr, val);

    return err;
}

static int custom_sensor_write_table(struct custom_sensor *priv, const custom_sensor_reg table[])
{
    return regmap_util_write_table_8(priv->s_data->regmap, table, NULL, 0,
        CUSTSENS_TABLE_WAIT_MS, CUSTSENS_TABLE_END);
}

static int custom_sensor_set_group_hold(struct tegracam_device *tc_dev, bool val)
{
    // custom_sensor does not support group hold
    return 0;
}

static struct tegracam_ctrl_ops custom_sensor_ctrl_ops = {
    .numctrls = ARRAY_SIZE(ctrl_cid_list),
    .ctrl_cid_list = ctrl_cid_list,
    .set_group_hold = custom_sensor_set_group_hold,
};

static int custom_sensor_power_on(struct camera_common_data *s_data)
{
    return 0;
}

static int custom_sensor_power_off(struct camera_common_data *s_data)
{
    return 0;
}

static int custom_sensor_power_put(struct tegracam_device *tc_dev)
{
    return 0;
}

static int custom_sensor_power_get(struct tegracam_device *tc_dev)
{
    return 0;
}

static struct camera_common_pdata *custom_sensor_parse_dt(
    struct tegracam_device *tc_dev)
{
    struct device *dev = tc_dev->dev;
    struct device_node *np = dev->of_node;
    struct camera_common_pdata *board_priv_pdata;
    const struct of_device_id *match;
    struct camera_common_pdata *ret = NULL;
    int err = 0;
    int gpio;

    if (!np)
        return NULL;

    match = of_match_device(custom_sensor_of_match, dev);
    if (!match) {
        dev_err(dev, "Failed to find matching dt id\n");
        return NULL;
    }

    board_priv_pdata = devm_kzalloc(dev,
        sizeof(*board_priv_pdata), GFP_KERNEL);
    if (!board_priv_pdata)
        return NULL;

    err = of_property_read_string(np, "mclk", &board_priv_pdata->mclk_name);
    if (err)
        dev_dbg(dev,
            "mclk name not present, assume sensor driven externally\n");

    err = of_property_read_string(np, "avdd-reg",
        &board_priv_pdata->regulators.avdd);
    err |= of_property_read_string(np, "iovdd-reg",
        &board_priv_pdata->regulators.iovdd);
    err |= of_property_read_string(np, "dvdd-reg",
        &board_priv_pdata->regulators.dvdd);
    if (err)
        dev_dbg(dev,
        "avdd, iovdd and/or dvdd reglrs. not present, assume sensor powered independently\n");

    board_priv_pdata->has_eeprom =
        of_property_read_bool(np, "has-eeprom");

    return board_priv_pdata;

error:
    devm_kfree(dev, board_priv_pdata);

    return ret;
}

static int custom_sensor_set_mode(struct tegracam_device *tc_dev)
{
    struct custom_sensor *priv = (struct custom_sensor *)tegracam_get_privdata(tc_dev);
    struct camera_common_data *s_data = tc_dev->s_data;

    int err = 0;

    err = custom_sensor_write_table(priv, mode_table[CUSTSENS_MODE_COMMON]);
    if (err)
        return err;

    if (s_data->mode < 0)
        return -EINVAL;
    err = custom_sensor_write_table(priv, mode_table[s_data->mode]);
    if (err)
        return err;

    return 0;
}

static int custom_sensor_start_streaming(struct tegracam_device *tc_dev)
{
    struct custom_sensor *priv = (struct custom_sensor *)tegracam_get_privdata(tc_dev);

    return custom_sensor_write_table(priv, mode_table[CUSTSENS_START_STREAM]);
}

static int custom_sensor_stop_streaming(struct tegracam_device *tc_dev)
{
    struct custom_sensor *priv = (struct custom_sensor *)tegracam_get_privdata(tc_dev);

    return custom_sensor_write_table(priv, mode_table[CUSTSENS_STOP_STREAM]);
}

static struct camera_common_sensor_ops custom_sensor_common_ops = {
    .numfrmfmts = ARRAY_SIZE(custom_sensor_frmfmt),
    .frmfmt_table = custom_sensor_frmfmt,
    .power_on = custom_sensor_power_on,
    .power_off = custom_sensor_power_off,
    .write_reg = custom_sensor_write_reg,
    .read_reg = custom_sensor_read_reg,
    .parse_dt = custom_sensor_parse_dt,
    .power_get = custom_sensor_power_get,
    .power_put = custom_sensor_power_put,
    .set_mode = custom_sensor_set_mode,
    .start_streaming = custom_sensor_start_streaming,
    .stop_streaming = custom_sensor_stop_streaming,
};

static int custom_sensor_board_setup(struct custom_sensor *priv)
{
    struct camera_common_data *s_data = priv->s_data;
    struct camera_common_pdata *pdata = s_data->pdata;
    struct device *dev = s_data->dev;
    u8 reg_val[2];
    int err = 0;

    if (pdata->mclk_name) {
        err = camera_common_mclk_enable(s_data);
        if (err) {
            dev_err(dev, "error turning on mclk (%d)\n", err);
            goto done;
        }
    }

    err = custom_sensor_power_on(s_data);
    if (err) {
        dev_err(dev, "error during power on sensor (%d)\n", err);
        goto err_power_on;
    }

    /* Probe sensor model id registers */
    err = custom_sensor_read_reg(s_data, CUSTSENS_MODEL_ID_ADDR_MSB, &reg_val[0]);
    if (err) {
        dev_err(dev, "%s: error during i2c read probe (%d)\n",
            __func__, err);
        goto err_reg_probe;
    }
    err = custom_sensor_read_reg(s_data, CUSTSENS_MODEL_ID_ADDR_LSB, &reg_val[1]);
    if (err) {
        dev_err(dev, "%s: error during i2c read probe (%d)\n",
            __func__, err);
        goto err_reg_probe;
    }
    if (!((reg_val[0] == 0x53) && reg_val[1] == 0x0E))
        dev_err(dev, "%s: invalid sensor model id: %x%x\n",
            __func__, reg_val[0], reg_val[1]);

err_reg_probe:
    custom_sensor_power_off(s_data);

err_power_on:
    if (pdata->mclk_name)
        camera_common_mclk_disable(s_data);

done:
    return err;
}

static int custom_sensor_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
    struct i2c_client *client = v4l2_get_subdevdata(sd);

    dev_dbg(&client->dev, "%s:\n", __func__);

    return 0;
}

static const struct v4l2_subdev_internal_ops custom_sensor_subdev_internal_ops = {
    .open = custom_sensor_open,
};

#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
static int custom_sensor_probe(struct i2c_client *client)
#else
static int custom_sensor_probe(struct i2c_client *client,
    const struct i2c_device_id *id)
#endif
{
    struct device *dev = &client->dev;
    struct tegracam_device *tc_dev;
    struct custom_sensor *priv;
    int err;

    dev_dbg(dev, "probing v4l2 sensor at addr 0x%0x\n", client->addr);

    if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
        return -EINVAL;

    priv = devm_kzalloc(dev,
            sizeof(struct custom_sensor), GFP_KERNEL);
    if (!priv)
        return -ENOMEM;

    tc_dev = devm_kzalloc(dev,
            sizeof(struct tegracam_device), GFP_KERNEL);
    if (!tc_dev)
        return -ENOMEM;

    priv->i2c_client = tc_dev->client = client;
    tc_dev->dev = dev;
    strncpy(tc_dev->name, "custom_sensor", sizeof(tc_dev->name));
    tc_dev->dev_regmap_config = &sensor_regmap_config;
    tc_dev->sensor_ops = &custom_sensor_common_ops;
    tc_dev->v4l2sd_internal_ops = &custom_sensor_subdev_internal_ops;
    tc_dev->tcctrl_ops = &custom_sensor_ctrl_ops;

    err = tegracam_device_register(tc_dev);
    if (err) {
        dev_err(dev, "tegra camera driver registration failed\n");
        return err;
    }
    priv->tc_dev = tc_dev;
    priv->s_data = tc_dev->s_data;
    priv->subdev = &tc_dev->s_data->subdev;
    tegracam_set_privdata(tc_dev, (void *)priv);

    err = custom_sensor_board_setup(priv);
    if (err) {
        tegracam_device_unregister(tc_dev);
        dev_err(dev, "board setup failed\n");
        return err;
    }

    err = tegracam_v4l2subdev_register(tc_dev, true);
    if (err) {
        tegracam_device_unregister(tc_dev);
        dev_err(dev, "tegra camera subdev registration failed\n");
        return err;
    }

    dev_dbg(dev, "detected custom_sensor sensor\n");

    return 0;
}

#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
static int custom_sensor_remove(struct i2c_client *client)
#else
static void custom_sensor_remove(struct i2c_client *client)
#endif
{
    struct camera_common_data *s_data = to_camera_common_data(&client->dev);
    struct custom_sensor *priv;

    if (!s_data) {
        dev_err(&client->dev, "camera common data is NULL\n");
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
        return -EINVAL;
#else
        return;
#endif
    }
    priv = (struct custom_sensor *)s_data->priv;

    tegracam_v4l2subdev_unregister(priv->tc_dev);
    tegracam_device_unregister(priv->tc_dev);

#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
    return 0;
#endif
}

static const struct i2c_device_id custom_sensor_id[] = {
    { "custom_sensor", 0 },
    { }
};
MODULE_DEVICE_TABLE(i2c, custom_sensor_id);

static struct i2c_driver custom_sensor_i2c_driver = {
    .driver = {
        .name = "custom_sensor",
        .owner = THIS_MODULE,
        .of_match_table = of_match_ptr(custom_sensor_of_match),
    },
    .probe = custom_sensor_probe,
    .remove = custom_sensor_remove,
    .id_table = custom_sensor_id,
};
module_i2c_driver(custom_sensor_i2c_driver);

MODULE_DESCRIPTION("Media Controller driver for CUSTSENS");
MODULE_AUTHOR("Author");
MODULE_LICENSE("GPL v2");

My current device tree overlay:

/dts-v1/;
/plugin/;

#define CAM_I2C_MUX 	TEGRA234_AON_GPIO(CC, 3)

#include <dt-bindings/tegra234-p3767-0000-common.h>

/ {
    overlay-name = "Camera CustomSensor";
    jetson-header-name = "Jetson 24pin CSI Connector";
    compatible = JETSON_COMPATIBLE_P3768;

    /* CustomSensor sensor module on CSI PORT A / cam1 */
    fragment@0 {
        target-path = "/";
        __overlay__ {
            tegra-camera-platform {
                compatible = "nvidia, tegra-camera-platform";
                /**
                * Physical settings to calculate max ISO BW
                *
                * num_csi_lanes = <>;
                * Total number of CSI lanes when all cameras are active
                *
                * max_lane_speed = <>;
                * Max lane speed in Kbit/s
                *
                * min_bits_per_pixel = <>;
                * Min bits per pixel
                *
                * vi_peak_byte_per_pixel = <>;
                * Max byte per pixel for the VI ISO case
                *
                * vi_bw_margin_pct = <>;
                * Vi bandwidth margin in percentage
                *
                * max_pixel_rate = <>;
                * Max pixel rate in Kpixel/s for the ISP ISO case
                *
                * isp_peak_byte_per_pixel = <>;
                * Max byte per pixel for the ISP ISO case
                *
                * isp_bw_margin_pct = <>;
                * Isp bandwidth margin in percentage
                */
                num_csi_lanes = <2>;
                max_lane_speed = <400000>;
                min_bits_per_pixel = <12>;
                vi_peak_byte_per_pixel = <2>;
                vi_bw_margin_pct = <25>;
                max_pixel_rate = <54000>;
                isp_peak_byte_per_pixel = <2>;
                isp_bw_margin_pct = <25>;
                /**
                 * The general guideline for naming badge_info contains 3 parts, and is as follows,
                 * The first part is the camera_board_id for the module; if the module is in a FFD
                 * platform, then use the platform name for this part.
                 * The second part contains the position of the module, ex. "rear" or "front".
                 * The third part contains the last 6 characters of a part number which is found
                 * in the module's specsheet from the vendor.
                 */
                modules {
                    cam_module0: module0 {
                        badge = "custom_front_CS1234";
                        position = "front";
                        orientation = "1";
                        cam_module0_drivernode0: drivernode0 {
                            pcl_id = "v4l2_sensor";
                            sysfs-device-tree = "/sys/firmware/devicetree/base/bus@0/i2c@3180000/custom_sensor@58";
                        };
                    };
                };
            };
            tegra-capture-vi  {
                num-channels = <1>;
                ports {
                    #address-cells = <1>;
                    #size-cells = <0>;
                    vi_port0: port@0 {
                        reg = <0>;
                        custom_sensor_vi_in0: endpoint {
                            port-index = <0>;
                            bus-width = <2>;
                            remote-endpoint = <&custom_sensor_csi_out0>;
                        };
                    };
                };
            };
            bus@0 {
                host1x@13e00000 {
                    nvcsi@15a00000 {
                        num-channels = <1>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        csi_chan0: channel@0 {
                            reg = <0>;
                            ports {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                csi_chan0_port0: port@0 {
                                    reg = <0>;
                                    custom_sensor_csi_in0: endpoint@0 {
                                        port-index = <0>;
                                        bus-width = <2>;
                                        remote-endpoint = <&custom_sensor_out0>;
                                    };
                                };
                                csi_chan0_port1: port@1 {
                                    reg = <1>;
                                    custom_sensor_csi_out0: endpoint@1 {
                                        remote-endpoint = <&custom_sensor_vi_in0>;
                                    };
                                };
                            };
                        };
                    };
                }; 
                i2c@3180000 {
                    status = "okay";
                    custom_sensor@58 {
                        compatible = "custom,custom_sensor";
                        /* I2C device address */
                        reg = <0x58>;
                        /* V4L2 device node location */
                        devnode = "video0";
                        /* Physical dimensions of sensor */
                        physical_w = "15.0";
                        physical_h = "10.0";
                        sensor_model = "custom_sensor";
                        use_sensor_mode_id = "true";
        
                        /**
                        * ==== Modes ====
                        * A modeX node is required to support v4l2 driver
                        * implementation with NVIDIA camera software stack
                        *
                        * == Signal properties ==
                        *
                        * phy_mode = "";
                        * PHY mode used by the MIPI lanes for this device
                        *
                        * tegra_sinterface = "";
                        * CSI Serial interface connected to tegra
                        * Incase of virtual HW devices, use virtual
                        * For SW emulated devices, use host
                        *
                        * pix_clk_hz = "";
                        * Sensor pixel clock used for calculations like exposure and framerate
                        *
                        * readout_orientation = "0";
                        * Based on camera module orientation.
                        * Only change readout_orientation if you specifically
                        * Program a different readout order for this mode
                        *
                        * == Image format Properties ==
                        *
                        * active_w = "";
                        * Pixel active region width
                        *
                        * active_h = "";
                        * Pixel active region height
                        *
                        * pixel_t = "";
                        * The sensor readout pixel pattern
                        *
                        * line_length = "";
                        * Pixel line length (width) for sensor mode.
                        *
                        * == Source Control Settings ==
                        *
                        * Gain factor used to convert fixed point integer to float
                        * Gain range [min_gain/gain_factor, max_gain/gain_factor]
                        * Gain step [step_gain/gain_factor is the smallest step that can be configured]
                        * Default gain [Default gain to be initialized for the control.
                        *     use min_gain_val as default for optimal results]
                        * Framerate factor used to convert fixed point integer to float
                        * Framerate range [min_framerate/framerate_factor, max_framerate/framerate_factor]
                        * Framerate step [step_framerate/framerate_factor is the smallest step that can be configured]
                        * Default Framerate [Default framerate to be initialized for the control.
                        *     use max_framerate to get required performance]
                        * Exposure factor used to convert fixed point integer to float
                        * For convenience use 1 sec = 1000000us as conversion factor
                        * Exposure range [min_exp_time/exposure_factor, max_exp_time/exposure_factor]
                        * Exposure step [step_exp_time/exposure_factor is the smallest step that can be configured]
                        * Default Exposure Time [Default exposure to be initialized for the control.
                        *     Set default exposure based on the default_framerate for optimal exposure settings]
                        *
                        * gain_factor = ""; (integer factor used for floating to fixed point conversion)
                        * min_gain_val = ""; (ceil to integer)
                        * max_gain_val = ""; (ceil to integer)
                        * step_gain_val = ""; (ceil to integer)
                        * default_gain = ""; (ceil to integer)
                        * Gain limits for mode
                        *
                        * exposure_factor = ""; (integer factor used for floating to fixed point conversion)
                        * min_exp_time = ""; (ceil to integer)
                        * max_exp_time = ""; (ceil to integer)
                        * step_exp_time = ""; (ceil to integer)
                        * default_exp_time = ""; (ceil to integer)
                        * Exposure Time limits for mode (sec)
                        *
                        * framerate_factor = ""; (integer factor used for floating to fixed point conversion)
                        * min_framerate = ""; (ceil to integer)
                        * max_framerate = ""; (ceil to integer)
                        * step_framerate = ""; (ceil to integer)
                        * default_framerate = ""; (ceil to integer)
                        * Framerate limits for mode (fps)
                        *
                        * embedded_metadata_height = "";
                        * Sensor embedded metadata height in units of rows.
                        * If sensor does not support embedded metadata value should be 0.
                        */
                        mode0 { /* CustomSensor_MODE_1280x1024_30FPS */
                            mclk_khz = "24000";
                            num_lanes = "2";
                            tegra_sinterface = "serial_a";
                            lane_polarity = "6";
                            phy_mode = "DPHY";
                            discontinuous_clk = "no";
                            dpcm_enable = "false";
                            cil_settletime = "0";
                            active_w = "1280";
                            active_h = "1024";
                            mode_type = "raw";
                            pixel_phase = "y12";
                            csi_pixel_bit_depth = "12";
                            readout_orientation = "0";
                            line_length = "1688";
                            inherent_gain = "1";
                            pix_clk_hz = "54000000";
                            gain_factor = "1";
                            framerate_factor = "1000000";
                            exposure_factor = "1000000";
                            min_gain_val = "1";
                            max_gain_val = "1";
                            step_gain_val = "1";
                            default_gain = "1";
                            min_hdr_ratio = "1";
                            max_hdr_ratio = "1";
                            min_framerate = "30000000"; /* 30.0 fps */
                            max_framerate = "30000000"; /* 30.0 fps */
                            step_framerate = "1";
                            default_framerate = "30000000"; /* 30.0 fps */
                            min_exp_time = "13"; /* us */
                            max_exp_time = "683709"; /* us */
                            step_exp_time = "1";
                            default_exp_time = "2495"; /* us */
                            embedded_metadata_height = "0";
                        };
        
                        ports {
                            #address-cells = <1>;
                            #size-cells = <0>;
                            port@0 {
                                reg = <0>;
                                custom_sensor_out0: endpoint {
                                    status = "okay";
                                    port-index = <0>;
                                    bus-width = <2>;
                                    remote-endpoint = <&custom_sensor_csi_in0>;
                                };
                            };
                        };
                    };
                };
            };
        };
    };
};

I have also updated the kernel drivers for the tegra-camera.ko in order to support the Y12 format:

diff --git a/drivers/media/platform/tegra/camera/camera_common.c b/drivers/media/platform/tegra/camera/camera_common.c
index 010c9965..507346c1 100644
--- a/drivers/media/platform/tegra/camera/camera_common.c
+++ b/drivers/media/platform/tegra/camera/camera_common.c
@@ -129,6 +129,24 @@ static const struct camera_common_colorfmt camera_common_color_fmts[] = {
 		V4L2_COLORSPACE_SRGB,
 		V4L2_PIX_FMT_VYUY,
 	},
+	{
+		MEDIA_BUS_FMT_Y8_1X8,
+		V4L2_COLORSPACE_RAW,
+		V4L2_PIX_FMT_GREY,
+	},
+	{
+		MEDIA_BUS_FMT_Y10_1X10,
+		V4L2_COLORSPACE_RAW,
+		V4L2_PIX_FMT_Y10,
+	},
+	{
+		MEDIA_BUS_FMT_Y12_1X12,
+		V4L2_COLORSPACE_RAW,
+		V4L2_PIX_FMT_Y12,
+	},
 };
 
 struct camera_common_csi_io_pad_ctx {
diff --git a/drivers/media/platform/tegra/camera/sensor_common.c b/drivers/media/platform/tegra/camera/sensor_common.c
index 92cc2fdf..4e4a8ea9 100644
--- a/drivers/media/platform/tegra/camera/sensor_common.c
+++ b/drivers/media/platform/tegra/camera/sensor_common.c
@@ -267,6 +267,12 @@ static int extract_pixel_format(
 		*format = V4L2_PIX_FMT_UYVY;
 	else if (strncmp(pixel_t, "yuv_vyuy16", size) == 0)
 		*format = V4L2_PIX_FMT_VYUY;
+	else if (strncmp(pixel_t, "raw_y88", size) == 0)
+		*format = V4L2_PIX_FMT_GREY;
+	else if (strncmp(pixel_t, "raw_y1010", size) == 0)
+		*format = V4L2_PIX_FMT_Y10;
+	else if (strncmp(pixel_t, "raw_y1212", size) == 0)
+		*format = V4L2_PIX_FMT_Y12;
 	else {
 		pr_err("%s: Need to extend format%s\n", __func__, pixel_t);
 		return -EINVAL;
diff --git a/drivers/media/platform/tegra/camera/vi/vi5_formats.h b/drivers/media/platform/tegra/camera/vi/vi5_formats.h
index 1d0c1133..d1543cb9 100644
--- a/drivers/media/platform/tegra/camera/vi/vi5_formats.h
+++ b/drivers/media/platform/tegra/camera/vi/vi5_formats.h
@@ -90,6 +90,8 @@ static const struct tegra_video_format vi5_video_formats[] = {
 				RAW8, SGBRG8, "GBGB.. RGRG.."),
 	TEGRA_VIDEO_FORMAT(RAW8, 8, SBGGR8_1X8, 1, 1, T_R8,
 				RAW8, SBGGR8, "BGBG.. GRGR.."),
+    TEGRA_VIDEO_FORMAT(RAW8, 8, Y8_1X8, 1, 1, T_R8,
+				RAW8, GREY, "GREY8"),
 
 	/* RAW 10 */
 	TEGRA_VIDEO_FORMAT(RAW10, 10, SRGGB10_1X10, 2, 1, T_R16,
@@ -100,6 +102,8 @@ static const struct tegra_video_format vi5_video_formats[] = {
 				RAW10, SGBRG10, "GBGB.. RGRG.."),
 	TEGRA_VIDEO_FORMAT(RAW10, 10, SBGGR10_1X10, 2, 1, T_R16,
 				RAW10, SBGGR10, "BGBG.. GRGR.."),
+    TEGRA_VIDEO_FORMAT(RAW10, 10, Y10_1X10, 2, 1, T_R16,
+				RAW10, Y10, "GREY10"),
 
 	/* RAW 12 */
 	TEGRA_VIDEO_FORMAT(RAW12, 12, SRGGB12_1X12, 2, 1, T_R16,
@@ -110,6 +114,8 @@ static const struct tegra_video_format vi5_video_formats[] = {
 				RAW12, SGBRG12, "GBGB.. RGRG.."),
 	TEGRA_VIDEO_FORMAT(RAW12, 12, SBGGR12_1X12, 2, 1, T_R16,
 				RAW12, SBGGR12, "BGBG.. GRGR.."),
+	TEGRA_VIDEO_FORMAT(RAW12, 12, Y12_1X12, 2, 1, T_R16,
+				RAW12, Y12, "GREY12"),
 
 	/* RGB888 */
 	TEGRA_VIDEO_FORMAT(RGB888, 24, RGB888_1X24, 4, 1, T_A8R8G8B8,

With the current implementation I am able to insmod the driver successfully, and the device is presented at /dev/video0. When I attempt to run v4l2-ctl --device /dev/video0 --set-fmt-video=width=1280,height=1024,pixelformat="Y12 " --stream-mmap --stream-count=10 --stream-to=frame.raw however I get the following error outputting continually:

tegra-camrtc-capture-vi tegra-capture-vi: corr_err: discarding frame 0, flags: 0, err_data 4194400

Sidenote: For some reason the pixelformat="Y12 " must contain that trailing space. I can’t work out where this is caused but it works as long as the format is provided in quotes with the space…

As I understand it, the error code (0x400060 in hex) indicates a CRC error, and something else, but I can’t work out what the something else is?

The vendor has confirmed to me that the MIPI stream does not currently include the CRC, and so the first error makes sense, and the sensor will be updated to provide the CRC so that should be solved soon.

What are the other errors related to, and where in the kernel source could I look to find where these codes are defined?

For completeness, from the tracelog I see:

# tracer: nop
#
# entries-in-buffer/entries-written: 178/178   #P:6
#
#                                _-------=> irqs-off
#                               / _------=> need-resched
#                              | / _-----=> need-resched-lazy
#                              || / _----=> hardirq/softirq
#                              ||| / _---=> preempt-depth
#                              |||| / _--=> preempt-lazy-depth
#                              ||||| / _-=> migrate-disable
#                              |||||| /     delay
#           TASK-PID     CPU#  |||||||  TIMESTAMP  FUNCTION
#              | |         |   |||||||      |         |
          v4l_id-2066    [003] .......   107.165647: tegra_channel_open: vi-output, custom_sensor 2-0058
          v4l_id-2066    [003] .......   107.165721: tegra_channel_close: vi-output, custom_sensor 2-0058
 pipewire-media--1721    [000] .......   107.177916: tegra_channel_open: vi-output, custom_sensor 2-0058
 pipewire-media--1721    [000] .......   107.177990: tegra_channel_close: vi-output, custom_sensor 2-0058
 pipewire-media--1721    [000] .......   107.178335: tegra_channel_open: vi-output, custom_sensor 2-0058
 pipewire-media--1721    [000] .......   107.178421: tegra_channel_close: vi-output, custom_sensor 2-0058
        pipewire-1719    [003] .......   107.178966: tegra_channel_open: vi-output, custom_sensor 2-0058
        pipewire-1719    [003] .......   107.178988: tegra_channel_close: vi-output, custom_sensor 2-0058
        pipewire-1719    [003] .......   107.179390: tegra_channel_open: vi-output, custom_sensor 2-0058
        pipewire-1719    [003] .......   107.179462: tegra_channel_close: vi-output, custom_sensor 2-0058
        pipewire-1719    [003] .......   107.179476: tegra_channel_open: vi-output, custom_sensor 2-0058
        pipewire-1719    [003] .......   107.179522: tegra_channel_close: vi-output, custom_sensor 2-0058
        v4l2-ctl-2072    [000] .......   127.488583: tegra_channel_open: vi-output, custom_sensor 2-0058
        v4l2-ctl-2072    [000] .......   127.493133: tegra_channel_set_power: custom_sensor 2-0058 : 0x1
        v4l2-ctl-2072    [000] .......   127.493143: camera_common_s_power: status : 0x1
        v4l2-ctl-2072    [000] .......   127.493150: tegra_channel_set_power: 13e00000.host1x:nvcsi@15a00000- : 0x1
        v4l2-ctl-2072    [000] .......   127.493152: csi_s_power: enable : 0x1
        v4l2-ctl-2072    [000] .......   127.493692: tegra_channel_capture_setup: vnc_id 0 W 1280 H 1024 fmt c4
 vi-output, owl1-2073    [001] .......   127.500899: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2073    [001] .......   127.500908: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2073    [001] .......   127.500909: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2073    [001] .......   127.500911: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
        v4l2-ctl-2072    [000] .......   127.500934: tegra_channel_set_stream: enable : 0x1
        v4l2-ctl-2072    [000] .......   127.503454: tegra_channel_set_stream: 13e00000.host1x:nvcsi@15a00000- : 0x1
        v4l2-ctl-2072    [000] .......   127.503456: csi_s_stream: enable : 0x1
        v4l2-ctl-2072    [000] .......   127.503882: tegra_channel_set_stream: custom_sensor 2-0058 : 0x1
 vi-output, owl1-2074    [002] .......   127.547105: tegra_channel_capture_frame: sof:148.559567392
 vi-output, owl1-2074    [002] .......   127.547106: tegra_channel_capture_frame: eof:148.592865440
 vi-output, owl1-2073    [001] .......   127.547126: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [002] .......   127.580475: tegra_channel_capture_frame: sof:148.592889312
 vi-output, owl1-2074    [002] .......   127.580477: tegra_channel_capture_frame: eof:148.626187360
 vi-output, owl1-2073    [001] .......   127.580523: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [002] .......   127.613785: tegra_channel_capture_frame: sof:148.626211200
 vi-output, owl1-2074    [002] .......   127.613786: tegra_channel_capture_frame: eof:148.659509248
 vi-output, owl1-2073    [001] .......   127.613831: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [002] .......   127.647103: tegra_channel_capture_frame: sof:148.659533088
 vi-output, owl1-2074    [002] .......   127.647104: tegra_channel_capture_frame: eof:148.692831136
 vi-output, owl1-2073    [001] .......   127.647136: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [002] .......   127.680398: tegra_channel_capture_frame: sof:148.692854880
 vi-output, owl1-2074    [002] .......   127.680400: tegra_channel_capture_frame: eof:148.726152928
 vi-output, owl1-2073    [001] .......   127.680446: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [002] .......   127.713748: tegra_channel_capture_frame: sof:148.726176768
 vi-output, owl1-2074    [002] .......   127.713750: tegra_channel_capture_frame: eof:148.759474816
 vi-output, owl1-2073    [001] .......   127.713786: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [002] .......   127.747069: tegra_channel_capture_frame: sof:148.759498688
 vi-output, owl1-2074    [002] .......   127.747071: tegra_channel_capture_frame: eof:148.792796736
 vi-output, owl1-2073    [001] .......   127.747111: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   127.780392: tegra_channel_capture_frame: sof:148.792820544
 vi-output, owl1-2074    [004] .......   127.780394: tegra_channel_capture_frame: eof:148.826118624
 vi-output, owl1-2073    [001] .......   127.780432: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   127.813709: tegra_channel_capture_frame: sof:148.826142336
 vi-output, owl1-2074    [004] .......   127.813711: tegra_channel_capture_frame: eof:148.859440416
 vi-output, owl1-2073    [001] .......   127.813756: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   127.847027: tegra_channel_capture_frame: sof:148.859464256
 vi-output, owl1-2074    [004] .......   127.847029: tegra_channel_capture_frame: eof:148.892762336
 vi-output, owl1-2073    [001] .......   127.847068: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   127.880349: tegra_channel_capture_frame: sof:148.892786144
 vi-output, owl1-2074    [004] .......   127.880350: tegra_channel_capture_frame: eof:148.926084192
 vi-output, owl1-2073    [001] .......   127.880393: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   127.913677: tegra_channel_capture_frame: sof:148.926108064
 vi-output, owl1-2074    [004] .......   127.913679: tegra_channel_capture_frame: eof:148.959406112
 vi-output, owl1-2073    [001] .......   127.913721: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   127.946965: tegra_channel_capture_frame: sof:148.959429856
 vi-output, owl1-2074    [004] .......   127.946966: tegra_channel_capture_frame: eof:148.992727904
 vi-output, owl1-2073    [001] .......   127.947009: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [005] .......   127.980324: tegra_channel_capture_frame: sof:148.992751744
 vi-output, owl1-2074    [005] .......   127.980326: tegra_channel_capture_frame: eof:149.26049792
 vi-output, owl1-2073    [001] .......   127.980372: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   128.013637: tegra_channel_capture_frame: sof:149.26073632
 vi-output, owl1-2074    [004] .......   128.013639: tegra_channel_capture_frame: eof:149.59371680
 vi-output, owl1-2073    [001] .......   128.013680: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   128.046953: tegra_channel_capture_frame: sof:149.59395424
 vi-output, owl1-2074    [004] .......   128.046955: tegra_channel_capture_frame: eof:149.92693568
 vi-output, owl1-2073    [001] .......   128.046996: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   128.080245: tegra_channel_capture_frame: sof:149.92717312
 vi-output, owl1-2074    [004] .......   128.080247: tegra_channel_capture_frame: eof:149.126015360
 vi-output, owl1-2073    [001] .......   128.080291: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   128.113600: tegra_channel_capture_frame: sof:149.126039232
 vi-output, owl1-2074    [004] .......   128.113601: tegra_channel_capture_frame: eof:149.159337280
 vi-output, owl1-2073    [001] .......   128.113648: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   128.146918: tegra_channel_capture_frame: sof:149.159361120
 vi-output, owl1-2074    [004] .......   128.146919: tegra_channel_capture_frame: eof:149.192659168
 vi-output, owl1-2073    [001] .......   128.146961: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   128.180252: tegra_channel_capture_frame: sof:149.192682912
 vi-output, owl1-2074    [004] .......   128.180253: tegra_channel_capture_frame: eof:149.225981056
 vi-output, owl1-2073    [001] .......   128.180294: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   128.213571: tegra_channel_capture_frame: sof:149.226004800
 vi-output, owl1-2074    [004] .......   128.213572: tegra_channel_capture_frame: eof:149.259302848
 vi-output, owl1-2073    [001] .......   128.213611: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   128.246886: tegra_channel_capture_frame: sof:149.259326688
 vi-output, owl1-2074    [004] .......   128.246887: tegra_channel_capture_frame: eof:149.292624736
 vi-output, owl1-2073    [001] .......   128.246929: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [005] .......   128.280210: tegra_channel_capture_frame: sof:149.292648608
 vi-output, owl1-2074    [005] .......   128.280212: tegra_channel_capture_frame: eof:149.325946656
 vi-output, owl1-2073    [001] .......   128.280253: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [005] .......   128.313508: tegra_channel_capture_frame: sof:149.325970400
 vi-output, owl1-2074    [005] .......   128.313509: tegra_channel_capture_frame: eof:149.359268448
 vi-output, owl1-2073    [001] .......   128.313550: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [005] .......   128.346825: tegra_channel_capture_frame: sof:149.359292256
 vi-output, owl1-2074    [005] .......   128.346826: tegra_channel_capture_frame: eof:149.392590304
 vi-output, owl1-2073    [001] .......   128.346869: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [005] .......   128.380180: tegra_channel_capture_frame: sof:149.392614176
 vi-output, owl1-2074    [005] .......   128.380181: tegra_channel_capture_frame: eof:149.425912224
 vi-output, owl1-2073    [001] .......   128.380214: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [005] .......   128.413465: tegra_channel_capture_frame: sof:149.425936064
 vi-output, owl1-2074    [005] .......   128.413466: tegra_channel_capture_frame: eof:149.459234112
 vi-output, owl1-2073    [001] .......   128.413508: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [005] .......   128.446817: tegra_channel_capture_frame: sof:149.459257856
 vi-output, owl1-2074    [005] .......   128.446818: tegra_channel_capture_frame: eof:149.492555904
 vi-output, owl1-2073    [001] .......   128.446859: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [005] .......   128.480139: tegra_channel_capture_frame: sof:149.492579744
 vi-output, owl1-2074    [005] .......   128.480140: tegra_channel_capture_frame: eof:149.525877824
 vi-output, owl1-2073    [001] .......   128.480182: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [005] .......   128.513430: tegra_channel_capture_frame: sof:149.525901632
 vi-output, owl1-2074    [005] .......   128.513431: tegra_channel_capture_frame: eof:149.559199712
 vi-output, owl1-2073    [001] .......   128.513469: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [005] .......   128.546781: tegra_channel_capture_frame: sof:149.559223552
 vi-output, owl1-2074    [005] .......   128.546782: tegra_channel_capture_frame: eof:149.592521632
 vi-output, owl1-2073    [001] .......   128.546818: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [005] .......   128.580101: tegra_channel_capture_frame: sof:149.592545344
 vi-output, owl1-2074    [005] .......   128.580101: tegra_channel_capture_frame: eof:149.625843392
 vi-output, owl1-2073    [001] .......   128.580139: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [005] .......   128.613437: tegra_channel_capture_frame: sof:149.625867232
 vi-output, owl1-2074    [005] .......   128.613438: tegra_channel_capture_frame: eof:149.659165280
 vi-output, owl1-2073    [001] .......   128.613479: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [005] .......   128.646751: tegra_channel_capture_frame: sof:149.659189120
 vi-output, owl1-2074    [005] .......   128.646752: tegra_channel_capture_frame: eof:149.692487200
 vi-output, owl1-2073    [001] .......   128.646790: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [005] .......   128.680075: tegra_channel_capture_frame: sof:149.692511008
 vi-output, owl1-2074    [005] .......   128.680076: tegra_channel_capture_frame: eof:149.725809088
 vi-output, owl1-2073    [001] .......   128.680116: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [005] .......   128.713363: tegra_channel_capture_frame: sof:149.725832832
 vi-output, owl1-2074    [005] .......   128.713364: tegra_channel_capture_frame: eof:149.759130880
 vi-output, owl1-2073    [001] .......   128.713403: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [005] .......   128.746715: tegra_channel_capture_frame: sof:149.759154720
 vi-output, owl1-2074    [005] .......   128.746716: tegra_channel_capture_frame: eof:149.792452800
 vi-output, owl1-2073    [001] .......   128.746759: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [005] .......   128.780035: tegra_channel_capture_frame: sof:149.792476608
 vi-output, owl1-2074    [005] .......   128.780036: tegra_channel_capture_frame: eof:149.825774656
 vi-output, owl1-2073    [001] .......   128.780073: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   128.813331: tegra_channel_capture_frame: sof:149.825798432
 vi-output, owl1-2074    [004] .......   128.813332: tegra_channel_capture_frame: eof:149.859096576
 vi-output, owl1-2073    [001] .......   128.813373: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   128.846678: tegra_channel_capture_frame: sof:149.859120288
 vi-output, owl1-2074    [004] .......   128.846679: tegra_channel_capture_frame: eof:149.892418368
 vi-output, owl1-2073    [001] .......   128.846717: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   128.879975: tegra_channel_capture_frame: sof:149.892442208
 vi-output, owl1-2074    [004] .......   128.879976: tegra_channel_capture_frame: eof:149.925740224
 vi-output, owl1-2073    [001] .......   128.880012: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   128.913327: tegra_channel_capture_frame: sof:149.925764096
 vi-output, owl1-2074    [004] .......   128.913328: tegra_channel_capture_frame: eof:149.959062144
 vi-output, owl1-2073    [001] .......   128.913364: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   128.946647: tegra_channel_capture_frame: sof:149.959085888
 vi-output, owl1-2074    [004] .......   128.946648: tegra_channel_capture_frame: eof:149.992384032
 vi-output, owl1-2073    [001] .......   128.946682: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   128.979968: tegra_channel_capture_frame: sof:149.992407776
 vi-output, owl1-2074    [004] .......   128.979969: tegra_channel_capture_frame: eof:150.25705824
 vi-output, owl1-2073    [001] .......   128.980008: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   129.013291: tegra_channel_capture_frame: sof:150.25729696
 vi-output, owl1-2074    [004] .......   129.013291: tegra_channel_capture_frame: eof:150.59027744
 vi-output, owl1-2073    [001] .......   129.013324: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   129.046613: tegra_channel_capture_frame: sof:150.59051584
 vi-output, owl1-2074    [004] .......   129.046614: tegra_channel_capture_frame: eof:150.92349632
 vi-output, owl1-2073    [001] .......   129.046648: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
 vi-output, owl1-2074    [004] .......   129.079898: tegra_channel_capture_frame: sof:150.92373376
 vi-output, owl1-2074    [004] .......   129.079898: tegra_channel_capture_frame: eof:150.125671424
 vi-output, owl1-2073    [001] .......   129.079934: vi_task_submit: class_id:48 ch:0 syncpt_id:22 syncpt_thresh:0 pid:2073 tid:2073
        v4l2-ctl-2072    [000] .......   129.102037: tegra_channel_close: vi-output, custom_sensor 2-0058
 vi-output, owl1-2074    [004] .......   129.113219: tegra_channel_capture_frame: sof:150.125695264
 vi-output, owl1-2074    [004] .......   129.113220: tegra_channel_capture_frame: eof:150.158993312
        v4l2-ctl-2072    [000] .......   129.113237: tegra_channel_set_stream: enable : 0x0
        v4l2-ctl-2072    [000] .......   129.113238: tegra_channel_set_stream: custom_sensor 2-0058 : 0x0
        v4l2-ctl-2072    [000] .......   129.113251: tegra_channel_set_stream: 13e00000.host1x:nvcsi@15a00000- : 0x0
        v4l2-ctl-2072    [000] .......   129.113254: csi_s_stream: enable : 0x0
        v4l2-ctl-2072    [000] .......   129.115452: tegra_channel_set_power: custom_sensor 2-0058 : 0x0
        v4l2-ctl-2072    [000] .......   129.115456: camera_common_s_power: status : 0x0
        v4l2-ctl-2072    [000] .......   129.115462: tegra_channel_set_power: 13e00000.host1x:nvcsi@15a00000- : 0x0
        v4l2-ctl-2072    [000] .......   129.115464: csi_s_power: enable : 0x0

Thanks in advance!

hello bt.rmrl,

please refer to Topic 318537 to debug discarding frame corr_err messages.
could you please also check $ v4l2-ctl -d /dev/video0 --list-formats-ext for sensor formats.

The output of v4l2-ctl -d /dev/video0 --list-formats-ext gives:

ioctl: VIDIOC_ENUM_FMT
	Type: Video Capture

	[0]: 'Y12 ' (12-bit Greyscale)
		Size: Discrete 1280x1024
			Interval: Discrete 0.033s (30.000 fps)

And when I run v4l2-ctl --device /dev/video0 --set-fmt-video=width=1280,height=1024,pixelformat="Y12 " --stream-mmap --stream-count=1 --verbose I see:

VIDIOC_QUERYCAP: ok
VIDIOC_G_FMT: ok
VIDIOC_S_FMT: ok
Format Video Capture:
	Width/Height      : 1280/1024
	Pixel Format      : 'Y12 ' (12-bit Greyscale)
	Field             : None
	Bytes per Line    : 2560
	Size Image        : 2621440
	Colorspace        : sRGB
	Transfer Function : Default (maps to sRGB)
	YCbCr/HSV Encoding: Default (maps to ITU-R 601)
	Quantization      : Default (maps to Full Range)
	Flags             : 
		VIDIOC_REQBUFS returned 0 (Success)
		VIDIOC_QUERYBUF returned 0 (Success)
		VIDIOC_QUERYBUF returned 0 (Success)
		VIDIOC_QUERYBUF returned 0 (Success)
		VIDIOC_QUERYBUF returned 0 (Success)
		VIDIOC_QBUF returned 0 (Success)
		VIDIOC_QBUF returned 0 (Success)
		VIDIOC_QBUF returned 0 (Success)
		VIDIOC_QBUF returned 0 (Success)
		VIDIOC_STREAMON returned 0 (Success)
cap dqbuf: 0 seq:      0 bytesused: 2621440 ts: 1938.339048 (error, ts-monotonic, ts-src-eof)
cap dqbuf: 1 seq:      1 bytesused: 2621440 ts: 1938.372370 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 2 seq:      2 bytesused: 2621440 ts: 1938.405692 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 3 seq:      3 bytesused: 2621440 ts: 1938.439013 delta: 33.321 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 0 seq:      4 bytesused: 2621440 ts: 1938.472335 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 1 seq:      5 bytesused: 2621440 ts: 1938.505657 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 2 seq:      6 bytesused: 2621440 ts: 1938.538979 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 3 seq:      7 bytesused: 2621440 ts: 1938.572301 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 0 seq:      8 bytesused: 2621440 ts: 1938.605623 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 1 seq:      9 bytesused: 2621440 ts: 1938.638944 delta: 33.321 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 2 seq:     10 bytesused: 2621440 ts: 1938.672266 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 3 seq:     11 bytesused: 2621440 ts: 1938.705588 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 0 seq:     12 bytesused: 2621440 ts: 1938.738910 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 1 seq:     13 bytesused: 2621440 ts: 1938.772232 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 2 seq:     14 bytesused: 2621440 ts: 1938.805553 delta: 33.321 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 3 seq:     15 bytesused: 2621440 ts: 1938.838875 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 0 seq:     16 bytesused: 2621440 ts: 1938.872197 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 1 seq:     17 bytesused: 2621440 ts: 1938.905519 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 2 seq:     18 bytesused: 2621440 ts: 1938.938841 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 3 seq:     19 bytesused: 2621440 ts: 1938.972163 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 0 seq:     20 bytesused: 2621440 ts: 1939.005484 delta: 33.321 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 1 seq:     21 bytesused: 2621440 ts: 1939.038806 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 2 seq:     22 bytesused: 2621440 ts: 1939.072128 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 3 seq:     23 bytesused: 2621440 ts: 1939.105450 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 0 seq:     24 bytesused: 2621440 ts: 1939.138772 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 1 seq:     25 bytesused: 2621440 ts: 1939.172094 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 2 seq:     26 bytesused: 2621440 ts: 1939.205415 delta: 33.321 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 3 seq:     27 bytesused: 2621440 ts: 1939.238737 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 0 seq:     28 bytesused: 2621440 ts: 1939.272059 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 1 seq:     29 bytesused: 2621440 ts: 1939.305381 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 2 seq:     30 bytesused: 2621440 ts: 1939.338703 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 3 seq:     31 bytesused: 2621440 ts: 1939.372025 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 0 seq:     32 bytesused: 2621440 ts: 1939.405346 delta: 33.321 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 1 seq:     33 bytesused: 2621440 ts: 1939.438668 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 2 seq:     34 bytesused: 2621440 ts: 1939.471990 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 3 seq:     35 bytesused: 2621440 ts: 1939.505312 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 0 seq:     36 bytesused: 2621440 ts: 1939.538634 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 1 seq:     37 bytesused: 2621440 ts: 1939.571955 delta: 33.321 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 2 seq:     38 bytesused: 2621440 ts: 1939.605277 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)
cap dqbuf: 3 seq:     39 bytesused: 2621440 ts: 1939.638599 delta: 33.322 ms (error, ts-monotonic, ts-src-eof)

I am unlcear whether the Bytes per Line and Size Image values make sense as they don’t seem to match with what I have configures in my device tree (1280 x 1024 x 12bit / 8 = 1966080 bytes).

For the error code I see of 4194400, this suggests that the following errors are occurring:

CAPTURE_STATUS_NOTIFY_BIT_CSIMUX_FRAME_PXL_ENABLE_FAULT ( 1 << 5)
CAPTURE_STATUS_NOTIFY_BIT_CSIMUX_STREAM_FIFO_OVERFLOW (1 << 22)

But also (1 << 6) is set? There doesn’t seem to be an error code for this listed?

Are these errors more likely to be caused by a configuration error, or a stream error, or both? What is the best way to determine the cause of these issues?

It turned out to be the CRC missing from the MIPI CSI-2 stream. One the FPGA firmware was updated to include the CRC correctly, the errors stopped and the stream was captured successfully.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.