aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/staging/media/imx/imx-media-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/media/imx/imx-media-utils.c')
-rw-r--r--drivers/staging/media/imx/imx-media-utils.c550
1 files changed, 247 insertions, 303 deletions
diff --git a/drivers/staging/media/imx/imx-media-utils.c b/drivers/staging/media/imx/imx-media-utils.c
index fae981698c49..c2088f7ceef5 100644
--- a/drivers/staging/media/imx/imx-media-utils.c
+++ b/drivers/staging/media/imx/imx-media-utils.c
@@ -7,36 +7,30 @@
#include <linux/module.h>
#include "imx-media.h"
+#define IMX_BUS_FMTS(fmt...) (const u32[]) {fmt, 0}
+
/*
* List of supported pixel formats for the subdevs.
- *
- * In all of these tables, the non-mbus formats (with no
- * mbus codes) must all fall at the end of the table.
*/
-
-static const struct imx_media_pixfmt yuv_formats[] = {
+static const struct imx_media_pixfmt pixel_formats[] = {
+ /*** YUV formats start here ***/
{
.fourcc = V4L2_PIX_FMT_UYVY,
- .codes = {
+ .codes = IMX_BUS_FMTS(
MEDIA_BUS_FMT_UYVY8_2X8,
MEDIA_BUS_FMT_UYVY8_1X16
- },
+ ),
.cs = IPUV3_COLORSPACE_YUV,
.bpp = 16,
}, {
.fourcc = V4L2_PIX_FMT_YUYV,
- .codes = {
+ .codes = IMX_BUS_FMTS(
MEDIA_BUS_FMT_YUYV8_2X8,
MEDIA_BUS_FMT_YUYV8_1X16
- },
+ ),
.cs = IPUV3_COLORSPACE_YUV,
.bpp = 16,
- },
- /***
- * non-mbus YUV formats start here. NOTE! when adding non-mbus
- * formats, NUM_NON_MBUS_YUV_FORMATS must be updated below.
- ***/
- {
+ }, {
.fourcc = V4L2_PIX_FMT_YUV420,
.cs = IPUV3_COLORSPACE_YUV,
.bpp = 12,
@@ -61,213 +55,212 @@ static const struct imx_media_pixfmt yuv_formats[] = {
.cs = IPUV3_COLORSPACE_YUV,
.bpp = 16,
.planar = true,
+ }, {
+ .fourcc = V4L2_PIX_FMT_YUV32,
+ .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_AYUV8_1X32),
+ .cs = IPUV3_COLORSPACE_YUV,
+ .bpp = 32,
+ .ipufmt = true,
},
-};
-
-#define NUM_NON_MBUS_YUV_FORMATS 5
-#define NUM_YUV_FORMATS ARRAY_SIZE(yuv_formats)
-#define NUM_MBUS_YUV_FORMATS (NUM_YUV_FORMATS - NUM_NON_MBUS_YUV_FORMATS)
-
-static const struct imx_media_pixfmt rgb_formats[] = {
+ /*** RGB formats start here ***/
{
.fourcc = V4L2_PIX_FMT_RGB565,
- .codes = {MEDIA_BUS_FMT_RGB565_2X8_LE},
+ .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_RGB565_2X8_LE),
.cs = IPUV3_COLORSPACE_RGB,
.bpp = 16,
.cycles = 2,
}, {
.fourcc = V4L2_PIX_FMT_RGB24,
- .codes = {
+ .codes = IMX_BUS_FMTS(
MEDIA_BUS_FMT_RGB888_1X24,
MEDIA_BUS_FMT_RGB888_2X12_LE
- },
+ ),
+ .cs = IPUV3_COLORSPACE_RGB,
+ .bpp = 24,
+ }, {
+ .fourcc = V4L2_PIX_FMT_BGR24,
.cs = IPUV3_COLORSPACE_RGB,
.bpp = 24,
}, {
.fourcc = V4L2_PIX_FMT_XRGB32,
- .codes = {MEDIA_BUS_FMT_ARGB8888_1X32},
+ .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_ARGB8888_1X32),
+ .cs = IPUV3_COLORSPACE_RGB,
+ .bpp = 32,
+ }, {
+ .fourcc = V4L2_PIX_FMT_XRGB32,
+ .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_ARGB8888_1X32),
.cs = IPUV3_COLORSPACE_RGB,
.bpp = 32,
.ipufmt = true,
+ }, {
+ .fourcc = V4L2_PIX_FMT_XBGR32,
+ .cs = IPUV3_COLORSPACE_RGB,
+ .bpp = 32,
+ }, {
+ .fourcc = V4L2_PIX_FMT_BGRX32,
+ .cs = IPUV3_COLORSPACE_RGB,
+ .bpp = 32,
+ }, {
+ .fourcc = V4L2_PIX_FMT_RGBX32,
+ .cs = IPUV3_COLORSPACE_RGB,
+ .bpp = 32,
},
/*** raw bayer and grayscale formats start here ***/
{
.fourcc = V4L2_PIX_FMT_SBGGR8,
- .codes = {MEDIA_BUS_FMT_SBGGR8_1X8},
+ .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_SBGGR8_1X8),
.cs = IPUV3_COLORSPACE_RGB,
.bpp = 8,
.bayer = true,
}, {
.fourcc = V4L2_PIX_FMT_SGBRG8,
- .codes = {MEDIA_BUS_FMT_SGBRG8_1X8},
+ .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_SGBRG8_1X8),
.cs = IPUV3_COLORSPACE_RGB,
.bpp = 8,
.bayer = true,
}, {
.fourcc = V4L2_PIX_FMT_SGRBG8,
- .codes = {MEDIA_BUS_FMT_SGRBG8_1X8},
+ .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_SGRBG8_1X8),
.cs = IPUV3_COLORSPACE_RGB,
.bpp = 8,
.bayer = true,
}, {
.fourcc = V4L2_PIX_FMT_SRGGB8,
- .codes = {MEDIA_BUS_FMT_SRGGB8_1X8},
+ .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_SRGGB8_1X8),
.cs = IPUV3_COLORSPACE_RGB,
.bpp = 8,
.bayer = true,
}, {
.fourcc = V4L2_PIX_FMT_SBGGR16,
- .codes = {
+ .codes = IMX_BUS_FMTS(
MEDIA_BUS_FMT_SBGGR10_1X10,
MEDIA_BUS_FMT_SBGGR12_1X12,
MEDIA_BUS_FMT_SBGGR14_1X14,
MEDIA_BUS_FMT_SBGGR16_1X16
- },
+ ),
.cs = IPUV3_COLORSPACE_RGB,
.bpp = 16,
.bayer = true,
}, {
.fourcc = V4L2_PIX_FMT_SGBRG16,
- .codes = {
+ .codes = IMX_BUS_FMTS(
MEDIA_BUS_FMT_SGBRG10_1X10,
MEDIA_BUS_FMT_SGBRG12_1X12,
MEDIA_BUS_FMT_SGBRG14_1X14,
- MEDIA_BUS_FMT_SGBRG16_1X16,
- },
+ MEDIA_BUS_FMT_SGBRG16_1X16
+ ),
.cs = IPUV3_COLORSPACE_RGB,
.bpp = 16,
.bayer = true,
}, {
.fourcc = V4L2_PIX_FMT_SGRBG16,
- .codes = {
+ .codes = IMX_BUS_FMTS(
MEDIA_BUS_FMT_SGRBG10_1X10,
MEDIA_BUS_FMT_SGRBG12_1X12,
MEDIA_BUS_FMT_SGRBG14_1X14,
- MEDIA_BUS_FMT_SGRBG16_1X16,
- },
+ MEDIA_BUS_FMT_SGRBG16_1X16
+ ),
.cs = IPUV3_COLORSPACE_RGB,
.bpp = 16,
.bayer = true,
}, {
.fourcc = V4L2_PIX_FMT_SRGGB16,
- .codes = {
+ .codes = IMX_BUS_FMTS(
MEDIA_BUS_FMT_SRGGB10_1X10,
MEDIA_BUS_FMT_SRGGB12_1X12,
MEDIA_BUS_FMT_SRGGB14_1X14,
- MEDIA_BUS_FMT_SRGGB16_1X16,
- },
+ MEDIA_BUS_FMT_SRGGB16_1X16
+ ),
.cs = IPUV3_COLORSPACE_RGB,
.bpp = 16,
.bayer = true,
}, {
.fourcc = V4L2_PIX_FMT_GREY,
- .codes = {
+ .codes = IMX_BUS_FMTS(
MEDIA_BUS_FMT_Y8_1X8,
MEDIA_BUS_FMT_Y10_1X10,
- MEDIA_BUS_FMT_Y12_1X12,
- },
+ MEDIA_BUS_FMT_Y12_1X12
+ ),
.cs = IPUV3_COLORSPACE_RGB,
.bpp = 8,
.bayer = true,
}, {
.fourcc = V4L2_PIX_FMT_Y10,
- .codes = {MEDIA_BUS_FMT_Y10_1X10},
+ .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_Y10_1X10),
.cs = IPUV3_COLORSPACE_RGB,
.bpp = 16,
.bayer = true,
}, {
.fourcc = V4L2_PIX_FMT_Y12,
- .codes = {MEDIA_BUS_FMT_Y12_1X12},
+ .codes = IMX_BUS_FMTS(MEDIA_BUS_FMT_Y12_1X12),
.cs = IPUV3_COLORSPACE_RGB,
.bpp = 16,
.bayer = true,
},
- /***
- * non-mbus RGB formats start here. NOTE! when adding non-mbus
- * formats, NUM_NON_MBUS_RGB_FORMATS must be updated below.
- ***/
- {
- .fourcc = V4L2_PIX_FMT_BGR24,
- .cs = IPUV3_COLORSPACE_RGB,
- .bpp = 24,
- }, {
- .fourcc = V4L2_PIX_FMT_XBGR32,
- .cs = IPUV3_COLORSPACE_RGB,
- .bpp = 32,
- }, {
- .fourcc = V4L2_PIX_FMT_BGRX32,
- .cs = IPUV3_COLORSPACE_RGB,
- .bpp = 32,
- }, {
- .fourcc = V4L2_PIX_FMT_RGBX32,
- .cs = IPUV3_COLORSPACE_RGB,
- .bpp = 32,
- },
};
-#define NUM_NON_MBUS_RGB_FORMATS 2
-#define NUM_RGB_FORMATS ARRAY_SIZE(rgb_formats)
-#define NUM_MBUS_RGB_FORMATS (NUM_RGB_FORMATS - NUM_NON_MBUS_RGB_FORMATS)
+/*
+ * Search in the pixel_formats[] array for an entry with the given fourcc
+ * that matches the requested selection criteria and return it.
+ *
+ * @fourcc: Search for an entry with the given fourcc pixel format.
+ * @fmt_sel: Allow entries only with the given selection criteria.
+ */
+const struct imx_media_pixfmt *
+imx_media_find_pixel_format(u32 fourcc, enum imx_pixfmt_sel fmt_sel)
+{
+ bool sel_ipu = fmt_sel & PIXFMT_SEL_IPU;
+ unsigned int i;
-static const struct imx_media_pixfmt ipu_yuv_formats[] = {
- {
- .fourcc = V4L2_PIX_FMT_YUV32,
- .codes = {MEDIA_BUS_FMT_AYUV8_1X32},
- .cs = IPUV3_COLORSPACE_YUV,
- .bpp = 32,
- .ipufmt = true,
- },
-};
+ fmt_sel &= ~PIXFMT_SEL_IPU;
-#define NUM_IPU_YUV_FORMATS ARRAY_SIZE(ipu_yuv_formats)
+ for (i = 0; i < ARRAY_SIZE(pixel_formats); i++) {
+ const struct imx_media_pixfmt *fmt = &pixel_formats[i];
+ enum imx_pixfmt_sel sel;
-static const struct imx_media_pixfmt ipu_rgb_formats[] = {
- {
- .fourcc = V4L2_PIX_FMT_XRGB32,
- .codes = {MEDIA_BUS_FMT_ARGB8888_1X32},
- .cs = IPUV3_COLORSPACE_RGB,
- .bpp = 32,
- .ipufmt = true,
- },
-};
+ if (sel_ipu != fmt->ipufmt)
+ continue;
-#define NUM_IPU_RGB_FORMATS ARRAY_SIZE(ipu_rgb_formats)
+ sel = fmt->bayer ? PIXFMT_SEL_BAYER :
+ ((fmt->cs == IPUV3_COLORSPACE_YUV) ?
+ PIXFMT_SEL_YUV : PIXFMT_SEL_RGB);
-static void init_mbus_colorimetry(struct v4l2_mbus_framefmt *mbus,
- const struct imx_media_pixfmt *fmt)
-{
- mbus->colorspace = (fmt->cs == IPUV3_COLORSPACE_RGB) ?
- V4L2_COLORSPACE_SRGB : V4L2_COLORSPACE_SMPTE170M;
- mbus->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(mbus->colorspace);
- mbus->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(mbus->colorspace);
- mbus->quantization =
- V4L2_MAP_QUANTIZATION_DEFAULT(fmt->cs == IPUV3_COLORSPACE_RGB,
- mbus->colorspace,
- mbus->ycbcr_enc);
+ if ((fmt_sel & sel) && fmt->fourcc == fourcc)
+ return fmt;
+ }
+
+ return NULL;
}
+EXPORT_SYMBOL_GPL(imx_media_find_pixel_format);
-static const
-struct imx_media_pixfmt *__find_format(u32 fourcc,
- u32 code,
- bool allow_non_mbus,
- bool allow_bayer,
- const struct imx_media_pixfmt *array,
- u32 array_size)
+/*
+ * Search in the pixel_formats[] array for an entry with the given media
+ * bus code that matches the requested selection criteria and return it.
+ *
+ * @code: Search for an entry with the given media-bus code.
+ * @fmt_sel: Allow entries only with the given selection criteria.
+ */
+const struct imx_media_pixfmt *
+imx_media_find_mbus_format(u32 code, enum imx_pixfmt_sel fmt_sel)
{
- const struct imx_media_pixfmt *fmt;
- int i, j;
+ bool sel_ipu = fmt_sel & PIXFMT_SEL_IPU;
+ unsigned int i;
+
+ fmt_sel &= ~PIXFMT_SEL_IPU;
- for (i = 0; i < array_size; i++) {
- fmt = &array[i];
+ for (i = 0; i < ARRAY_SIZE(pixel_formats); i++) {
+ const struct imx_media_pixfmt *fmt = &pixel_formats[i];
+ enum imx_pixfmt_sel sel;
+ unsigned int j;
- if ((!allow_non_mbus && !fmt->codes[0]) ||
- (!allow_bayer && fmt->bayer))
+ if (sel_ipu != fmt->ipufmt)
continue;
- if (fourcc && fmt->fourcc == fourcc)
- return fmt;
+ sel = fmt->bayer ? PIXFMT_SEL_BAYER :
+ ((fmt->cs == IPUV3_COLORSPACE_YUV) ?
+ PIXFMT_SEL_YUV : PIXFMT_SEL_RGB);
- if (!code)
+ if (!(fmt_sel & sel) || !fmt->codes)
continue;
for (j = 0; fmt->codes[j]; j++) {
@@ -275,199 +268,103 @@ struct imx_media_pixfmt *__find_format(u32 fourcc,
return fmt;
}
}
+
return NULL;
}
+EXPORT_SYMBOL_GPL(imx_media_find_mbus_format);
-static const struct imx_media_pixfmt *find_format(u32 fourcc,
- u32 code,
- enum codespace_sel cs_sel,
- bool allow_non_mbus,
- bool allow_bayer)
+/*
+ * Enumerate entries in the pixel_formats[] array that match the
+ * requested selection criteria. Return the fourcc that matches the
+ * selection criteria at the requested match index.
+ *
+ * @fourcc: The returned fourcc that matches the search criteria at
+ * the requested match index.
+ * @index: The requested match index.
+ * @fmt_sel: Include in the enumeration entries with the given selection
+ * criteria.
+ */
+int imx_media_enum_pixel_formats(u32 *fourcc, u32 index,
+ enum imx_pixfmt_sel fmt_sel)
{
- const struct imx_media_pixfmt *ret;
-
- switch (cs_sel) {
- case CS_SEL_YUV:
- return __find_format(fourcc, code, allow_non_mbus, allow_bayer,
- yuv_formats, NUM_YUV_FORMATS);
- case CS_SEL_RGB:
- return __find_format(fourcc, code, allow_non_mbus, allow_bayer,
- rgb_formats, NUM_RGB_FORMATS);
- case CS_SEL_ANY:
- ret = __find_format(fourcc, code, allow_non_mbus, allow_bayer,
- yuv_formats, NUM_YUV_FORMATS);
- if (ret)
- return ret;
- return __find_format(fourcc, code, allow_non_mbus, allow_bayer,
- rgb_formats, NUM_RGB_FORMATS);
- default:
- return NULL;
- }
-}
+ bool sel_ipu = fmt_sel & PIXFMT_SEL_IPU;
+ unsigned int i;
-static int enum_format(u32 *fourcc, u32 *code, u32 index,
- enum codespace_sel cs_sel,
- bool allow_non_mbus,
- bool allow_bayer)
-{
- const struct imx_media_pixfmt *fmt;
- u32 mbus_yuv_sz = NUM_MBUS_YUV_FORMATS;
- u32 mbus_rgb_sz = NUM_MBUS_RGB_FORMATS;
- u32 yuv_sz = NUM_YUV_FORMATS;
- u32 rgb_sz = NUM_RGB_FORMATS;
-
- switch (cs_sel) {
- case CS_SEL_YUV:
- if (index >= yuv_sz ||
- (!allow_non_mbus && index >= mbus_yuv_sz))
- return -EINVAL;
- fmt = &yuv_formats[index];
- break;
- case CS_SEL_RGB:
- if (index >= rgb_sz ||
- (!allow_non_mbus && index >= mbus_rgb_sz))
- return -EINVAL;
- fmt = &rgb_formats[index];
- if (!allow_bayer && fmt->bayer)
- return -EINVAL;
- break;
- case CS_SEL_ANY:
- if (!allow_non_mbus) {
- if (index >= mbus_yuv_sz) {
- index -= mbus_yuv_sz;
- if (index >= mbus_rgb_sz)
- return -EINVAL;
- fmt = &rgb_formats[index];
- if (!allow_bayer && fmt->bayer)
- return -EINVAL;
- } else {
- fmt = &yuv_formats[index];
- }
- } else {
- if (index >= yuv_sz + rgb_sz)
- return -EINVAL;
- if (index >= yuv_sz) {
- fmt = &rgb_formats[index - yuv_sz];
- if (!allow_bayer && fmt->bayer)
- return -EINVAL;
- } else {
- fmt = &yuv_formats[index];
- }
+ fmt_sel &= ~PIXFMT_SEL_IPU;
+
+ for (i = 0; i < ARRAY_SIZE(pixel_formats); i++) {
+ const struct imx_media_pixfmt *fmt = &pixel_formats[i];
+ enum imx_pixfmt_sel sel;
+
+ if (sel_ipu != fmt->ipufmt)
+ continue;
+
+ sel = fmt->bayer ? PIXFMT_SEL_BAYER :
+ ((fmt->cs == IPUV3_COLORSPACE_YUV) ?
+ PIXFMT_SEL_YUV : PIXFMT_SEL_RGB);
+
+ if (!(fmt_sel & sel))
+ continue;
+
+ if (index == 0) {
+ *fourcc = fmt->fourcc;
+ return 0;
}
- break;
- default:
- return -EINVAL;
- }
- if (fourcc)
- *fourcc = fmt->fourcc;
- if (code)
- *code = fmt->codes[0];
+ index--;
+ }
- return 0;
+ return -EINVAL;
}
+EXPORT_SYMBOL_GPL(imx_media_enum_pixel_formats);
-const struct imx_media_pixfmt *
-imx_media_find_format(u32 fourcc, enum codespace_sel cs_sel, bool allow_bayer)
+/*
+ * Enumerate entries in the pixel_formats[] array that match the
+ * requested search criteria. Return the media-bus code that matches
+ * the search criteria at the requested match index.
+ *
+ * @code: The returned media-bus code that matches the search criteria at
+ * the requested match index.
+ * @index: The requested match index.
+ * @fmt_sel: Include in the enumeration entries with the given selection
+ * criteria.
+ */
+int imx_media_enum_mbus_formats(u32 *code, u32 index,
+ enum imx_pixfmt_sel fmt_sel)
{
- return find_format(fourcc, 0, cs_sel, true, allow_bayer);
-}
-EXPORT_SYMBOL_GPL(imx_media_find_format);
+ bool sel_ipu = fmt_sel & PIXFMT_SEL_IPU;
+ unsigned int i;
-int imx_media_enum_format(u32 *fourcc, u32 index, enum codespace_sel cs_sel)
-{
- return enum_format(fourcc, NULL, index, cs_sel, true, false);
-}
-EXPORT_SYMBOL_GPL(imx_media_enum_format);
+ fmt_sel &= ~PIXFMT_SEL_IPU;
-const struct imx_media_pixfmt *
-imx_media_find_mbus_format(u32 code, enum codespace_sel cs_sel,
- bool allow_bayer)
-{
- return find_format(0, code, cs_sel, false, allow_bayer);
-}
-EXPORT_SYMBOL_GPL(imx_media_find_mbus_format);
+ for (i = 0; i < ARRAY_SIZE(pixel_formats); i++) {
+ const struct imx_media_pixfmt *fmt = &pixel_formats[i];
+ enum imx_pixfmt_sel sel;
+ unsigned int j;
-int imx_media_enum_mbus_format(u32 *code, u32 index, enum codespace_sel cs_sel,
- bool allow_bayer)
-{
- return enum_format(NULL, code, index, cs_sel, false, allow_bayer);
-}
-EXPORT_SYMBOL_GPL(imx_media_enum_mbus_format);
+ if (sel_ipu != fmt->ipufmt)
+ continue;
-const struct imx_media_pixfmt *
-imx_media_find_ipu_format(u32 code, enum codespace_sel cs_sel)
-{
- const struct imx_media_pixfmt *array, *fmt, *ret = NULL;
- u32 array_size;
- int i, j;
-
- switch (cs_sel) {
- case CS_SEL_YUV:
- array_size = NUM_IPU_YUV_FORMATS;
- array = ipu_yuv_formats;
- break;
- case CS_SEL_RGB:
- array_size = NUM_IPU_RGB_FORMATS;
- array = ipu_rgb_formats;
- break;
- case CS_SEL_ANY:
- array_size = NUM_IPU_YUV_FORMATS + NUM_IPU_RGB_FORMATS;
- array = ipu_yuv_formats;
- break;
- default:
- return NULL;
- }
+ sel = fmt->bayer ? PIXFMT_SEL_BAYER :
+ ((fmt->cs == IPUV3_COLORSPACE_YUV) ?
+ PIXFMT_SEL_YUV : PIXFMT_SEL_RGB);
- for (i = 0; i < array_size; i++) {
- if (cs_sel == CS_SEL_ANY && i >= NUM_IPU_YUV_FORMATS)
- fmt = &ipu_rgb_formats[i - NUM_IPU_YUV_FORMATS];
- else
- fmt = &array[i];
+ if (!(fmt_sel & sel) || !fmt->codes)
+ continue;
- for (j = 0; code && fmt->codes[j]; j++) {
- if (code == fmt->codes[j]) {
- ret = fmt;
- goto out;
+ for (j = 0; fmt->codes[j]; j++) {
+ if (index == 0) {
+ *code = fmt->codes[j];
+ return 0;
}
- }
- }
-out:
- return ret;
-}
-EXPORT_SYMBOL_GPL(imx_media_find_ipu_format);
-
-int imx_media_enum_ipu_format(u32 *code, u32 index, enum codespace_sel cs_sel)
-{
- switch (cs_sel) {
- case CS_SEL_YUV:
- if (index >= NUM_IPU_YUV_FORMATS)
- return -EINVAL;
- *code = ipu_yuv_formats[index].codes[0];
- break;
- case CS_SEL_RGB:
- if (index >= NUM_IPU_RGB_FORMATS)
- return -EINVAL;
- *code = ipu_rgb_formats[index].codes[0];
- break;
- case CS_SEL_ANY:
- if (index >= NUM_IPU_YUV_FORMATS + NUM_IPU_RGB_FORMATS)
- return -EINVAL;
- if (index >= NUM_IPU_YUV_FORMATS) {
- index -= NUM_IPU_YUV_FORMATS;
- *code = ipu_rgb_formats[index].codes[0];
- } else {
- *code = ipu_yuv_formats[index].codes[0];
+ index--;
}
- break;
- default:
- return -EINVAL;
}
- return 0;
+ return -EINVAL;
}
-EXPORT_SYMBOL_GPL(imx_media_enum_ipu_format);
+EXPORT_SYMBOL_GPL(imx_media_enum_mbus_formats);
int imx_media_init_mbus_fmt(struct v4l2_mbus_framefmt *mbus,
u32 width, u32 height, u32 code, u32 field,
@@ -478,17 +375,27 @@ int imx_media_init_mbus_fmt(struct v4l2_mbus_framefmt *mbus,
mbus->width = width;
mbus->height = height;
mbus->field = field;
+
if (code == 0)
- imx_media_enum_mbus_format(&code, 0, CS_SEL_YUV, false);
- lcc = imx_media_find_mbus_format(code, CS_SEL_ANY, false);
+ imx_media_enum_mbus_formats(&code, 0, PIXFMT_SEL_YUV);
+
+ lcc = imx_media_find_mbus_format(code, PIXFMT_SEL_ANY);
if (!lcc) {
- lcc = imx_media_find_ipu_format(code, CS_SEL_ANY);
+ lcc = imx_media_find_ipu_format(code, PIXFMT_SEL_YUV_RGB);
if (!lcc)
return -EINVAL;
}
mbus->code = code;
- init_mbus_colorimetry(mbus, lcc);
+
+ mbus->colorspace = V4L2_COLORSPACE_SRGB;
+ mbus->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(mbus->colorspace);
+ mbus->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(mbus->colorspace);
+ mbus->quantization =
+ V4L2_MAP_QUANTIZATION_DEFAULT(lcc->cs == IPUV3_COLORSPACE_RGB,
+ mbus->colorspace,
+ mbus->ycbcr_enc);
+
if (cc)
*cc = lcc;
@@ -542,9 +449,11 @@ void imx_media_try_colorimetry(struct v4l2_mbus_framefmt *tryfmt,
const struct imx_media_pixfmt *cc;
bool is_rgb = false;
- cc = imx_media_find_mbus_format(tryfmt->code, CS_SEL_ANY, true);
+ cc = imx_media_find_mbus_format(tryfmt->code, PIXFMT_SEL_ANY);
if (!cc)
- cc = imx_media_find_ipu_format(tryfmt->code, CS_SEL_ANY);
+ cc = imx_media_find_ipu_format(tryfmt->code,
+ PIXFMT_SEL_YUV_RGB);
+
if (cc && cc->cs == IPUV3_COLORSPACE_RGB)
is_rgb = true;
@@ -587,17 +496,18 @@ void imx_media_try_colorimetry(struct v4l2_mbus_framefmt *tryfmt,
EXPORT_SYMBOL_GPL(imx_media_try_colorimetry);
int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix,
- struct v4l2_mbus_framefmt *mbus,
+ const struct v4l2_mbus_framefmt *mbus,
const struct imx_media_pixfmt *cc)
{
u32 width;
u32 stride;
if (!cc) {
- cc = imx_media_find_ipu_format(mbus->code, CS_SEL_ANY);
+ cc = imx_media_find_ipu_format(mbus->code,
+ PIXFMT_SEL_YUV_RGB);
if (!cc)
- cc = imx_media_find_mbus_format(mbus->code, CS_SEL_ANY,
- true);
+ cc = imx_media_find_mbus_format(mbus->code,
+ PIXFMT_SEL_ANY);
if (!cc)
return -EINVAL;
}
@@ -609,8 +519,8 @@ int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix,
if (cc->ipufmt && cc->cs == IPUV3_COLORSPACE_YUV) {
u32 code;
- imx_media_enum_mbus_format(&code, 0, CS_SEL_YUV, false);
- cc = imx_media_find_mbus_format(code, CS_SEL_YUV, false);
+ imx_media_enum_mbus_formats(&code, 0, PIXFMT_SEL_YUV);
+ cc = imx_media_find_mbus_format(code, PIXFMT_SEL_YUV);
}
/* Round up width for minimum burst size */
@@ -639,7 +549,7 @@ int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix,
EXPORT_SYMBOL_GPL(imx_media_mbus_fmt_to_pix_fmt);
int imx_media_mbus_fmt_to_ipu_image(struct ipu_image *image,
- struct v4l2_mbus_framefmt *mbus)
+ const struct v4l2_mbus_framefmt *mbus)
{
int ret;
@@ -657,12 +567,13 @@ int imx_media_mbus_fmt_to_ipu_image(struct ipu_image *image,
EXPORT_SYMBOL_GPL(imx_media_mbus_fmt_to_ipu_image);
int imx_media_ipu_image_to_mbus_fmt(struct v4l2_mbus_framefmt *mbus,
- struct ipu_image *image)
+ const struct ipu_image *image)
{
const struct imx_media_pixfmt *fmt;
- fmt = imx_media_find_format(image->pix.pixelformat, CS_SEL_ANY, true);
- if (!fmt)
+ fmt = imx_media_find_pixel_format(image->pix.pixelformat,
+ PIXFMT_SEL_ANY);
+ if (!fmt || !fmt->codes || !fmt->codes[0])
return -EINVAL;
memset(mbus, 0, sizeof(*mbus));
@@ -924,6 +835,39 @@ imx_media_pipeline_video_device(struct media_entity *start_entity,
EXPORT_SYMBOL_GPL(imx_media_pipeline_video_device);
/*
+ * Find a fwnode endpoint that maps to the given subdevice's pad.
+ * If there are multiple endpoints that map to the pad, only the
+ * first endpoint encountered is returned.
+ *
+ * On success the refcount of the returned fwnode endpoint is
+ * incremented.
+ */
+struct fwnode_handle *imx_media_get_pad_fwnode(struct media_pad *pad)
+{
+ struct fwnode_handle *endpoint;
+ struct v4l2_subdev *sd;
+
+ if (!is_media_entity_v4l2_subdev(pad->entity))
+ return ERR_PTR(-ENODEV);
+
+ sd = media_entity_to_v4l2_subdev(pad->entity);
+
+ fwnode_graph_for_each_endpoint(dev_fwnode(sd->dev), endpoint) {
+ int pad_idx = media_entity_get_fwnode_pad(&sd->entity,
+ endpoint,
+ pad->flags);
+ if (pad_idx < 0)
+ continue;
+
+ if (pad_idx == pad->index)
+ return endpoint;
+ }
+
+ return ERR_PTR(-ENODEV);
+}
+EXPORT_SYMBOL_GPL(imx_media_get_pad_fwnode);
+
+/*
* Turn current pipeline streaming on/off starting from entity.
*/
int imx_media_pipeline_set_stream(struct imx_media_dev *imxmd,