@@ -71,7 +71,11 @@ struct rzg2l_cru_ip {
* @yuv: Flag to indicate whether the format is YUV-based.
*/
struct rzg2l_cru_ip_format {
- u32 code;
+ /*
+ * RAW output formats might be produced by RAW media codes with any one
+ * of the 4 common bayer patterns.
+ */
+ u32 codes[4];
u32 datatype;
u32 format;
u32 icndmr;
@@ -190,6 +194,8 @@ struct v4l2_mbus_framefmt *rzg2l_cru_ip_get_src_fmt(struct rzg2l_cru_dev *cru);
const struct rzg2l_cru_ip_format *rzg2l_cru_ip_code_to_fmt(unsigned int code);
const struct rzg2l_cru_ip_format *rzg2l_cru_ip_format_to_fmt(u32 format);
const struct rzg2l_cru_ip_format *rzg2l_cru_ip_index_to_fmt(u32 index);
+bool rzg2l_cru_ip_fmt_supports_mbus_code(const struct rzg2l_cru_ip_format *fmt,
+ unsigned int code);
void rzg2l_cru_enable_interrupts(struct rzg2l_cru_dev *cru);
void rzg2l_cru_disable_interrupts(struct rzg2l_cru_dev *cru);
@@ -13,35 +13,45 @@
static const struct rzg2l_cru_ip_format rzg2l_cru_ip_formats[] = {
{
- .code = MEDIA_BUS_FMT_UYVY8_1X16,
+ .codes = {
+ MEDIA_BUS_FMT_UYVY8_1X16,
+ },
.datatype = MIPI_CSI2_DT_YUV422_8B,
.format = V4L2_PIX_FMT_UYVY,
.icndmr = ICnDMR_YCMODE_UYVY,
.yuv = true,
},
{
- .code = MEDIA_BUS_FMT_SBGGR8_1X8,
+ .codes = {
+ MEDIA_BUS_FMT_SBGGR8_1X8,
+ },
.format = V4L2_PIX_FMT_SBGGR8,
.datatype = MIPI_CSI2_DT_RAW8,
.icndmr = 0,
.yuv = false,
},
{
- .code = MEDIA_BUS_FMT_SGBRG8_1X8,
+ .codes = {
+ MEDIA_BUS_FMT_SGBRG8_1X8,
+ },
.format = V4L2_PIX_FMT_SGBRG8,
.datatype = MIPI_CSI2_DT_RAW8,
.icndmr = 0,
.yuv = false,
},
{
- .code = MEDIA_BUS_FMT_SGRBG8_1X8,
+ .codes = {
+ MEDIA_BUS_FMT_SGRBG8_1X8,
+ },
.format = V4L2_PIX_FMT_SGRBG8,
.datatype = MIPI_CSI2_DT_RAW8,
.icndmr = 0,
.yuv = false,
},
{
- .code = MEDIA_BUS_FMT_SRGGB8_1X8,
+ .codes = {
+ MEDIA_BUS_FMT_SRGGB8_1X8,
+ },
.format = V4L2_PIX_FMT_SRGGB8,
.datatype = MIPI_CSI2_DT_RAW8,
.icndmr = 0,
@@ -51,11 +61,14 @@ static const struct rzg2l_cru_ip_format rzg2l_cru_ip_formats[] = {
const struct rzg2l_cru_ip_format *rzg2l_cru_ip_code_to_fmt(unsigned int code)
{
- unsigned int i;
+ unsigned int i, j;
- for (i = 0; i < ARRAY_SIZE(rzg2l_cru_ip_formats); i++)
- if (rzg2l_cru_ip_formats[i].code == code)
- return &rzg2l_cru_ip_formats[i];
+ for (i = 0; i < ARRAY_SIZE(rzg2l_cru_ip_formats); i++) {
+ for (j = 0; j < ARRAY_SIZE(rzg2l_cru_ip_formats[i].codes); j++) {
+ if (rzg2l_cru_ip_formats[i].codes[j] == code)
+ return &rzg2l_cru_ip_formats[i];
+ }
+ }
return NULL;
}
@@ -80,6 +93,17 @@ const struct rzg2l_cru_ip_format *rzg2l_cru_ip_index_to_fmt(u32 index)
return &rzg2l_cru_ip_formats[index];
}
+bool rzg2l_cru_ip_fmt_supports_mbus_code(const struct rzg2l_cru_ip_format *fmt,
+ unsigned int code)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(fmt->codes); i++)
+ if (fmt->codes[i] == code)
+ return true;
+
+ return false;
+}
struct v4l2_mbus_framefmt *rzg2l_cru_ip_get_src_fmt(struct rzg2l_cru_dev *cru)
{
struct v4l2_subdev_state *state;
@@ -157,7 +181,7 @@ static int rzg2l_cru_ip_set_format(struct v4l2_subdev *sd,
sink_format = v4l2_subdev_state_get_format(state, fmt->pad);
if (!rzg2l_cru_ip_code_to_fmt(fmt->format.code))
- sink_format->code = rzg2l_cru_ip_formats[0].code;
+ sink_format->code = rzg2l_cru_ip_formats[0].codes[0];
else
sink_format->code = fmt->format.code;
@@ -183,11 +207,26 @@ static int rzg2l_cru_ip_enum_mbus_code(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state,
struct v4l2_subdev_mbus_code_enum *code)
{
- if (code->index >= ARRAY_SIZE(rzg2l_cru_ip_formats))
- return -EINVAL;
+ unsigned int index = code->index;
+ unsigned int i, j;
- code->code = rzg2l_cru_ip_formats[code->index].code;
- return 0;
+ for (i = 0; i < ARRAY_SIZE(rzg2l_cru_ip_formats); i++) {
+ const struct rzg2l_cru_ip_format *fmt = &rzg2l_cru_ip_formats[i];
+
+ for (j = 0; j < ARRAY_SIZE(fmt->codes); j++) {
+ if (!fmt->codes[j])
+ continue;
+
+ if (!index) {
+ code->code = fmt->codes[j];
+ return 0;
+ }
+
+ index--;
+ }
+ }
+
+ return -EINVAL;
}
static int rzg2l_cru_ip_enum_frame_size(struct v4l2_subdev *sd,
@@ -1149,7 +1149,7 @@ static int rzg2l_cru_video_link_validate(struct media_link *link)
if (fmt.format.width != cru->format.width ||
fmt.format.height != cru->format.height ||
fmt.format.field != cru->format.field ||
- video_fmt->code != fmt.format.code)
+ !rzg2l_cru_ip_fmt_supports_mbus_code(video_fmt, fmt.format.code))
return -EPIPE;
return 0;