diff --git a/drivers/video/gc2145.c b/drivers/video/gc2145.c index 3d7a7bda219b..ef369dec7b87 100644 --- a/drivers/video/gc2145.c +++ b/drivers/video/gc2145.c @@ -12,7 +12,7 @@ #include #include #include - +#include #include #include "video_ctrls.h" @@ -42,6 +42,54 @@ LOG_MODULE_REGISTER(video_gc2145, CONFIG_VIDEO_LOG_LEVEL); #define GC2145_REG_SUBSAMPLE_MODE 0x9A #define GC2145_SUBSAMPLE_MODE_SMOOTH 0x0E +/* MIPI-CSI registers - on page 3 */ +#define GC2145_REG_DPHY_MODE1 0x01 +#define GC2145_DPHY_MODE1_CLK_EN BIT(0) +#define GC2145_DPHY_MODE1_LANE0_EN BIT(1) +#define GC2145_DPHY_MODE1_LANE1_EN BIT(2) +#define GC2145_DPHY_MODE1_CLK_LANE_P2S_SEL BIT(7) + +#define GC2145_REG_DPHY_MODE2 0x02 +#define GC2145_DPHY_MODE2_CLK_DIFF(a) ((a) & 0x07) +#define GC2145_DPHY_MODE2_LANE0_DIFF(a) (((a) & 0x07) << 4) + +#define GC2145_REG_DPHY_MODE3 0x03 +#define GC2145_DPHY_MODE3_LANE1_DIFF(a) ((a) & 0x07) +#define GC2145_DPHY_MODE3_CLK_DELAY BIT(4) +#define GC2145_DPHY_MODE3_LANE0_DELAY BIT(5) +#define GC2145_DPHY_MODE3_LANE1_DELAY BIT(6) + +#define GC2145_REG_FIFO_FULL_LVL_LOW 0x04 +#define GC2145_REG_FIFO_FULL_LVL_HIGH 0x05 +#define GC2145_REG_FIFO_MODE 0x06 +#define GC2145_FIFO_MODE_READ_GATE BIT(3) +#define GC2145_FIFO_MODE_MIPI_CLK_MODULE BIT(7) + +#define GC2145_REG_BUF_CSI2_MODE 0x10 +#define GC2145_CSI2_MODE_DOUBLE BIT(0) +#define GC2145_CSI2_MODE_RAW8 BIT(2) +#define GC2145_CSI2_MODE_MIPI_EN BIT(4) +#define GC2145_CSI2_MODE_EN BIT(7) + +#define GC2145_REG_MIPI_DT 0x11 +#define GC2145_REG_LWC_LOW 0x12 +#define GC2145_REG_LWC_HIGH 0x13 +#define GC2145_REG_DPHY_MODE 0x15 +#define GC2145_DPHY_MODE_TRIGGER_PROG BIT(4) + +#define GC2145_REG_FIFO_GATE_MODE 0x17 +#define GC2145_REG_T_LPX 0x21 +#define GC2145_REG_T_CLK_HS_PREPARE 0x22 +#define GC2145_REG_T_CLK_ZERO 0x23 +#define GC2145_REG_T_CLK_PRE 0x24 +#define GC2145_REG_T_CLK_POST 0x25 +#define GC2145_REG_T_CLK_TRAIL 0x26 +#define GC2145_REG_T_HS_EXIT 0x27 +#define GC2145_REG_T_WAKEUP 0x28 +#define GC2145_REG_T_HS_PREPARE 0x29 +#define GC2145_REG_T_HS_ZERO 0x2a +#define GC2145_REG_T_HS_TRAIL 0x2b + #define UXGA_HSIZE 1600 #define UXGA_VSIZE 1200 @@ -659,8 +707,6 @@ static const struct gc2145_reg default_regs[] = { {0xfe, 0x00}, /* Output Control */ - {0xfe, 0x00}, - {0xf2, 0x0f}, {0xfe, 0x02}, {0x40, 0xbf}, {0x46, 0xcf}, @@ -683,6 +729,32 @@ static const struct gc2145_reg default_regs[] = { {0x00, 0x00}, }; +static const struct gc2145_reg default_mipi_csi_regs[] = { + /* Switch to page 3 */ + {0xfe, 0x03}, + {GC2145_REG_DPHY_MODE1, GC2145_DPHY_MODE1_CLK_EN | + GC2145_DPHY_MODE1_LANE0_EN | GC2145_DPHY_MODE1_LANE1_EN | + GC2145_DPHY_MODE1_CLK_LANE_P2S_SEL}, + {GC2145_REG_DPHY_MODE2, GC2145_DPHY_MODE2_CLK_DIFF(2) | + GC2145_DPHY_MODE2_LANE0_DIFF(2)}, + {GC2145_REG_DPHY_MODE3, GC2145_DPHY_MODE3_LANE1_DIFF(0) | + GC2145_DPHY_MODE3_CLK_DELAY}, + {GC2145_REG_FIFO_MODE, GC2145_FIFO_MODE_READ_GATE | + GC2145_FIFO_MODE_MIPI_CLK_MODULE}, + {GC2145_REG_DPHY_MODE, GC2145_DPHY_MODE_TRIGGER_PROG}, + + /* Clock & Data lanes timing */ + {GC2145_REG_T_LPX, 0x10}, + {GC2145_REG_T_CLK_HS_PREPARE, 0x04}, + {GC2145_REG_T_CLK_ZERO, 0x10}, + {GC2145_REG_T_CLK_PRE, 0x10}, + {GC2145_REG_T_CLK_POST, 0x10}, + {GC2145_REG_T_CLK_TRAIL, 0x05}, + {GC2145_REG_T_HS_PREPARE, 0x03}, + {GC2145_REG_T_HS_ZERO, 0x0a}, + {GC2145_REG_T_HS_TRAIL, 0x06}, +}; + struct gc2145_config { struct i2c_dt_spec i2c; #if DT_INST_NODE_HAS_PROP(0, pwdn_gpios) @@ -691,11 +763,13 @@ struct gc2145_config { #if DT_INST_NODE_HAS_PROP(0, reset_gpios) struct gpio_dt_spec reset_gpio; #endif + int bus_type; }; struct gc2145_ctrls { struct video_ctrl hflip; struct video_ctrl vflip; + struct video_ctrl linkfreq; }; struct gc2145_data { @@ -1040,9 +1114,89 @@ static uint8_t gc2145_check_connection(const struct device *dev) return 0; } +#define GC2145_640_480_LINK_FREQ 120000000 +#define GC2145_640_480_LINK_FREQ_ID 0 +#define GC2145_1600_1200_LINK_FREQ 240000000 +#define GC2145_1600_1200_LINK_FREQ_ID 1 +const int64_t gc2145_link_frequency[] = { + GC2145_640_480_LINK_FREQ, GC2145_1600_1200_LINK_FREQ, +}; +static int gc2145_config_csi(const struct device *dev, uint32_t pixelformat, + uint32_t width, uint32_t height) +{ + const struct gc2145_config *cfg = dev->config; + struct gc2145_data *drv_data = dev->data; + struct gc2145_ctrls *ctrls = &drv_data->ctrls; + uint16_t fifo_full_level = width == 1600 ? 0x0001 : 0x0190; + uint16_t lwc = width * video_bits_per_pixel(pixelformat) / BITS_PER_BYTE; + uint8_t csi_dt; + int ret; + + switch (pixelformat) { + case VIDEO_PIX_FMT_RGB565: + csi_dt = VIDEO_MIPI_CSI2_DT_RGB565; + break; + case VIDEO_PIX_FMT_YUYV: + csi_dt = VIDEO_MIPI_CSI2_DT_YUV422_8; + break; + default: + LOG_ERR("Unsupported pixelformat for CSI"); + return -EINVAL; + } + + /* Only VGA & UXGA work (currently) in CSI */ + if (width == RESOLUTION_VGA_W && height == RESOLUTION_VGA_H) { + ctrls->linkfreq.val = GC2145_640_480_LINK_FREQ_ID; + } else if (width == RESOLUTION_UXGA_W && height == RESOLUTION_UXGA_H) { + ctrls->linkfreq.val = GC2145_1600_1200_LINK_FREQ_ID; + } else { + LOG_ERR("Unsupported resolution 320x240 for CSI"); + return -EINVAL; + } + + /* Apply fixed settings for MIPI-CSI. After that active page is 3 */ + ret = gc2145_write_all(dev, default_mipi_csi_regs, ARRAY_SIZE(default_mipi_csi_regs)); + if (ret < 0) { + return ret; + } + + ret = gc2145_write_reg(&cfg->i2c, GC2145_REG_LWC_LOW, lwc & 0xff); + if (ret < 0) { + return ret; + } + + ret = gc2145_write_reg(&cfg->i2c, GC2145_REG_LWC_HIGH, lwc >> 8); + if (ret < 0) { + return ret; + } + + ret = gc2145_write_reg(&cfg->i2c, GC2145_REG_FIFO_FULL_LVL_LOW, fifo_full_level & 0xff); + if (ret < 0) { + return ret; + } + + ret = gc2145_write_reg(&cfg->i2c, GC2145_REG_FIFO_FULL_LVL_HIGH, fifo_full_level >> 8); + if (ret < 0) { + return ret; + } + + ret = gc2145_write_reg(&cfg->i2c, GC2145_REG_FIFO_GATE_MODE, 0xf0); + if (ret < 0) { + return ret; + } + + ret = gc2145_write_reg(&cfg->i2c, GC2145_REG_MIPI_DT, csi_dt); + if (ret < 0) { + return ret; + } + + return gc2145_write_reg(&cfg->i2c, 0xfe, 0x0); +} + static int gc2145_set_fmt(const struct device *dev, struct video_format *fmt) { struct gc2145_data *drv_data = dev->data; + const struct gc2145_config *cfg = dev->config; size_t res = ARRAY_SIZE(fmts); int ret; @@ -1064,8 +1218,6 @@ static int gc2145_set_fmt(const struct device *dev, struct video_format *fmt) return -ENOTSUP; } - drv_data->fmt = *fmt; - /* Set output format */ ret = gc2145_set_output_format(dev, fmt->pixelformat); if (ret < 0) { @@ -1081,6 +1233,16 @@ static int gc2145_set_fmt(const struct device *dev, struct video_format *fmt) return ret; } + if (cfg->bus_type == VIDEO_BUS_TYPE_CSI2_DPHY) { + ret = gc2145_config_csi(dev, fmt->pixelformat, fmt->width, fmt->height); + if (ret < 0) { + LOG_ERR("Failed to configure MIPI-CSI"); + return ret; + } + } + + drv_data->fmt = *fmt; + return 0; } @@ -1093,7 +1255,7 @@ static int gc2145_get_fmt(const struct device *dev, struct video_format *fmt) return 0; } -static int gc2145_set_stream(const struct device *dev, bool enable, enum video_buf_type type) +static int gc2145_set_stream_dvp(const struct device *dev, bool enable) { const struct gc2145_config *cfg = dev->config; @@ -1101,6 +1263,36 @@ static int gc2145_set_stream(const struct device *dev, bool enable, enum video_b : gc2145_write_reg(&cfg->i2c, 0xf2, 0x00); } +static int gc2145_set_stream_csi(const struct device *dev, bool enable) +{ + const struct gc2145_config *cfg = dev->config; + int ret; + + ret = gc2145_write_reg(&cfg->i2c, 0xfe, 0x03); + if (ret < 0) { + return ret; + } + + ret = gc2145_write_reg(&cfg->i2c, GC2145_REG_BUF_CSI2_MODE, + enable ? GC2145_CSI2_MODE_RAW8 | GC2145_CSI2_MODE_DOUBLE | + GC2145_CSI2_MODE_EN | GC2145_CSI2_MODE_MIPI_EN + : 0); + if (ret < 0) { + return ret; + } + + return gc2145_write_reg(&cfg->i2c, 0xfe, 0x0); +} + +static int gc2145_set_stream(const struct device *dev, bool enable, enum video_buf_type type) +{ + const struct gc2145_config *cfg = dev->config; + + return cfg->bus_type == VIDEO_BUS_TYPE_PARALLEL ? + gc2145_set_stream_dvp(dev, enable) : + gc2145_set_stream_csi(dev, enable); +} + static int gc2145_get_caps(const struct device *dev, struct video_caps *caps) { caps->format_caps = fmts; @@ -1141,8 +1333,22 @@ static int gc2145_init_controls(const struct device *dev) return ret; } - return video_init_ctrl(&ctrls->vflip, dev, VIDEO_CID_VFLIP, - (struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 0}); + ret = video_init_ctrl(&ctrls->vflip, dev, VIDEO_CID_VFLIP, + (struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 0}); + if (ret < 0) { + return ret; + } + + ret = video_init_int_menu_ctrl(&ctrls->linkfreq, dev, VIDEO_CID_LINK_FREQ, + GC2145_640_480_LINK_FREQ_ID, gc2145_link_frequency, + ARRAY_SIZE(gc2145_link_frequency)); + if (ret < 0) { + return ret; + } + + ctrls->linkfreq.flags |= VIDEO_CTRL_FLAG_READ_ONLY; + + return 0; } static int gc2145_init(const struct device *dev) @@ -1179,10 +1385,10 @@ static int gc2145_init(const struct device *dev) gc2145_soft_reset(dev); gc2145_write_all(dev, default_regs, ARRAY_SIZE(default_regs)); - /* set default/init format QVGA RGB565 */ + /* set default/init format VGA RGB565 */ fmt.pixelformat = VIDEO_PIX_FMT_RGB565; - fmt.width = RESOLUTION_QVGA_W; - fmt.height = RESOLUTION_QVGA_H; + fmt.width = RESOLUTION_VGA_W; + fmt.height = RESOLUTION_VGA_H; ret = gc2145_set_fmt(dev, &fmt); if (ret) { @@ -1203,6 +1409,8 @@ static const struct gc2145_config gc2145_cfg_0 = { #if DT_INST_NODE_HAS_PROP(0, reset_gpios) .reset_gpio = GPIO_DT_SPEC_INST_GET(0, reset_gpios), #endif + .bus_type = DT_PROP_OR(DT_INST_ENDPOINT_BY_ID(0, 0, 0), bus_type, + VIDEO_BUS_TYPE_PARALLEL), }; static struct gc2145_data gc2145_data_0; diff --git a/drivers/video/video_common.c b/drivers/video/video_common.c index 9c92ed09b028..95b3ad6b0384 100644 --- a/drivers/video/video_common.c +++ b/drivers/video/video_common.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -365,3 +366,42 @@ int video_write_cci_multiregs16(const struct i2c_dt_spec *i2c, const struct vide return 0; } + +int64_t video_get_csi_link_freq(const struct device *dev, uint8_t bpp, uint8_t lane_nb) +{ + struct video_control ctrl = { + .id = VIDEO_CID_LINK_FREQ, + }; + struct video_ctrl_query ctrl_query = { + .id = VIDEO_CID_LINK_FREQ, + }; + int ret; + + /* Try to get the LINK_FREQ value from the source device */ + ret = video_get_ctrl(dev, &ctrl); + if (ret < 0) { + goto fallback; + } + + ret = video_query_ctrl(dev, &ctrl_query); + if (ret < 0) { + return ret; + } + + if (!IN_RANGE(ctrl.val, ctrl_query.range.min, ctrl_query.range.max)) { + return -ERANGE; + } + + return (int64_t)ctrl_query.int_menu[ctrl.val]; + +fallback: + /* If VIDEO_CID_LINK_FREQ is not available, approximate from VIDEO_CID_PIXEL_RATE */ + ctrl.id = VIDEO_CID_PIXEL_RATE; + ret = video_get_ctrl(dev, &ctrl); + if (ret < 0) { + return ret; + } + + /* CSI D-PHY is using a DDR data bus so bitrate is twice the frequency */ + return ctrl.val64 * bpp / (2 * lane_nb); +} diff --git a/drivers/video/video_ctrls.c b/drivers/video/video_ctrls.c index dcab6582eef7..c213dcbb4790 100644 --- a/drivers/video/video_ctrls.c +++ b/drivers/video/video_ctrls.c @@ -70,6 +70,7 @@ static inline int check_range(enum video_ctrl_type type, struct video_ctrl_range } return 0; case VIDEO_CTRL_TYPE_MENU: + case VIDEO_CTRL_TYPE_INTEGER_MENU: if (!IN_RANGE(range.min, 0, range.max) || !IN_RANGE(range.def, range.min, range.max)) { return -ERANGE; @@ -107,6 +108,9 @@ static inline void set_type_flag(uint32_t id, enum video_ctrl_type *type, uint32 *type = VIDEO_CTRL_TYPE_INTEGER64; *flags |= VIDEO_CTRL_FLAG_READ_ONLY; break; + case VIDEO_CID_LINK_FREQ: + *type = VIDEO_CTRL_TYPE_INTEGER_MENU; + break; default: *type = VIDEO_CTRL_TYPE_INTEGER; break; @@ -196,6 +200,28 @@ int video_init_menu_ctrl(struct video_ctrl *ctrl, const struct device *dev, uint return 0; } +int video_init_int_menu_ctrl(struct video_ctrl *ctrl, const struct device *dev, uint32_t id, + uint8_t def, const int64_t menu[], size_t menu_len) +{ + int ret; + + if (!menu) { + return -EINVAL; + } + + ret = video_init_ctrl( + ctrl, dev, id, + (struct video_ctrl_range){.min = 0, .max = menu_len - 1, .step = 1, .def = def}); + + if (ret) { + return ret; + } + + ctrl->int_menu = menu; + + return 0; +} + /* By definition, the cluster is in manual mode if the master control value is 0 */ static inline bool is_cluster_manual(const struct video_ctrl *master) { @@ -505,6 +531,8 @@ static inline const char *video_get_ctrl_name(uint32_t id) return "Pixel Rate"; case VIDEO_CID_TEST_PATTERN: return "Test Pattern"; + case VIDEO_CID_LINK_FREQ: + return "Link Frequency"; default: return NULL; } @@ -540,7 +568,11 @@ int video_query_ctrl(const struct device *dev, struct video_ctrl_query *cq) cq->type = ctrl->type; cq->flags = ctrl->flags; cq->range = ctrl->range; - cq->menu = ctrl->menu; + if (cq->type == VIDEO_CTRL_TYPE_MENU) { + cq->menu = ctrl->menu; + } else if (cq->type == VIDEO_CTRL_TYPE_INTEGER_MENU) { + cq->int_menu = ctrl->int_menu; + } cq->name = video_get_ctrl_name(cq->id); return 0; @@ -568,6 +600,9 @@ void video_print_ctrl(const struct device *const dev, const struct video_ctrl_qu case VIDEO_CTRL_TYPE_MENU: type = "menu"; break; + case VIDEO_CTRL_TYPE_INTEGER_MENU: + type = "integer menu"; + break; case VIDEO_CTRL_TYPE_STRING: type = "string"; break; @@ -594,10 +629,15 @@ void video_print_ctrl(const struct device *const dev, const struct video_ctrl_qu cq->range.step, cq->range.def, vc.val); } - if (cq->menu) { + if (cq->type == VIDEO_CTRL_TYPE_MENU && cq->menu) { while (cq->menu[i]) { LOG_INF("%*s %u: %s", 32, "", i, cq->menu[i]); i++; } + } else if (cq->type == VIDEO_CTRL_TYPE_INTEGER_MENU && cq->int_menu) { + while (cq->int_menu[i]) { + LOG_INF("%*s %u: %lld", 12, "", i, cq->int_menu[i]); + i++; + } } } diff --git a/drivers/video/video_ctrls.h b/drivers/video/video_ctrls.h index 07c6c5575f3a..485eacc4a3ce 100644 --- a/drivers/video/video_ctrls.h +++ b/drivers/video/video_ctrls.h @@ -27,10 +27,12 @@ enum video_ctrl_type { VIDEO_CTRL_TYPE_INTEGER = 2, /** 64-bit integer type */ VIDEO_CTRL_TYPE_INTEGER64 = 3, - /** Menu type, standard or driver-defined menu */ + /** Menu string type, standard or driver-defined menu */ VIDEO_CTRL_TYPE_MENU = 4, /** String type */ VIDEO_CTRL_TYPE_STRING = 5, + /** Menu integer type, standard or driver-defined menu */ + VIDEO_CTRL_TYPE_INTEGER_MENU = 6, }; struct video_device; @@ -54,7 +56,10 @@ struct video_ctrl { int32_t val; int64_t val64; }; - const char *const *menu; + union { + const char *const *menu; + const int64_t *int_menu; + }; sys_dnode_t node; }; @@ -64,6 +69,9 @@ int video_init_ctrl(struct video_ctrl *ctrl, const struct device *dev, uint32_t int video_init_menu_ctrl(struct video_ctrl *ctrl, const struct device *dev, uint32_t id, uint8_t def, const char *const menu[]); +int video_init_int_menu_ctrl(struct video_ctrl *ctrl, const struct device *dev, uint32_t id, + uint8_t def, const int64_t menu[], size_t menu_len); + void video_cluster_ctrl(struct video_ctrl *ctrls, uint8_t sz); void video_auto_cluster_ctrl(struct video_ctrl *ctrls, uint8_t sz, bool set_volatile); diff --git a/dts/bindings/video/galaxycore,gc2145.yaml b/dts/bindings/video/galaxycore,gc2145.yaml index a275023c3714..ee0e20d7516d 100644 --- a/dts/bindings/video/galaxycore,gc2145.yaml +++ b/dts/bindings/video/galaxycore,gc2145.yaml @@ -18,3 +18,7 @@ properties: description: | The PWDN pin is asserted to power down the sensor. The sensor receives this as an active high signal + +child-binding: + child-binding: + include: video-interfaces.yaml diff --git a/include/zephyr/drivers/video-controls.h b/include/zephyr/drivers/video-controls.h index 79141eb430d8..314c9f520396 100644 --- a/include/zephyr/drivers/video-controls.h +++ b/include/zephyr/drivers/video-controls.h @@ -362,6 +362,9 @@ enum video_camera_orientation { */ #define VIDEO_CID_IMAGE_PROC_CLASS_BASE 0x009f0900 +/** Link frequency, applicable for the CSI2 based devices */ +#define VIDEO_CID_LINK_FREQ (VIDEO_CID_IMAGE_PROC_CLASS_BASE + 1) + /** Pixel rate (pixels/second) in the device's pixel array. This control is read-only. */ #define VIDEO_CID_PIXEL_RATE (VIDEO_CID_IMAGE_PROC_CLASS_BASE + 2) @@ -463,7 +466,10 @@ struct video_ctrl_query { /** control range */ struct video_ctrl_range range; /** menu if control is of menu type */ - const char *const *menu; + union { + const char *const *menu; + const int64_t *int_menu; + }; }; /** diff --git a/include/zephyr/drivers/video.h b/include/zephyr/drivers/video.h index b5a706752589..8b4c13fd3a0f 100644 --- a/include/zephyr/drivers/video.h +++ b/include/zephyr/drivers/video.h @@ -804,6 +804,23 @@ void video_closest_frmival_stepwise(const struct video_frmival_stepwise *stepwis */ void video_closest_frmival(const struct device *dev, struct video_frmival_enum *match); +/** + * @brief Return the link-frequency advertised by a device + * + * Device exposing a CSI link should advertise at least one of the following two controls: + * - @ref VIDEO_CID_LINK_FREQ + * - @ref VIDEO_CID_PIXEL_RATE + * + * At first the helper will try read the @ref VIDEO_CID_LINK_FREQ and if not available will + * approximate the link-frequency from the @ref VIDEO_CID_PIXEL_RATE value, taking into + * consideration the bits per pixel of the format and the number of lanes. + * + * @param dev Video device to query. + * @param bpp Amount of bits per pixel of the pixel format produced by the device + * @param lane_nb Number of CSI-2 lanes used + */ +int64_t video_get_csi_link_freq(const struct device *dev, uint8_t bpp, uint8_t lane_nb); + /** * @defgroup video_pixel_formats Video pixel formats * The '|' characters separate the pixels or logical blocks, and spaces separate the bytes. @@ -1418,6 +1435,39 @@ static inline unsigned int video_bits_per_pixel(uint32_t pixfmt) } } +/** + * @} + */ + +/** + * @name MIPI CSI2 Data-types + * + * @{ + */ +#define VIDEO_MIPI_CSI2_DT_NULL 0x10 +#define VIDEO_MIPI_CSI2_DT_BLANKING 0x11 +#define VIDEO_MIPI_CSI2_DT_EMBEDDED_8 0x12 +#define VIDEO_MIPI_CSI2_DT_YUV420_8 0x18 +#define VIDEO_MIPI_CSI2_DT_YUV420_10 0x19 +#define VIDEO_MIPI_CSI2_DT_YUV420_CSPS_8 0x1c +#define VIDEO_MIPI_CSI2_DT_YUV420_CSPS_10 0x1d +#define VIDEO_MIPI_CSI2_DT_YUV422_8 0x1e +#define VIDEO_MIPI_CSI2_DT_YUV422_10 0x1f +#define VIDEO_MIPI_CSI2_DT_RGB444 0x20 +#define VIDEO_MIPI_CSI2_DT_RGB555 0x21 +#define VIDEO_MIPI_CSI2_DT_RGB565 0x22 +#define VIDEO_MIPI_CSI2_DT_RGB666 0x23 +#define VIDEO_MIPI_CSI2_DT_RGB888 0x24 +#define VIDEO_MIPI_CSI2_DT_RAW6 0x28 +#define VIDEO_MIPI_CSI2_DT_RAW7 0x29 +#define VIDEO_MIPI_CSI2_DT_RAW8 0x2a +#define VIDEO_MIPI_CSI2_DT_RAW10 0x2b +#define VIDEO_MIPI_CSI2_DT_RAW12 0x2c +#define VIDEO_MIPI_CSI2_DT_RAW14 0x2d + +/* User-defined Data-Type range from 0x30 to 0x37 */ +#define VIDEO_MIPI_CSI2_DT_USER(n) (0x30 + (n)) + /** * @} */