]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/commitdiff
media: tegra: camera: support both UYVY and NV16
authorKen Chang <kenc@nvidia.com>
Mon, 17 Oct 2016 05:54:49 +0000 (13:54 +0800)
committermobile promotions <svcmobile_promotions@nvidia.com>
Mon, 14 Nov 2016 16:50:58 +0000 (08:50 -0800)
VI can output different pixel formats for the same
CSI input format. This change enables both UYVY and
NV16 formats for YUV422 input.
Thus user-space applications can see both the supported
formats and select the prefer one.

ioctl: VIDIOC_ENUM_FMT
        Index       : 0
        Type        : Video Capture
        Pixel Format: 'AR24'
        Name        : BGRA-8-8-8-8

        Index       : 1
        Type        : Video Capture
        Pixel Format: 'NV16'
        Name        : NV16

        Index       : 2
        Type        : Video Capture
        Pixel Format: 'UYVY'
        Name        : YUV 4:2:2

Bug 1779149

Change-Id: I92c190e0dbf19be770503c7e3dfa5223b9ac1dcf
Signed-off-by: Ken Chang <kenc@nvidia.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Reviewed-on: http://git-master/r/1215349
(cherry picked from commit 08e5a55057ece99b8d0c25e5a684802ec769c8ab)
Reviewed-on: http://git-master/r/1237409
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
drivers/media/platform/tegra/camera/csi/csi.c
drivers/media/platform/tegra/camera/vi/channel.c
drivers/media/platform/tegra/camera/vi/core.c
drivers/media/platform/tegra/camera/vi/core.h
drivers/media/platform/tegra/camera/vi/mc_common.c

index f855bac472c94073bc140a7b3b8991deeb54284e..78a4691a3c2ef5a278789e9e0f07a2becb2e37da 100644 (file)
@@ -427,7 +427,8 @@ static int tegra_csi_enum_framesizes(struct v4l2_subdev *sd,
 
        for (i = 0; i < ARRAY_SIZE(tegra_csi_tpg_fmts); i++) {
                const struct tegra_video_format *format =
-                     tegra_core_get_format_by_code(tegra_csi_tpg_fmts[i].code);
+                     tegra_core_get_format_by_code(
+                               tegra_csi_tpg_fmts[i].code, 0);
                if (format && format->fourcc == fse->code)
                        break;
        }
@@ -596,7 +597,7 @@ static int tegra_csi_set_format(struct v4l2_subdev *subdev,
        if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
                return 0;
 
-       vf = tegra_core_get_format_by_code(format->code);
+       vf = tegra_core_get_format_by_code(format->code, 0);
        if (!vf) {
                dev_err(chan->csi->dev, "Fail to find tegra video fmt");
                mutex_unlock(&chan->format_lock);
index 21a97e4f5adc1b691b1e1af489741e618d6a0601..511ab04e55a99e13597c81dbc9c24fe8f11d6b3d 100644 (file)
@@ -202,18 +202,22 @@ static void tegra_channel_fmts_bitmap_init(struct tegra_channel *chan)
                        /* no more formats */
                        break;
 
-               pixel_format_index = tegra_core_get_idx_by_code(code.code);
-               if (pixel_format_index >= 0) {
+               pixel_format_index = tegra_core_get_idx_by_code(code.code, 0);
+               while (pixel_format_index >= 0) {
                        bitmap_set(chan->fmts_bitmap, pixel_format_index, 1);
+                       /* Set init_code to the first matched format */
                        if (!init_code)
                                init_code = code.code;
+                       /* Look for other formats with the same mbus code */
+                       pixel_format_index = tegra_core_get_idx_by_code(code.code,
+                               pixel_format_index + 1);
                }
 
                code.index++;
        }
 
        if (!init_code) {
-               pixel_format_index = tegra_core_get_idx_by_code(TEGRA_VF_DEF);
+               pixel_format_index = tegra_core_get_idx_by_code(TEGRA_VF_DEF, 0);
                if (pixel_format_index >= 0) {
                        bitmap_set(chan->fmts_bitmap, pixel_format_index, 1);
                        init_code = TEGRA_VF_DEF;
@@ -224,7 +228,8 @@ static void tegra_channel_fmts_bitmap_init(struct tegra_channel *chan)
        if (ret)
                return;
 
-       chan->fmtinfo = tegra_core_get_format_by_code(fmt.format.code);
+       /* Initiate the channel format to the first matched format */
+       chan->fmtinfo = tegra_core_get_format_by_code(fmt.format.code, 0);
        v4l2_fill_pix_format(&chan->format, &fmt.format);
        chan->format.pixelformat = chan->fmtinfo->fourcc;
        chan->format.bytesperline = chan->format.width *
@@ -977,7 +982,7 @@ __tegra_channel_get_format(struct tegra_channel *chan,
                return -ENOTTY;
 
        v4l2_fill_pix_format(pix, &fmt.format);
-       vfmt = tegra_core_get_format_by_code(fmt.format.code);
+       vfmt = tegra_core_get_format_by_code(fmt.format.code, 0);
        if (vfmt != NULL) {
                pix->pixelformat = vfmt->fourcc;
                tegra_channel_fmt_align(chan,
@@ -1393,7 +1398,7 @@ int tegra_channel_init(struct tegra_channel *chan)
        spin_lock_init(&chan->capture_state_lock);
 
        /* Init video format */
-       chan->fmtinfo = tegra_core_get_format_by_code(TEGRA_VF_DEF);
+       chan->fmtinfo = tegra_core_get_format_by_code(TEGRA_VF_DEF, 0);
        chan->format.pixelformat = chan->fmtinfo->fourcc;
        chan->format.colorspace = V4L2_COLORSPACE_SRGB;
        chan->format.field = V4L2_FIELD_NONE;
index 9c081de6a337fd70bf3d479eae3a639561d01cf9..12a2d443b0d25005ada6cc69f6960edfea4f6355 100644 (file)
@@ -287,11 +287,11 @@ u32 tegra_core_get_word_count(unsigned int frame_width,
  * given V4L2 media bus format @code, or -1 if no corresponding format can
  * be found.
  */
-int tegra_core_get_idx_by_code(unsigned int code)
+int tegra_core_get_idx_by_code(unsigned int code, unsigned offset)
 {
        unsigned int i;
 
-       for (i = 0; i < ARRAY_SIZE(tegra_video_formats); ++i) {
+       for (i = offset; i < ARRAY_SIZE(tegra_video_formats); ++i) {
                if (tegra_video_formats[i].code == code)
                        return i;
        }
@@ -309,11 +309,11 @@ int tegra_core_get_idx_by_code(unsigned int code)
  * be found.
  */
 const struct tegra_video_format *
-tegra_core_get_format_by_code(unsigned int code)
+tegra_core_get_format_by_code(unsigned int code, unsigned offset)
 {
        unsigned int i;
 
-       for (i = 0; i < ARRAY_SIZE(tegra_video_formats); ++i) {
+       for (i = offset; i < ARRAY_SIZE(tegra_video_formats); ++i) {
                if (tegra_video_formats[i].code == code)
                        return &tegra_video_formats[i];
        }
index f5517f979a921b47f64ac355a49d6ea129529472..9ab21029a1d491acd9de9cf07c838096eacefe48 100644 (file)
@@ -220,9 +220,9 @@ struct tegra_video_format {
 u32 tegra_core_get_fourcc_by_idx(unsigned int index);
 u32 tegra_core_get_word_count(unsigned int frame_width,
                              const struct tegra_video_format *fmt);
-int tegra_core_get_idx_by_code(unsigned int code);
+int tegra_core_get_idx_by_code(unsigned int code, unsigned offset);
 const struct tegra_video_format *tegra_core_get_format_by_code(unsigned int
-                                                              code);
+                                       code, unsigned offset);
 const struct tegra_video_format *tegra_core_get_format_by_fourcc(u32 fourcc);
 u32 tegra_core_bytes_per_line(unsigned int width, unsigned int align,
                              const struct tegra_video_format *fmt);
index 5a4970e645aa7ebd5fb0edfcfb9eee4edef439dd..4dc716c6c0a984250292639ffa24c3dce0bc19d7 100644 (file)
@@ -36,10 +36,10 @@ static void vi_tpg_fmts_bitmap_init(struct tegra_mc_vi *vi)
 
        bitmap_zero(vi->tpg_fmts_bitmap, MAX_FORMAT_NUM);
 
-       index = tegra_core_get_idx_by_code(MEDIA_BUS_FMT_SRGGB10_1X10);
+       index = tegra_core_get_idx_by_code(MEDIA_BUS_FMT_SRGGB10_1X10, 0);
        bitmap_set(vi->tpg_fmts_bitmap, index, 1);
 
-       index = tegra_core_get_idx_by_code(MEDIA_BUS_FMT_RGB888_1X32_PADHI);
+       index = tegra_core_get_idx_by_code(MEDIA_BUS_FMT_RGB888_1X32_PADHI, 0);
        bitmap_set(vi->tpg_fmts_bitmap, index, 1);
 }