From e31a0ba7df6ce21ac4ed58c4182ec12ca8fd78fb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 2 Jan 2015 12:18:23 -0300 Subject: [media] media: Fix DVB devnode representation at media controller The previous provision for DVB media controller support were to define an ID (likely meaning the adapter number) for the DVB devnodes. This is just plain wrong. Just like V4L, DVB devices (and any other device node)) are uniquely identified via a (major, minor) tuple. This is enough to uniquely identify a devnode, no matter what API it implements. So, before we go too far, let's mark the old v4l, fb, dvb and alsa "devnode" info as deprecated, and just call it as "dev". We can latter add fields specific to each API if needed. As we don't want to break compilation on already existing apps, let's just keep the old definitions as-is, adding a note that those are deprecated at media-entity.h. Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/media.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include/uapi') diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index d847c760e8f0..418f4fec391a 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -75,6 +75,20 @@ struct media_entity_desc { union { /* Node specifications */ + struct { + __u32 major; + __u32 minor; + } dev; + +#if 1 + /* + * DEPRECATED: previous node specifications. Kept just to + * avoid breaking compilation, but media_entity_desc.dev + * should be used instead. In particular, alsa and dvb + * fields below are wrong: for all devnodes, there should + * be just major/minor inside the struct, as this is enough + * to represent any devnode, no matter what type. + */ struct { __u32 major; __u32 minor; @@ -89,6 +103,7 @@ struct media_entity_desc { __u32 subdevice; } alsa; int dvb; +#endif /* Sub-device specifications */ /* Nothing needed yet */ -- cgit v1.2.3 From 1d20f9f6330c988505e51f5010656978fd70cd0c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 3 Jan 2015 11:09:39 -0300 Subject: [media] media: add new types for DVB devnodes Most of the DVB subdevs have already their own devnode. Add support for them at the media controller API. Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/media.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'include/uapi') diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 418f4fec391a..4c8f26243252 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -50,7 +50,14 @@ struct media_device_info { #define MEDIA_ENT_T_DEVNODE_V4L (MEDIA_ENT_T_DEVNODE + 1) #define MEDIA_ENT_T_DEVNODE_FB (MEDIA_ENT_T_DEVNODE + 2) #define MEDIA_ENT_T_DEVNODE_ALSA (MEDIA_ENT_T_DEVNODE + 3) -#define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4) +#define MEDIA_ENT_T_DEVNODE_DVB_FE (MEDIA_ENT_T_DEVNODE + 4) +#define MEDIA_ENT_T_DEVNODE_DVB_DEMUX (MEDIA_ENT_T_DEVNODE + 5) +#define MEDIA_ENT_T_DEVNODE_DVB_DVR (MEDIA_ENT_T_DEVNODE + 6) +#define MEDIA_ENT_T_DEVNODE_DVB_CA (MEDIA_ENT_T_DEVNODE + 7) +#define MEDIA_ENT_T_DEVNODE_DVB_NET (MEDIA_ENT_T_DEVNODE + 8) + +/* Legacy symbol. Use it to avoid userspace compilation breakages */ +#define MEDIA_ENT_T_DEVNODE_DVB MEDIA_ENT_T_DEVNODE_DVB_FE #define MEDIA_ENT_T_V4L2_SUBDEV (2 << MEDIA_ENT_TYPE_SHIFT) #define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV + 1) -- cgit v1.2.3 From 91b0f3a06e432d01c66cd05973628a2ec3bde9ed Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 26 Jan 2015 08:53:18 -0300 Subject: [media] media: add a subdev type for tuner Add MEDIA_ENT_T_V4L2_SUBDEV_TUNER to represent the V4L2 (and dvb) tuner subdevices. Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/media.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/uapi') diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 4c8f26243252..52cc2a6b19b7 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -66,6 +66,8 @@ struct media_device_info { /* A converter of analogue video to its digital representation. */ #define MEDIA_ENT_T_V4L2_SUBDEV_DECODER (MEDIA_ENT_T_V4L2_SUBDEV + 4) +#define MEDIA_ENT_T_V4L2_SUBDEV_TUNER (MEDIA_ENT_T_V4L2_SUBDEV + 5) + #define MEDIA_ENT_FL_DEFAULT (1 << 0) struct media_entity_desc { -- cgit v1.2.3 From 7e182f78988404717e27aed5a9d4150631b323f4 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 25 Feb 2015 12:05:13 -0300 Subject: [media] media.h: mark alsa struct in media_entity_desc as TODO The alsa struct in struct media_entity_desc is now marked as deprecated. However, the alsa struct should remain as it is since it cannot be replaced by a simple major/minor device node description. The alsa struct was designed to be used as an alsa card description so V4L2 drivers could use this to expose the alsa card that they create to carry the captured audio. Such a card is not just a PCM device, but also needs to contain the alsa subdevice information, and it may map to multiple devices, e.g. a PCM and a mixer device, such as the au0828 usb stick creates. This is exactly as intended and this cannot and should not be replaced by a simple major/minor. However, whether this information is in the right form for an ALSA device such that it can handle udev renaming rules as well is another matter. So mark this alsa struct as TODO and document the problems involved. Updated the documentation as well to reflect this and to add the 'major' and 'minor' field documentation. Updated the documentation to clearly state that struct dev is to be used for (sub-)devices that create a single device node. Other devices need their own structure here. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../DocBook/media/v4l/media-ioc-enum-entities.xml | 16 ++++++++++++- include/uapi/linux/media.h | 26 +++++++++++++++++----- 2 files changed, 36 insertions(+), 6 deletions(-) (limited to 'include/uapi') diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml index cbf307f21a63..5872f8bbf774 100644 --- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml @@ -145,7 +145,21 @@ struct dev - Valid for (sub-)devices that create devnodes. + Valid for (sub-)devices that create a single device node. + + + + + __u32 + major + Device node major number. + + + + + __u32 + minor + Device node minor number. diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 52cc2a6b19b7..4e816be3de39 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -89,6 +89,27 @@ struct media_entity_desc { __u32 minor; } dev; +#if 1 + /* + * TODO: this shouldn't have been added without + * actual drivers that use this. When the first real driver + * appears that sets this information, special attention + * should be given whether this information is 1) enough, and + * 2) can deal with udev rules that rename devices. The struct + * dev would not be sufficient for this since that does not + * contain the subdevice information. In addition, struct dev + * can only refer to a single device, and not to multiple (e.g. + * pcm and mixer devices). + * + * So for now mark this as a to do. + */ + struct { + __u32 card; + __u32 device; + __u32 subdevice; + } alsa; +#endif + #if 1 /* * DEPRECATED: previous node specifications. Kept just to @@ -106,11 +127,6 @@ struct media_entity_desc { __u32 major; __u32 minor; } fb; - struct { - __u32 card; - __u32 device; - __u32 subdevice; - } alsa; int dvb; #endif -- cgit v1.2.3 From e1c47e732cbb4211d15ae0c4465dc4ceefcaa398 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 4 Mar 2015 01:47:55 -0800 Subject: [media] v4l2-subdev.h: add 'which' field for the enum structs While all other pad ops allow you to select whether to use the 'try' or the 'active' formats, the enum ops didn't have that option and always used 'try'. However, this will fail if a simple (e.g. PCI) bridge driver wants to use the enum pad op of a subdev that's also used in a complex platform driver like the omap3. Such a bridge driver generally wants to enum formats based on the active format. So add a new 'which' field to these structs. Note that V4L2_SUBDEV_FORMAT_TRY is 0, so the default remains TRY (applications need to set reserved to 0). Signed-off-by: Hans Verkuil Acked-by: Lad, Prabhakar Tested-by: Lad, Prabhakar Acked-by: Laurent Pinchart Acked-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/v4l2-subdev.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'include/uapi') diff --git a/include/uapi/linux/v4l2-subdev.h b/include/uapi/linux/v4l2-subdev.h index e0a7e3da498a..dbce2b554e02 100644 --- a/include/uapi/linux/v4l2-subdev.h +++ b/include/uapi/linux/v4l2-subdev.h @@ -69,12 +69,14 @@ struct v4l2_subdev_crop { * @pad: pad number, as reported by the media API * @index: format index during enumeration * @code: format code (MEDIA_BUS_FMT_ definitions) + * @which: format type (from enum v4l2_subdev_format_whence) */ struct v4l2_subdev_mbus_code_enum { __u32 pad; __u32 index; __u32 code; - __u32 reserved[9]; + __u32 which; + __u32 reserved[8]; }; /** @@ -82,6 +84,7 @@ struct v4l2_subdev_mbus_code_enum { * @pad: pad number, as reported by the media API * @index: format index during enumeration * @code: format code (MEDIA_BUS_FMT_ definitions) + * @which: format type (from enum v4l2_subdev_format_whence) */ struct v4l2_subdev_frame_size_enum { __u32 index; @@ -91,7 +94,8 @@ struct v4l2_subdev_frame_size_enum { __u32 max_width; __u32 min_height; __u32 max_height; - __u32 reserved[9]; + __u32 which; + __u32 reserved[8]; }; /** @@ -113,6 +117,7 @@ struct v4l2_subdev_frame_interval { * @width: frame width in pixels * @height: frame height in pixels * @interval: frame interval in seconds + * @which: format type (from enum v4l2_subdev_format_whence) */ struct v4l2_subdev_frame_interval_enum { __u32 index; @@ -121,7 +126,8 @@ struct v4l2_subdev_frame_interval_enum { __u32 width; __u32 height; struct v4l2_fract interval; - __u32 reserved[9]; + __u32 which; + __u32 reserved[8]; }; /** -- cgit v1.2.3 From 64bf8049a2ec1e61e1475eb02b5514d7061d443e Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Wed, 4 Mar 2015 17:13:24 -0300 Subject: [media] am437x: include linux/videodev2.h for expanding BASE_VIDIOC_PRIVATE In am437x-vpfe.h BASE_VIDIOC_PRIVATE is used for making the name of ioctl command(VIDIOC_AM437X_CCDC_CFG). The definition of BASE_VIDIOC_PRIVATE is in linux/videodev2.h. However, linux/videodev2.h is not included in am437x-vpfe.h. As the result an application using has to include both am437x-vpfe.h and linux/videodev2.h. With this patch, the application can include just am437x-vpfe.h. Signed-off-by: Masatake YAMATO Acked-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/am437x-vpfe.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/uapi') diff --git a/include/uapi/linux/am437x-vpfe.h b/include/uapi/linux/am437x-vpfe.h index 9b03033f9cd6..d75774317b9b 100644 --- a/include/uapi/linux/am437x-vpfe.h +++ b/include/uapi/linux/am437x-vpfe.h @@ -21,6 +21,8 @@ #ifndef AM437X_VPFE_USER_H #define AM437X_VPFE_USER_H +#include + enum vpfe_ccdc_data_size { VPFE_CCDC_DATA_16BITS = 0, VPFE_CCDC_DATA_15BITS, -- cgit v1.2.3 From aa05b979f14998fec16fa38f1c91eaa197e73148 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 8 Mar 2015 04:53:32 -0300 Subject: [media] videodev2.h: fix comment The quantization comment in the header was incorrect w.r.t. BT.2020. Fix this. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/videodev2.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'include/uapi') diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index fbdc3602ee27..15b21e481246 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -268,9 +268,10 @@ enum v4l2_ycbcr_encoding { enum v4l2_quantization { /* - * The default for R'G'B' quantization is always full range. For - * Y'CbCr the quantization is always limited range, except for - * SYCC, XV601, XV709 or JPEG: those are full range. + * The default for R'G'B' quantization is always full range, except + * for the BT2020 colorspace. For Y'CbCr the quantization is always + * limited range, except for COLORSPACE_JPEG, SYCC, XV601 or XV709: + * those are full range. */ V4L2_QUANTIZATION_DEFAULT = 0, V4L2_QUANTIZATION_FULL_RANGE = 1, -- cgit v1.2.3 From cc7d2dfb75b3ac0f248801ceed65f69465eb0389 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 15 Mar 2015 14:30:25 -0300 Subject: [media] v4l2_plane_pix_format: use __u32 bytesperline instead of __u16 While running v4l2-compliance tests on vivid I suddenly got errors due to a call to vmalloc_user with size 0 from vb2. Digging deeper into the cause I discovered that this was due to the fact that struct v4l2_plane_pix_format defines bytesperline as a __u16 instead of a __u32. The test I was running selected a format of 4 * 4096 by 4 * 2048 with a 32 bit pixelformat. So bytesperline was 4 * 4 * 4096 = 65536, which becomes 0 in a __u16. And bytesperline * height is suddenly 0 as well. While the vivid driver may be a virtual driver, it is to be expected that this limit will be hit for real hardware as well in the near future: 8k deep-color video will already reach it. The solution is to change the type to __u32. The only drivers besides vivid that use the multiplanar API are little-endian ARM and SH platforms (exynos, ti-vpe, vsp1), so this is safe. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media/v4l/pixfmt.xml | 4 ++-- drivers/media/platform/s5p-tv/mixer_video.c | 2 +- include/uapi/linux/videodev2.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'include/uapi') diff --git a/Documentation/DocBook/media/v4l/pixfmt.xml b/Documentation/DocBook/media/v4l/pixfmt.xml index 0a1528f3e891..fcde4e20205e 100644 --- a/Documentation/DocBook/media/v4l/pixfmt.xml +++ b/Documentation/DocBook/media/v4l/pixfmt.xml @@ -182,14 +182,14 @@ see . - __u16 + __u32 bytesperline Distance in bytes between the leftmost pixels in two adjacent lines. See &v4l2-pix-format;. __u16 - reserved[7] + reserved[6] Reserved for future extensions. Should be zeroed by the application. diff --git a/drivers/media/platform/s5p-tv/mixer_video.c b/drivers/media/platform/s5p-tv/mixer_video.c index 72d4f2e1efc0..751f3b618337 100644 --- a/drivers/media/platform/s5p-tv/mixer_video.c +++ b/drivers/media/platform/s5p-tv/mixer_video.c @@ -287,7 +287,7 @@ static void mxr_mplane_fill(struct v4l2_plane_pix_format *planes, u32 bl_width = divup(width, blk->width); u32 bl_height = divup(height, blk->height); u32 sizeimage = bl_width * bl_height * blk->size; - u16 bytesperline = bl_width * blk->size / blk->height; + u32 bytesperline = bl_width * blk->size / blk->height; plane->sizeimage += sizeimage; plane->bytesperline = max(plane->bytesperline, bytesperline); diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 15b21e481246..47df18f36c4b 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -1842,8 +1842,8 @@ struct v4l2_mpeg_vbi_fmt_ivtv { */ struct v4l2_plane_pix_format { __u32 sizeimage; - __u16 bytesperline; - __u16 reserved[7]; + __u32 bytesperline; + __u16 reserved[6]; } __attribute__ ((packed)); /** -- cgit v1.2.3 From 7b0fd4568bee379474eb0d989ef1125064f19fa7 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 15 May 2013 11:34:26 -0300 Subject: [media] v4l: Add RBG and RGB 8:8:8 media bus formats on 24 and 32 bit busses Add support and documentation for two media bus formats: MEDIA_BUS_FMT_RBG888_1X24 and MEDIA_BUS_FMT_RGB888_1X32_PADHI Signed-off-by: Laurent Pinchart Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media/v4l/subdev-formats.xml | 67 ++++++++++++++++++++++ include/uapi/linux/media-bus-format.h | 4 +- 2 files changed, 70 insertions(+), 1 deletion(-) (limited to 'include/uapi') diff --git a/Documentation/DocBook/media/v4l/subdev-formats.xml b/Documentation/DocBook/media/v4l/subdev-formats.xml index c5ea868e3909..d253e8f85f4d 100644 --- a/Documentation/DocBook/media/v4l/subdev-formats.xml +++ b/Documentation/DocBook/media/v4l/subdev-formats.xml @@ -440,6 +440,36 @@ see . b1 b0 + + MEDIA_BUS_FMT_RBG888_1X24 + 0x100e + + &dash-ent-8; + r7 + r6 + r5 + r4 + r3 + r2 + r1 + r0 + b7 + b6 + b5 + b4 + b3 + b2 + b1 + b0 + g7 + g6 + g5 + g4 + g3 + g2 + g1 + g0 + MEDIA_BUS_FMT_RGB888_1X24 0x100a @@ -579,6 +609,43 @@ see . b1 b0 + + MEDIA_BUS_FMT_RGB888_1X32_PADHI + 0x100f + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + r7 + r6 + r5 + r4 + r3 + r2 + r1 + r0 + g7 + g6 + g5 + g4 + g3 + g2 + g1 + g0 + b7 + b6 + b5 + b4 + b3 + b2 + b1 + b0 + diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h index 23b40908be30..b585bb32d25e 100644 --- a/include/uapi/linux/media-bus-format.h +++ b/include/uapi/linux/media-bus-format.h @@ -33,7 +33,7 @@ #define MEDIA_BUS_FMT_FIXED 0x0001 -/* RGB - next is 0x100e */ +/* RGB - next is 0x1010 */ #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE 0x1001 #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE 0x1002 #define MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE 0x1003 @@ -43,10 +43,12 @@ #define MEDIA_BUS_FMT_RGB565_2X8_BE 0x1007 #define MEDIA_BUS_FMT_RGB565_2X8_LE 0x1008 #define MEDIA_BUS_FMT_RGB666_1X18 0x1009 +#define MEDIA_BUS_FMT_RBG888_1X24 0x100e #define MEDIA_BUS_FMT_RGB888_1X24 0x100a #define MEDIA_BUS_FMT_RGB888_2X12_BE 0x100b #define MEDIA_BUS_FMT_RGB888_2X12_LE 0x100c #define MEDIA_BUS_FMT_ARGB8888_1X32 0x100d +#define MEDIA_BUS_FMT_RGB888_1X32_PADHI 0x100f /* YUV (including grey) - next is 0x2024 */ #define MEDIA_BUS_FMT_Y8_1X8 0x2001 -- cgit v1.2.3 From e8b2d7a565ae4fc8627ffe35b953062ff6119533 Mon Sep 17 00:00:00 2001 From: Hyun Kwon Date: Tue, 18 Mar 2014 13:18:14 -0300 Subject: [media] v4l: Sort YUV formats of v4l2_mbus_pixelcode Keep the formats sorted by type, bus_width, bits per component, samples per pixel and order of subsamples, in that order. Signed-off-by: Hyun Kwon Signed-off-by: Laurent Pinchart Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media/v4l/subdev-formats.xml | 600 ++++++++++----------- include/uapi/linux/media-bus-format.h | 12 +- 2 files changed, 306 insertions(+), 306 deletions(-) (limited to 'include/uapi') diff --git a/Documentation/DocBook/media/v4l/subdev-formats.xml b/Documentation/DocBook/media/v4l/subdev-formats.xml index d253e8f85f4d..9bfd468cd524 100644 --- a/Documentation/DocBook/media/v4l/subdev-formats.xml +++ b/Documentation/DocBook/media/v4l/subdev-formats.xml @@ -2255,11 +2255,15 @@ see . y1 y0 - - MEDIA_BUS_FMT_UYVY8_1X16 - 0x200f + + MEDIA_BUS_FMT_UYVY12_2X12 + 0x201c - &dash-ent-16; + &dash-ent-20; + u11 + u10 + u9 + u8 u7 u6 u5 @@ -2268,6 +2272,16 @@ see . u2 u1 u0 + + + + + + &dash-ent-20; + y11 + y10 + y9 + y8 y7 y6 y5 @@ -2281,7 +2295,11 @@ see . - &dash-ent-16; + &dash-ent-20; + v11 + v10 + v9 + v8 v7 v6 v5 @@ -2290,6 +2308,16 @@ see . v2 v1 v0 + + + + + + &dash-ent-20; + y11 + y10 + y9 + y8 y7 y6 y5 @@ -2299,11 +2327,15 @@ see . y1 y0 - - MEDIA_BUS_FMT_VYUY8_1X16 - 0x2010 + + MEDIA_BUS_FMT_VYUY12_2X12 + 0x201d - &dash-ent-16; + &dash-ent-20; + v11 + v10 + v9 + v8 v7 v6 v5 @@ -2312,6 +2344,16 @@ see . v2 v1 v0 + + + + + + &dash-ent-20; + y11 + y10 + y9 + y8 y7 y6 y5 @@ -2325,7 +2367,11 @@ see . - &dash-ent-16; + &dash-ent-20; + u11 + u10 + u9 + u8 u7 u6 u5 @@ -2334,6 +2380,16 @@ see . u2 u1 u0 + + + + + + &dash-ent-20; + y11 + y10 + y9 + y8 y7 y6 y5 @@ -2343,11 +2399,15 @@ see . y1 y0 - - MEDIA_BUS_FMT_YUYV8_1X16 - 0x2011 + + MEDIA_BUS_FMT_YUYV12_2X12 + 0x201e - &dash-ent-16; + &dash-ent-20; + y11 + y10 + y9 + y8 y7 y6 y5 @@ -2356,6 +2416,16 @@ see . y2 y1 y0 + + + + + + &dash-ent-20; + u11 + u10 + u9 + u8 u7 u6 u5 @@ -2369,7 +2439,11 @@ see . - &dash-ent-16; + &dash-ent-20; + y11 + y10 + y9 + y8 y7 y6 y5 @@ -2378,6 +2452,16 @@ see . y2 y1 y0 + + + + + + &dash-ent-20; + v11 + v10 + v9 + v8 v7 v6 v5 @@ -2387,11 +2471,15 @@ see . v1 v0 - - MEDIA_BUS_FMT_YVYU8_1X16 - 0x2012 + + MEDIA_BUS_FMT_YVYU12_2X12 + 0x201f - &dash-ent-16; + &dash-ent-20; + y11 + y10 + y9 + y8 y7 y6 y5 @@ -2400,6 +2488,16 @@ see . y2 y1 y0 + + + + + + &dash-ent-20; + v11 + v10 + v9 + v8 v7 v6 v5 @@ -2413,29 +2511,11 @@ see . - &dash-ent-16; - y7 - y6 - y5 - y4 - y3 - y2 - y1 - y0 - u7 - u6 - u5 - u4 - u3 - u2 - u1 - u0 - - - MEDIA_BUS_FMT_YDYUYDYV8_1X16 - 0x2014 - - &dash-ent-16; + &dash-ent-20; + y11 + y10 + y9 + y8 y7 y6 y5 @@ -2444,28 +2524,16 @@ see . y2 y1 y0 - d - d - d - d - d - d - d - d - &dash-ent-16; - y7 - y6 - y5 - y4 - y3 - y2 - y1 - y0 + &dash-ent-20; + u11 + u10 + u9 + u8 u7 u6 u5 @@ -2475,57 +2543,11 @@ see . u1 u0 - - - - - &dash-ent-16; - y7 - y6 - y5 - y4 - y3 - y2 - y1 - y0 - d - d - d - d - d - d - d - d - - - - + + MEDIA_BUS_FMT_UYVY8_1X16 + 0x200f &dash-ent-16; - y7 - y6 - y5 - y4 - y3 - y2 - y1 - y0 - v7 - v6 - v5 - v4 - v3 - v2 - v1 - v0 - - - MEDIA_BUS_FMT_UYVY10_1X20 - 0x201a - - &dash-ent-12; - u9 - u8 u7 u6 u5 @@ -2534,8 +2556,6 @@ see . u2 u1 u0 - y9 - y8 y7 y6 y5 @@ -2549,9 +2569,7 @@ see . - &dash-ent-12; - v9 - v8 + &dash-ent-16; v7 v6 v5 @@ -2560,8 +2578,6 @@ see . v2 v1 v0 - y9 - y8 y7 y6 y5 @@ -2571,13 +2587,11 @@ see . y1 y0 - - MEDIA_BUS_FMT_VYUY10_1X20 - 0x201b + + MEDIA_BUS_FMT_VYUY8_1X16 + 0x2010 - &dash-ent-12; - v9 - v8 + &dash-ent-16; v7 v6 v5 @@ -2586,8 +2600,6 @@ see . v2 v1 v0 - y9 - y8 y7 y6 y5 @@ -2601,9 +2613,7 @@ see . - &dash-ent-12; - u9 - u8 + &dash-ent-16; u7 u6 u5 @@ -2612,8 +2622,6 @@ see . u2 u1 u0 - y9 - y8 y7 y6 y5 @@ -2623,13 +2631,11 @@ see . y1 y0 - - MEDIA_BUS_FMT_YUYV10_1X20 - 0x200d + + MEDIA_BUS_FMT_YUYV8_1X16 + 0x2011 - &dash-ent-12; - y9 - y8 + &dash-ent-16; y7 y6 y5 @@ -2638,8 +2644,6 @@ see . y2 y1 y0 - u9 - u8 u7 u6 u5 @@ -2653,9 +2657,7 @@ see . - &dash-ent-12; - y9 - y8 + &dash-ent-16; y7 y6 y5 @@ -2664,8 +2666,6 @@ see . y2 y1 y0 - v9 - v8 v7 v6 v5 @@ -2675,13 +2675,11 @@ see . v1 v0 - - MEDIA_BUS_FMT_YVYU10_1X20 - 0x200e + + MEDIA_BUS_FMT_YVYU8_1X16 + 0x2012 - &dash-ent-12; - y9 - y8 + &dash-ent-16; y7 y6 y5 @@ -2690,8 +2688,6 @@ see . y2 y1 y0 - v9 - v8 v7 v6 v5 @@ -2705,9 +2701,51 @@ see . - &dash-ent-12; - y9 - y8 + &dash-ent-16; + y7 + y6 + y5 + y4 + y3 + y2 + y1 + y0 + u7 + u6 + u5 + u4 + u3 + u2 + u1 + u0 + + + MEDIA_BUS_FMT_YDYUYDYV8_1X16 + 0x2014 + + &dash-ent-16; + y7 + y6 + y5 + y4 + y3 + y2 + y1 + y0 + d + d + d + d + d + d + d + d + + + + + + &dash-ent-16; y7 y6 y5 @@ -2716,8 +2754,6 @@ see . y2 y1 y0 - u9 - u8 u7 u6 u5 @@ -2727,14 +2763,11 @@ see . u1 u0 - - MEDIA_BUS_FMT_YUV10_1X30 - 0x2016 + - - - - - y9 - y8 + + + &dash-ent-16; y7 y6 y5 @@ -2743,39 +2776,20 @@ see . y2 y1 y0 - u9 - u8 - u7 - u6 - u5 - u4 - u3 - u2 - u1 - u0 - v9 - v8 - v7 - v6 - v5 - v4 - v3 - v2 - v1 - v0 + d + d + d + d + d + d + d + d - - MEDIA_BUS_FMT_AYUV8_1X32 - 0x2017 + - a7 - a6 - a5 - a4 - a3 - a2 - a1 - a0 + + + &dash-ent-16; y7 y6 y5 @@ -2784,14 +2798,6 @@ see . y2 y1 y0 - u7 - u6 - u5 - u4 - u3 - u2 - u1 - u0 v7 v6 v5 @@ -2801,13 +2807,11 @@ see . v1 v0 - - MEDIA_BUS_FMT_UYVY12_2X12 - 0x201c + + MEDIA_BUS_FMT_UYVY10_1X20 + 0x201a - &dash-ent-20; - u11 - u10 + &dash-ent-12; u9 u8 u7 @@ -2818,14 +2822,6 @@ see . u2 u1 u0 - - - - - - &dash-ent-20; - y11 - y10 y9 y8 y7 @@ -2841,9 +2837,7 @@ see . - &dash-ent-20; - v11 - v10 + &dash-ent-12; v9 v8 v7 @@ -2854,14 +2848,6 @@ see . v2 v1 v0 - - - - - - &dash-ent-20; - y11 - y10 y9 y8 y7 @@ -2873,13 +2859,11 @@ see . y1 y0 - - MEDIA_BUS_FMT_VYUY12_2X12 - 0x201d + + MEDIA_BUS_FMT_VYUY10_1X20 + 0x201b - &dash-ent-20; - v11 - v10 + &dash-ent-12; v9 v8 v7 @@ -2890,14 +2874,6 @@ see . v2 v1 v0 - - - - - - &dash-ent-20; - y11 - y10 y9 y8 y7 @@ -2913,9 +2889,7 @@ see . - &dash-ent-20; - u11 - u10 + &dash-ent-12; u9 u8 u7 @@ -2926,14 +2900,6 @@ see . u2 u1 u0 - - - - - - &dash-ent-20; - y11 - y10 y9 y8 y7 @@ -2945,13 +2911,11 @@ see . y1 y0 - - MEDIA_BUS_FMT_YUYV12_2X12 - 0x201e + + MEDIA_BUS_FMT_YUYV10_1X20 + 0x200d - &dash-ent-20; - y11 - y10 + &dash-ent-12; y9 y8 y7 @@ -2962,14 +2926,6 @@ see . y2 y1 y0 - - - - - - &dash-ent-20; - u11 - u10 u9 u8 u7 @@ -2985,9 +2941,7 @@ see . - &dash-ent-20; - y11 - y10 + &dash-ent-12; y9 y8 y7 @@ -2998,14 +2952,6 @@ see . y2 y1 y0 - - - - - - &dash-ent-20; - v11 - v10 v9 v8 v7 @@ -3017,13 +2963,11 @@ see . v1 v0 - - MEDIA_BUS_FMT_YVYU12_2X12 - 0x201f + + MEDIA_BUS_FMT_YVYU10_1X20 + 0x200e - &dash-ent-20; - y11 - y10 + &dash-ent-12; y9 y8 y7 @@ -3034,14 +2978,6 @@ see . y2 y1 y0 - - - - - - &dash-ent-20; - v11 - v10 v9 v8 v7 @@ -3057,9 +2993,7 @@ see . - &dash-ent-20; - y11 - y10 + &dash-ent-12; y9 y8 y7 @@ -3070,14 +3004,6 @@ see . y2 y1 y0 - - - - - - &dash-ent-20; - u11 - u10 u9 u8 u7 @@ -3329,6 +3255,80 @@ see . u1 u0 + + MEDIA_BUS_FMT_YUV10_1X30 + 0x2016 + + - + - + y9 + y8 + y7 + y6 + y5 + y4 + y3 + y2 + y1 + y0 + u9 + u8 + u7 + u6 + u5 + u4 + u3 + u2 + u1 + u0 + v9 + v8 + v7 + v6 + v5 + v4 + v3 + v2 + v1 + v0 + + + MEDIA_BUS_FMT_AYUV8_1X32 + 0x2017 + + a7 + a6 + a5 + a4 + a3 + a2 + a1 + a0 + y7 + y6 + y5 + y4 + y3 + y2 + y1 + y0 + u7 + u6 + u5 + u4 + u3 + u2 + u1 + u0 + v7 + v6 + v5 + v4 + v3 + v2 + v1 + v0 + diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h index b585bb32d25e..363a30fd8a21 100644 --- a/include/uapi/linux/media-bus-format.h +++ b/include/uapi/linux/media-bus-format.h @@ -67,6 +67,10 @@ #define MEDIA_BUS_FMT_YUYV10_2X10 0x200b #define MEDIA_BUS_FMT_YVYU10_2X10 0x200c #define MEDIA_BUS_FMT_Y12_1X12 0x2013 +#define MEDIA_BUS_FMT_UYVY12_2X12 0x201c +#define MEDIA_BUS_FMT_VYUY12_2X12 0x201d +#define MEDIA_BUS_FMT_YUYV12_2X12 0x201e +#define MEDIA_BUS_FMT_YVYU12_2X12 0x201f #define MEDIA_BUS_FMT_UYVY8_1X16 0x200f #define MEDIA_BUS_FMT_VYUY8_1X16 0x2010 #define MEDIA_BUS_FMT_YUYV8_1X16 0x2011 @@ -76,16 +80,12 @@ #define MEDIA_BUS_FMT_VYUY10_1X20 0x201b #define MEDIA_BUS_FMT_YUYV10_1X20 0x200d #define MEDIA_BUS_FMT_YVYU10_1X20 0x200e -#define MEDIA_BUS_FMT_YUV10_1X30 0x2016 -#define MEDIA_BUS_FMT_AYUV8_1X32 0x2017 -#define MEDIA_BUS_FMT_UYVY12_2X12 0x201c -#define MEDIA_BUS_FMT_VYUY12_2X12 0x201d -#define MEDIA_BUS_FMT_YUYV12_2X12 0x201e -#define MEDIA_BUS_FMT_YVYU12_2X12 0x201f #define MEDIA_BUS_FMT_UYVY12_1X24 0x2020 #define MEDIA_BUS_FMT_VYUY12_1X24 0x2021 #define MEDIA_BUS_FMT_YUYV12_1X24 0x2022 #define MEDIA_BUS_FMT_YVYU12_1X24 0x2023 +#define MEDIA_BUS_FMT_YUV10_1X30 0x2016 +#define MEDIA_BUS_FMT_AYUV8_1X32 0x2017 /* Bayer - next is 0x3019 */ #define MEDIA_BUS_FMT_SBGGR8_1X8 0x3001 -- cgit v1.2.3 From 2dca0551e4e2f3fc2b9beee784c7071e1e79c14b Mon Sep 17 00:00:00 2001 From: Hyun Kwon Date: Tue, 18 Mar 2014 13:18:15 -0300 Subject: [media] v4l: Add VUY8 24 bits bus format Add VUY8 24 bits bus format, V4L2_MBUS_FMT_VUY8_1X24. Signed-off-by: Hyun Kwon Signed-off-by: Laurent Pinchart Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media/v4l/subdev-formats.xml | 30 ++++++++++++++++++++++ include/uapi/linux/media-bus-format.h | 3 ++- 2 files changed, 32 insertions(+), 1 deletion(-) (limited to 'include/uapi') diff --git a/Documentation/DocBook/media/v4l/subdev-formats.xml b/Documentation/DocBook/media/v4l/subdev-formats.xml index 9bfd468cd524..bc8d3fb9e4a9 100644 --- a/Documentation/DocBook/media/v4l/subdev-formats.xml +++ b/Documentation/DocBook/media/v4l/subdev-formats.xml @@ -3015,6 +3015,36 @@ see . u1 u0 + + MEDIA_BUS_FMT_VUY8_1X24 + 0x201a + + &dash-ent-8; + v7 + v6 + v5 + v4 + v3 + v2 + v1 + v0 + u7 + u6 + u5 + u4 + u3 + u2 + u1 + u0 + y7 + y6 + y5 + y4 + y3 + y2 + y1 + y0 + MEDIA_BUS_FMT_UYVY12_1X24 0x2020 diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h index 363a30fd8a21..d391893064a0 100644 --- a/include/uapi/linux/media-bus-format.h +++ b/include/uapi/linux/media-bus-format.h @@ -50,7 +50,7 @@ #define MEDIA_BUS_FMT_ARGB8888_1X32 0x100d #define MEDIA_BUS_FMT_RGB888_1X32_PADHI 0x100f -/* YUV (including grey) - next is 0x2024 */ +/* YUV (including grey) - next is 0x2025 */ #define MEDIA_BUS_FMT_Y8_1X8 0x2001 #define MEDIA_BUS_FMT_UV8_1X8 0x2015 #define MEDIA_BUS_FMT_UYVY8_1_5X8 0x2002 @@ -80,6 +80,7 @@ #define MEDIA_BUS_FMT_VYUY10_1X20 0x201b #define MEDIA_BUS_FMT_YUYV10_1X20 0x200d #define MEDIA_BUS_FMT_YVYU10_1X20 0x200e +#define MEDIA_BUS_FMT_VUY8_1X24 0x2024 #define MEDIA_BUS_FMT_UYVY12_1X24 0x2020 #define MEDIA_BUS_FMT_VYUY12_1X24 0x2021 #define MEDIA_BUS_FMT_YUYV12_1X24 0x2022 -- cgit v1.2.3 From a5562f65b1371a0988b707c10c44fcc2bba56990 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 15 May 2013 11:36:56 -0300 Subject: [media] v4l: xilinx: Add Test Pattern Generator driver The TPG generates multiple static or dynamic test patterns. The driver currently hardcodes the pattern to the moving box pattern. Signed-off-by: Christian Kohn Signed-off-by: Hyun Kwon Signed-off-by: Laurent Pinchart Signed-off-by: Michal Simek Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../bindings/media/xilinx/xlnx,v-tpg.txt | 71 ++ MAINTAINERS | 1 + drivers/media/platform/xilinx/Kconfig | 7 + drivers/media/platform/xilinx/Makefile | 1 + drivers/media/platform/xilinx/xilinx-tpg.c | 931 +++++++++++++++++++++ include/uapi/linux/Kbuild | 1 + include/uapi/linux/xilinx-v4l2-controls.h | 73 ++ 7 files changed, 1085 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt create mode 100644 drivers/media/platform/xilinx/xilinx-tpg.c create mode 100644 include/uapi/linux/xilinx-v4l2-controls.h (limited to 'include/uapi') diff --git a/Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt b/Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt new file mode 100644 index 000000000000..9dd86b3db937 --- /dev/null +++ b/Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt @@ -0,0 +1,71 @@ +Xilinx Video Test Pattern Generator (TPG) +----------------------------------------- + +Required properties: + +- compatible: Must contain at least one of + + "xlnx,v-tpg-5.0" (TPG version 5.0) + "xlnx,v-tpg-6.0" (TPG version 6.0) + + TPG versions backward-compatible with previous versions should list all + compatible versions in the newer to older order. + +- reg: Physical base address and length of the registers set for the device. + +- clocks: Reference to the video core clock. + +- xlnx,video-format, xlnx,video-width: Video format and width, as defined in + video.txt. + +- port: Video port, using the DT bindings defined in ../video-interfaces.txt. + The TPG has a single output port numbered 0. + +Optional properties: + +- xlnx,vtc: A phandle referencing the Video Timing Controller that generates + video timings for the TPG test patterns. + +- timing-gpios: Specifier for a GPIO that controls the timing mux at the TPG + input. The GPIO active level corresponds to the selection of VTC-generated + video timings. + +The xlnx,vtc and timing-gpios properties are mandatory when the TPG is +synthesized with two ports and forbidden when synthesized with one port. + +Example: + + tpg_0: tpg@40050000 { + compatible = "xlnx,v-tpg-6.0", "xlnx,v-tpg-5.0"; + reg = <0x40050000 0x10000>; + clocks = <&clkc 15>; + + xlnx,vtc = <&vtc_3>; + timing-gpios = <&ps7_gpio_0 55 GPIO_ACTIVE_LOW>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + xlnx,video-format = ; + xlnx,video-width = <8>; + + tpg_in: endpoint { + remote-endpoint = <&adv7611_out>; + }; + }; + port@1 { + reg = <1>; + + xlnx,video-format = ; + xlnx,video-width = <8>; + + tpg1_out: endpoint { + remote-endpoint = <&switch_in0>; + }; + }: + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index ca3b2638fcc6..30e7e38ccad0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10826,6 +10826,7 @@ T: git git://linuxtv.org/media_tree.git S: Supported F: Documentation/devicetree/bindings/media/xilinx/ F: drivers/media/platform/xilinx/ +F: include/uapi/linux/xilinx-v4l2-controls.h XILLYBUS DRIVER M: Eli Billauer diff --git a/drivers/media/platform/xilinx/Kconfig b/drivers/media/platform/xilinx/Kconfig index 19db82343bb8..d7324c726fc2 100644 --- a/drivers/media/platform/xilinx/Kconfig +++ b/drivers/media/platform/xilinx/Kconfig @@ -7,6 +7,13 @@ config VIDEO_XILINX if VIDEO_XILINX +config VIDEO_XILINX_TPG + tristate "Xilinx Video Test Pattern Generator" + depends on VIDEO_XILINX + select VIDEO_XILINX_VTC + ---help--- + Driver for the Xilinx Video Test Pattern Generator + config VIDEO_XILINX_VTC tristate "Xilinx Video Timing Controller" depends on VIDEO_XILINX diff --git a/drivers/media/platform/xilinx/Makefile b/drivers/media/platform/xilinx/Makefile index 6611e3228e3c..e8a0f2a9f733 100644 --- a/drivers/media/platform/xilinx/Makefile +++ b/drivers/media/platform/xilinx/Makefile @@ -1,4 +1,5 @@ xilinx-video-objs += xilinx-dma.o xilinx-vip.o xilinx-vipp.o obj-$(CONFIG_VIDEO_XILINX) += xilinx-video.o +obj-$(CONFIG_VIDEO_XILINX_TPG) += xilinx-tpg.o obj-$(CONFIG_VIDEO_XILINX_VTC) += xilinx-vtc.o diff --git a/drivers/media/platform/xilinx/xilinx-tpg.c b/drivers/media/platform/xilinx/xilinx-tpg.c new file mode 100644 index 000000000000..b5f7d5ecb7f6 --- /dev/null +++ b/drivers/media/platform/xilinx/xilinx-tpg.c @@ -0,0 +1,931 @@ +/* + * Xilinx Test Pattern Generator + * + * Copyright (C) 2013-2015 Ideas on Board + * Copyright (C) 2013-2015 Xilinx, Inc. + * + * Contacts: Hyun Kwon + * Laurent Pinchart + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "xilinx-vip.h" +#include "xilinx-vtc.h" + +#define XTPG_CTRL_STATUS_SLAVE_ERROR (1 << 16) +#define XTPG_CTRL_IRQ_SLAVE_ERROR (1 << 16) + +#define XTPG_PATTERN_CONTROL 0x0100 +#define XTPG_PATTERN_MASK (0xf << 0) +#define XTPG_PATTERN_CONTROL_CROSS_HAIRS (1 << 4) +#define XTPG_PATTERN_CONTROL_MOVING_BOX (1 << 5) +#define XTPG_PATTERN_CONTROL_COLOR_MASK_SHIFT 6 +#define XTPG_PATTERN_CONTROL_COLOR_MASK_MASK (0xf << 6) +#define XTPG_PATTERN_CONTROL_STUCK_PIXEL (1 << 9) +#define XTPG_PATTERN_CONTROL_NOISE (1 << 10) +#define XTPG_PATTERN_CONTROL_MOTION (1 << 12) +#define XTPG_MOTION_SPEED 0x0104 +#define XTPG_CROSS_HAIRS 0x0108 +#define XTPG_CROSS_HAIRS_ROW_SHIFT 0 +#define XTPG_CROSS_HAIRS_ROW_MASK (0xfff << 0) +#define XTPG_CROSS_HAIRS_COLUMN_SHIFT 16 +#define XTPG_CROSS_HAIRS_COLUMN_MASK (0xfff << 16) +#define XTPG_ZPLATE_HOR_CONTROL 0x010c +#define XTPG_ZPLATE_VER_CONTROL 0x0110 +#define XTPG_ZPLATE_START_SHIFT 0 +#define XTPG_ZPLATE_START_MASK (0xffff << 0) +#define XTPG_ZPLATE_SPEED_SHIFT 16 +#define XTPG_ZPLATE_SPEED_MASK (0xffff << 16) +#define XTPG_BOX_SIZE 0x0114 +#define XTPG_BOX_COLOR 0x0118 +#define XTPG_STUCK_PIXEL_THRESH 0x011c +#define XTPG_NOISE_GAIN 0x0120 +#define XTPG_BAYER_PHASE 0x0124 +#define XTPG_BAYER_PHASE_RGGB 0 +#define XTPG_BAYER_PHASE_GRBG 1 +#define XTPG_BAYER_PHASE_GBRG 2 +#define XTPG_BAYER_PHASE_BGGR 3 +#define XTPG_BAYER_PHASE_OFF 4 + +/* + * The minimum blanking value is one clock cycle for the front porch, one clock + * cycle for the sync pulse and one clock cycle for the back porch. + */ +#define XTPG_MIN_HBLANK 3 +#define XTPG_MAX_HBLANK (XVTC_MAX_HSIZE - XVIP_MIN_WIDTH) +#define XTPG_MIN_VBLANK 3 +#define XTPG_MAX_VBLANK (XVTC_MAX_VSIZE - XVIP_MIN_HEIGHT) + +/** + * struct xtpg_device - Xilinx Test Pattern Generator device structure + * @xvip: Xilinx Video IP device + * @pads: media pads + * @npads: number of pads (1 or 2) + * @has_input: whether an input is connected to the sink pad + * @formats: active V4L2 media bus format for each pad + * @default_format: default V4L2 media bus format + * @vip_format: format information corresponding to the active format + * @bayer: boolean flag if TPG is set to any bayer format + * @ctrl_handler: control handler + * @hblank: horizontal blanking control + * @vblank: vertical blanking control + * @pattern: test pattern control + * @streaming: is the video stream active + * @vtc: video timing controller + * @vtmux_gpio: video timing mux GPIO + */ +struct xtpg_device { + struct xvip_device xvip; + + struct media_pad pads[2]; + unsigned int npads; + bool has_input; + + struct v4l2_mbus_framefmt formats[2]; + struct v4l2_mbus_framefmt default_format; + const struct xvip_video_format *vip_format; + bool bayer; + + struct v4l2_ctrl_handler ctrl_handler; + struct v4l2_ctrl *hblank; + struct v4l2_ctrl *vblank; + struct v4l2_ctrl *pattern; + bool streaming; + + struct xvtc_device *vtc; + struct gpio_desc *vtmux_gpio; +}; + +static inline struct xtpg_device *to_tpg(struct v4l2_subdev *subdev) +{ + return container_of(subdev, struct xtpg_device, xvip.subdev); +} + +static u32 xtpg_get_bayer_phase(unsigned int code) +{ + switch (code) { + case MEDIA_BUS_FMT_SRGGB8_1X8: + return XTPG_BAYER_PHASE_RGGB; + case MEDIA_BUS_FMT_SGRBG8_1X8: + return XTPG_BAYER_PHASE_GRBG; + case MEDIA_BUS_FMT_SGBRG8_1X8: + return XTPG_BAYER_PHASE_GBRG; + case MEDIA_BUS_FMT_SBGGR8_1X8: + return XTPG_BAYER_PHASE_BGGR; + default: + return XTPG_BAYER_PHASE_OFF; + } +} + +static void __xtpg_update_pattern_control(struct xtpg_device *xtpg, + bool passthrough, bool pattern) +{ + u32 pattern_mask = (1 << (xtpg->pattern->maximum + 1)) - 1; + + /* + * If the TPG has no sink pad or no input connected to its sink pad + * passthrough mode can't be enabled. + */ + if (xtpg->npads == 1 || !xtpg->has_input) + passthrough = false; + + /* If passthrough mode is allowed unmask bit 0. */ + if (passthrough) + pattern_mask &= ~1; + + /* If test pattern mode is allowed unmask all other bits. */ + if (pattern) + pattern_mask &= 1; + + __v4l2_ctrl_modify_range(xtpg->pattern, 0, xtpg->pattern->maximum, + pattern_mask, pattern ? 9 : 0); +} + +static void xtpg_update_pattern_control(struct xtpg_device *xtpg, + bool passthrough, bool pattern) +{ + mutex_lock(xtpg->ctrl_handler.lock); + __xtpg_update_pattern_control(xtpg, passthrough, pattern); + mutex_unlock(xtpg->ctrl_handler.lock); +} + +/* ----------------------------------------------------------------------------- + * V4L2 Subdevice Video Operations + */ + +static int xtpg_s_stream(struct v4l2_subdev *subdev, int enable) +{ + struct xtpg_device *xtpg = to_tpg(subdev); + unsigned int width = xtpg->formats[0].width; + unsigned int height = xtpg->formats[0].height; + bool passthrough; + u32 bayer_phase; + + if (!enable) { + xvip_stop(&xtpg->xvip); + if (xtpg->vtc) + xvtc_generator_stop(xtpg->vtc); + + xtpg_update_pattern_control(xtpg, true, true); + xtpg->streaming = false; + return 0; + } + + xvip_set_frame_size(&xtpg->xvip, &xtpg->formats[0]); + + if (xtpg->vtc) { + struct xvtc_config config = { + .hblank_start = width, + .hsync_start = width + 1, + .vblank_start = height, + .vsync_start = height + 1, + }; + unsigned int htotal; + unsigned int vtotal; + + htotal = min_t(unsigned int, XVTC_MAX_HSIZE, + v4l2_ctrl_g_ctrl(xtpg->hblank) + width); + vtotal = min_t(unsigned int, XVTC_MAX_VSIZE, + v4l2_ctrl_g_ctrl(xtpg->vblank) + height); + + config.hsync_end = htotal - 1; + config.hsize = htotal; + config.vsync_end = vtotal - 1; + config.vsize = vtotal; + + xvtc_generator_start(xtpg->vtc, &config); + } + + /* + * Configure the bayer phase and video timing mux based on the + * operation mode (passthrough or test pattern generation). The test + * pattern can be modified by the control set handler, we thus need to + * take the control lock here to avoid races. + */ + mutex_lock(xtpg->ctrl_handler.lock); + + xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, + XTPG_PATTERN_MASK, xtpg->pattern->cur.val); + + /* + * Switching between passthrough and test pattern generation modes isn't + * allowed during streaming, update the control range accordingly. + */ + passthrough = xtpg->pattern->cur.val == 0; + __xtpg_update_pattern_control(xtpg, passthrough, !passthrough); + + xtpg->streaming = true; + + mutex_unlock(xtpg->ctrl_handler.lock); + + /* + * For TPG v5.0, the bayer phase needs to be off for the pass through + * mode, otherwise the external input would be subsampled. + */ + bayer_phase = passthrough ? XTPG_BAYER_PHASE_OFF + : xtpg_get_bayer_phase(xtpg->formats[0].code); + xvip_write(&xtpg->xvip, XTPG_BAYER_PHASE, bayer_phase); + + if (xtpg->vtmux_gpio) + gpiod_set_value_cansleep(xtpg->vtmux_gpio, !passthrough); + + xvip_start(&xtpg->xvip); + + return 0; +} + +/* ----------------------------------------------------------------------------- + * V4L2 Subdevice Pad Operations + */ + +static struct v4l2_mbus_framefmt * +__xtpg_get_pad_format(struct xtpg_device *xtpg, + struct v4l2_subdev_pad_config *cfg, + unsigned int pad, u32 which) +{ + switch (which) { + case V4L2_SUBDEV_FORMAT_TRY: + return v4l2_subdev_get_try_format(&xtpg->xvip.subdev, cfg, pad); + case V4L2_SUBDEV_FORMAT_ACTIVE: + return &xtpg->formats[pad]; + default: + return NULL; + } +} + +static int xtpg_get_format(struct v4l2_subdev *subdev, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct xtpg_device *xtpg = to_tpg(subdev); + + fmt->format = *__xtpg_get_pad_format(xtpg, cfg, fmt->pad, fmt->which); + + return 0; +} + +static int xtpg_set_format(struct v4l2_subdev *subdev, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct xtpg_device *xtpg = to_tpg(subdev); + struct v4l2_mbus_framefmt *__format; + u32 bayer_phase; + + __format = __xtpg_get_pad_format(xtpg, cfg, fmt->pad, fmt->which); + + /* In two pads mode the source pad format is always identical to the + * sink pad format. + */ + if (xtpg->npads == 2 && fmt->pad == 1) { + fmt->format = *__format; + return 0; + } + + /* Bayer phase is configurable at runtime */ + if (xtpg->bayer) { + bayer_phase = xtpg_get_bayer_phase(fmt->format.code); + if (bayer_phase != XTPG_BAYER_PHASE_OFF) + __format->code = fmt->format.code; + } + + xvip_set_format_size(__format, fmt); + + fmt->format = *__format; + + /* Propagate the format to the source pad. */ + if (xtpg->npads == 2) { + __format = __xtpg_get_pad_format(xtpg, cfg, 1, fmt->which); + *__format = fmt->format; + } + + return 0; +} + +/* ----------------------------------------------------------------------------- + * V4L2 Subdevice Operations + */ + +static int xtpg_enum_frame_size(struct v4l2_subdev *subdev, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_frame_size_enum *fse) +{ + struct v4l2_mbus_framefmt *format; + + format = v4l2_subdev_get_try_format(subdev, cfg, fse->pad); + + if (fse->index || fse->code != format->code) + return -EINVAL; + + /* Min / max values for pad 0 is always fixed in both one and two pads + * modes. In two pads mode, the source pad(= 1) size is identical to + * the sink pad size */ + if (fse->pad == 0) { + fse->min_width = XVIP_MIN_WIDTH; + fse->max_width = XVIP_MAX_WIDTH; + fse->min_height = XVIP_MIN_HEIGHT; + fse->max_height = XVIP_MAX_HEIGHT; + } else { + fse->min_width = format->width; + fse->max_width = format->width; + fse->min_height = format->height; + fse->max_height = format->height; + } + + return 0; +} + +static int xtpg_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) +{ + struct xtpg_device *xtpg = to_tpg(subdev); + struct v4l2_mbus_framefmt *format; + + format = v4l2_subdev_get_try_format(subdev, fh->pad, 0); + *format = xtpg->default_format; + + if (xtpg->npads == 2) { + format = v4l2_subdev_get_try_format(subdev, fh->pad, 1); + *format = xtpg->default_format; + } + + return 0; +} + +static int xtpg_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) +{ + return 0; +} + +static int xtpg_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct xtpg_device *xtpg = container_of(ctrl->handler, + struct xtpg_device, + ctrl_handler); + switch (ctrl->id) { + case V4L2_CID_TEST_PATTERN: + xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, + XTPG_PATTERN_MASK, ctrl->val); + return 0; + case V4L2_CID_XILINX_TPG_CROSS_HAIRS: + xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, + XTPG_PATTERN_CONTROL_CROSS_HAIRS, ctrl->val); + return 0; + case V4L2_CID_XILINX_TPG_MOVING_BOX: + xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, + XTPG_PATTERN_CONTROL_MOVING_BOX, ctrl->val); + return 0; + case V4L2_CID_XILINX_TPG_COLOR_MASK: + xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, + XTPG_PATTERN_CONTROL_COLOR_MASK_MASK, + ctrl->val << + XTPG_PATTERN_CONTROL_COLOR_MASK_SHIFT); + return 0; + case V4L2_CID_XILINX_TPG_STUCK_PIXEL: + xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, + XTPG_PATTERN_CONTROL_STUCK_PIXEL, ctrl->val); + return 0; + case V4L2_CID_XILINX_TPG_NOISE: + xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, + XTPG_PATTERN_CONTROL_NOISE, ctrl->val); + return 0; + case V4L2_CID_XILINX_TPG_MOTION: + xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, + XTPG_PATTERN_CONTROL_MOTION, ctrl->val); + return 0; + case V4L2_CID_XILINX_TPG_MOTION_SPEED: + xvip_write(&xtpg->xvip, XTPG_MOTION_SPEED, ctrl->val); + return 0; + case V4L2_CID_XILINX_TPG_CROSS_HAIR_ROW: + xvip_clr_and_set(&xtpg->xvip, XTPG_CROSS_HAIRS, + XTPG_CROSS_HAIRS_ROW_MASK, + ctrl->val << XTPG_CROSS_HAIRS_ROW_SHIFT); + return 0; + case V4L2_CID_XILINX_TPG_CROSS_HAIR_COLUMN: + xvip_clr_and_set(&xtpg->xvip, XTPG_CROSS_HAIRS, + XTPG_CROSS_HAIRS_COLUMN_MASK, + ctrl->val << XTPG_CROSS_HAIRS_COLUMN_SHIFT); + return 0; + case V4L2_CID_XILINX_TPG_ZPLATE_HOR_START: + xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_HOR_CONTROL, + XTPG_ZPLATE_START_MASK, + ctrl->val << XTPG_ZPLATE_START_SHIFT); + return 0; + case V4L2_CID_XILINX_TPG_ZPLATE_HOR_SPEED: + xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_HOR_CONTROL, + XTPG_ZPLATE_SPEED_MASK, + ctrl->val << XTPG_ZPLATE_SPEED_SHIFT); + return 0; + case V4L2_CID_XILINX_TPG_ZPLATE_VER_START: + xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_VER_CONTROL, + XTPG_ZPLATE_START_MASK, + ctrl->val << XTPG_ZPLATE_START_SHIFT); + return 0; + case V4L2_CID_XILINX_TPG_ZPLATE_VER_SPEED: + xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_VER_CONTROL, + XTPG_ZPLATE_SPEED_MASK, + ctrl->val << XTPG_ZPLATE_SPEED_SHIFT); + return 0; + case V4L2_CID_XILINX_TPG_BOX_SIZE: + xvip_write(&xtpg->xvip, XTPG_BOX_SIZE, ctrl->val); + return 0; + case V4L2_CID_XILINX_TPG_BOX_COLOR: + xvip_write(&xtpg->xvip, XTPG_BOX_COLOR, ctrl->val); + return 0; + case V4L2_CID_XILINX_TPG_STUCK_PIXEL_THRESH: + xvip_write(&xtpg->xvip, XTPG_STUCK_PIXEL_THRESH, ctrl->val); + return 0; + case V4L2_CID_XILINX_TPG_NOISE_GAIN: + xvip_write(&xtpg->xvip, XTPG_NOISE_GAIN, ctrl->val); + return 0; + } + + return 0; +} + +static const struct v4l2_ctrl_ops xtpg_ctrl_ops = { + .s_ctrl = xtpg_s_ctrl, +}; + +static struct v4l2_subdev_core_ops xtpg_core_ops = { +}; + +static struct v4l2_subdev_video_ops xtpg_video_ops = { + .s_stream = xtpg_s_stream, +}; + +static struct v4l2_subdev_pad_ops xtpg_pad_ops = { + .enum_mbus_code = xvip_enum_mbus_code, + .enum_frame_size = xtpg_enum_frame_size, + .get_fmt = xtpg_get_format, + .set_fmt = xtpg_set_format, +}; + +static struct v4l2_subdev_ops xtpg_ops = { + .core = &xtpg_core_ops, + .video = &xtpg_video_ops, + .pad = &xtpg_pad_ops, +}; + +static const struct v4l2_subdev_internal_ops xtpg_internal_ops = { + .open = xtpg_open, + .close = xtpg_close, +}; + +/* + * Control Config + */ + +static const char *const xtpg_pattern_strings[] = { + "Passthrough", + "Horizontal Ramp", + "Vertical Ramp", + "Temporal Ramp", + "Solid Red", + "Solid Green", + "Solid Blue", + "Solid Black", + "Solid White", + "Color Bars", + "Zone Plate", + "Tartan Color Bars", + "Cross Hatch", + "None", + "Vertical/Horizontal Ramps", + "Black/White Checker Board", +}; + +static struct v4l2_ctrl_config xtpg_ctrls[] = { + { + .ops = &xtpg_ctrl_ops, + .id = V4L2_CID_XILINX_TPG_CROSS_HAIRS, + .name = "Test Pattern: Cross Hairs", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .min = false, + .max = true, + .step = 1, + .def = 0, + }, { + .ops = &xtpg_ctrl_ops, + .id = V4L2_CID_XILINX_TPG_MOVING_BOX, + .name = "Test Pattern: Moving Box", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .min = false, + .max = true, + .step = 1, + .def = 0, + }, { + .ops = &xtpg_ctrl_ops, + .id = V4L2_CID_XILINX_TPG_COLOR_MASK, + .name = "Test Pattern: Color Mask", + .type = V4L2_CTRL_TYPE_BITMASK, + .min = 0, + .max = 0xf, + .def = 0, + }, { + .ops = &xtpg_ctrl_ops, + .id = V4L2_CID_XILINX_TPG_STUCK_PIXEL, + .name = "Test Pattern: Stuck Pixel", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .min = false, + .max = true, + .step = 1, + .def = 0, + }, { + .ops = &xtpg_ctrl_ops, + .id = V4L2_CID_XILINX_TPG_NOISE, + .name = "Test Pattern: Noise", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .min = false, + .max = true, + .step = 1, + .def = 0, + }, { + .ops = &xtpg_ctrl_ops, + .id = V4L2_CID_XILINX_TPG_MOTION, + .name = "Test Pattern: Motion", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .min = false, + .max = true, + .step = 1, + .def = 0, + }, { + .ops = &xtpg_ctrl_ops, + .id = V4L2_CID_XILINX_TPG_MOTION_SPEED, + .name = "Test Pattern: Motion Speed", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 0, + .max = (1 << 8) - 1, + .step = 1, + .def = 4, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .ops = &xtpg_ctrl_ops, + .id = V4L2_CID_XILINX_TPG_CROSS_HAIR_ROW, + .name = "Test Pattern: Cross Hairs Row", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 0, + .max = (1 << 12) - 1, + .step = 1, + .def = 0x64, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .ops = &xtpg_ctrl_ops, + .id = V4L2_CID_XILINX_TPG_CROSS_HAIR_COLUMN, + .name = "Test Pattern: Cross Hairs Column", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 0, + .max = (1 << 12) - 1, + .step = 1, + .def = 0x64, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .ops = &xtpg_ctrl_ops, + .id = V4L2_CID_XILINX_TPG_ZPLATE_HOR_START, + .name = "Test Pattern: Zplate Horizontal Start Pos", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 0, + .max = (1 << 16) - 1, + .step = 1, + .def = 0x1e, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .ops = &xtpg_ctrl_ops, + .id = V4L2_CID_XILINX_TPG_ZPLATE_HOR_SPEED, + .name = "Test Pattern: Zplate Horizontal Speed", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 0, + .max = (1 << 16) - 1, + .step = 1, + .def = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .ops = &xtpg_ctrl_ops, + .id = V4L2_CID_XILINX_TPG_ZPLATE_VER_START, + .name = "Test Pattern: Zplate Vertical Start Pos", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 0, + .max = (1 << 16) - 1, + .step = 1, + .def = 1, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .ops = &xtpg_ctrl_ops, + .id = V4L2_CID_XILINX_TPG_ZPLATE_VER_SPEED, + .name = "Test Pattern: Zplate Vertical Speed", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 0, + .max = (1 << 16) - 1, + .step = 1, + .def = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .ops = &xtpg_ctrl_ops, + .id = V4L2_CID_XILINX_TPG_BOX_SIZE, + .name = "Test Pattern: Box Size", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 0, + .max = (1 << 12) - 1, + .step = 1, + .def = 0x32, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .ops = &xtpg_ctrl_ops, + .id = V4L2_CID_XILINX_TPG_BOX_COLOR, + .name = "Test Pattern: Box Color(RGB)", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 0, + .max = (1 << 24) - 1, + .step = 1, + .def = 0, + }, { + .ops = &xtpg_ctrl_ops, + .id = V4L2_CID_XILINX_TPG_STUCK_PIXEL_THRESH, + .name = "Test Pattern: Stuck Pixel threshold", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 0, + .max = (1 << 16) - 1, + .step = 1, + .def = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .ops = &xtpg_ctrl_ops, + .id = V4L2_CID_XILINX_TPG_NOISE_GAIN, + .name = "Test Pattern: Noise Gain", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 0, + .max = (1 << 8) - 1, + .step = 1, + .def = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, +}; + +/* ----------------------------------------------------------------------------- + * Media Operations + */ + +static const struct media_entity_operations xtpg_media_ops = { + .link_validate = v4l2_subdev_link_validate, +}; + +/* ----------------------------------------------------------------------------- + * Power Management + */ + +static int __maybe_unused xtpg_pm_suspend(struct device *dev) +{ + struct xtpg_device *xtpg = dev_get_drvdata(dev); + + xvip_suspend(&xtpg->xvip); + + return 0; +} + +static int __maybe_unused xtpg_pm_resume(struct device *dev) +{ + struct xtpg_device *xtpg = dev_get_drvdata(dev); + + xvip_resume(&xtpg->xvip); + + return 0; +} + +/* ----------------------------------------------------------------------------- + * Platform Device Driver + */ + +static int xtpg_parse_of(struct xtpg_device *xtpg) +{ + struct device *dev = xtpg->xvip.dev; + struct device_node *node = xtpg->xvip.dev->of_node; + struct device_node *ports; + struct device_node *port; + unsigned int nports = 0; + bool has_endpoint = false; + + ports = of_get_child_by_name(node, "ports"); + if (ports == NULL) + ports = node; + + for_each_child_of_node(ports, port) { + const struct xvip_video_format *format; + struct device_node *endpoint; + + if (!port->name || of_node_cmp(port->name, "port")) + continue; + + format = xvip_of_get_format(port); + if (IS_ERR(format)) { + dev_err(dev, "invalid format in DT"); + return PTR_ERR(format); + } + + /* Get and check the format description */ + if (!xtpg->vip_format) { + xtpg->vip_format = format; + } else if (xtpg->vip_format != format) { + dev_err(dev, "in/out format mismatch in DT"); + return -EINVAL; + } + + if (nports == 0) { + endpoint = of_get_next_child(port, NULL); + if (endpoint) + has_endpoint = true; + of_node_put(endpoint); + } + + /* Count the number of ports. */ + nports++; + } + + if (nports != 1 && nports != 2) { + dev_err(dev, "invalid number of ports %u\n", nports); + return -EINVAL; + } + + xtpg->npads = nports; + if (nports == 2 && has_endpoint) + xtpg->has_input = true; + + return 0; +} + +static int xtpg_probe(struct platform_device *pdev) +{ + struct v4l2_subdev *subdev; + struct xtpg_device *xtpg; + u32 i, bayer_phase; + int ret; + + xtpg = devm_kzalloc(&pdev->dev, sizeof(*xtpg), GFP_KERNEL); + if (!xtpg) + return -ENOMEM; + + xtpg->xvip.dev = &pdev->dev; + + ret = xtpg_parse_of(xtpg); + if (ret < 0) + return ret; + + ret = xvip_init_resources(&xtpg->xvip); + if (ret < 0) + return ret; + + xtpg->vtmux_gpio = devm_gpiod_get_optional(&pdev->dev, "timing", + GPIOD_OUT_HIGH); + if (IS_ERR(xtpg->vtmux_gpio)) { + ret = PTR_ERR(xtpg->vtmux_gpio); + goto error_resource; + } + + xtpg->vtc = xvtc_of_get(pdev->dev.of_node); + if (IS_ERR(xtpg->vtc)) { + ret = PTR_ERR(xtpg->vtc); + goto error_resource; + } + + /* Reset and initialize the core */ + xvip_reset(&xtpg->xvip); + + /* Initialize V4L2 subdevice and media entity. Pad numbers depend on the + * number of pads. + */ + if (xtpg->npads == 2) { + xtpg->pads[0].flags = MEDIA_PAD_FL_SINK; + xtpg->pads[1].flags = MEDIA_PAD_FL_SOURCE; + } else { + xtpg->pads[0].flags = MEDIA_PAD_FL_SOURCE; + } + + /* Initialize the default format */ + xtpg->default_format.code = xtpg->vip_format->code; + xtpg->default_format.field = V4L2_FIELD_NONE; + xtpg->default_format.colorspace = V4L2_COLORSPACE_SRGB; + xvip_get_frame_size(&xtpg->xvip, &xtpg->default_format); + + bayer_phase = xtpg_get_bayer_phase(xtpg->vip_format->code); + if (bayer_phase != XTPG_BAYER_PHASE_OFF) + xtpg->bayer = true; + + xtpg->formats[0] = xtpg->default_format; + if (xtpg->npads == 2) + xtpg->formats[1] = xtpg->default_format; + + /* Initialize V4L2 subdevice and media entity */ + subdev = &xtpg->xvip.subdev; + v4l2_subdev_init(subdev, &xtpg_ops); + subdev->dev = &pdev->dev; + subdev->internal_ops = &xtpg_internal_ops; + strlcpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name)); + v4l2_set_subdevdata(subdev, xtpg); + subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + subdev->entity.ops = &xtpg_media_ops; + + ret = media_entity_init(&subdev->entity, xtpg->npads, xtpg->pads, 0); + if (ret < 0) + goto error; + + v4l2_ctrl_handler_init(&xtpg->ctrl_handler, 3 + ARRAY_SIZE(xtpg_ctrls)); + + xtpg->vblank = v4l2_ctrl_new_std(&xtpg->ctrl_handler, &xtpg_ctrl_ops, + V4L2_CID_VBLANK, XTPG_MIN_VBLANK, + XTPG_MAX_VBLANK, 1, 100); + xtpg->hblank = v4l2_ctrl_new_std(&xtpg->ctrl_handler, &xtpg_ctrl_ops, + V4L2_CID_HBLANK, XTPG_MIN_HBLANK, + XTPG_MAX_HBLANK, 1, 100); + xtpg->pattern = v4l2_ctrl_new_std_menu_items(&xtpg->ctrl_handler, + &xtpg_ctrl_ops, V4L2_CID_TEST_PATTERN, + ARRAY_SIZE(xtpg_pattern_strings) - 1, + 1, 9, xtpg_pattern_strings); + + for (i = 0; i < ARRAY_SIZE(xtpg_ctrls); i++) + v4l2_ctrl_new_custom(&xtpg->ctrl_handler, &xtpg_ctrls[i], NULL); + + if (xtpg->ctrl_handler.error) { + dev_err(&pdev->dev, "failed to add controls\n"); + ret = xtpg->ctrl_handler.error; + goto error; + } + subdev->ctrl_handler = &xtpg->ctrl_handler; + + xtpg_update_pattern_control(xtpg, true, true); + + ret = v4l2_ctrl_handler_setup(&xtpg->ctrl_handler); + if (ret < 0) { + dev_err(&pdev->dev, "failed to set controls\n"); + goto error; + } + + platform_set_drvdata(pdev, xtpg); + + xvip_print_version(&xtpg->xvip); + + ret = v4l2_async_register_subdev(subdev); + if (ret < 0) { + dev_err(&pdev->dev, "failed to register subdev\n"); + goto error; + } + + return 0; + +error: + v4l2_ctrl_handler_free(&xtpg->ctrl_handler); + media_entity_cleanup(&subdev->entity); + xvtc_put(xtpg->vtc); +error_resource: + xvip_cleanup_resources(&xtpg->xvip); + return ret; +} + +static int xtpg_remove(struct platform_device *pdev) +{ + struct xtpg_device *xtpg = platform_get_drvdata(pdev); + struct v4l2_subdev *subdev = &xtpg->xvip.subdev; + + v4l2_async_unregister_subdev(subdev); + v4l2_ctrl_handler_free(&xtpg->ctrl_handler); + media_entity_cleanup(&subdev->entity); + + xvip_cleanup_resources(&xtpg->xvip); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(xtpg_pm_ops, xtpg_pm_suspend, xtpg_pm_resume); + +static const struct of_device_id xtpg_of_id_table[] = { + { .compatible = "xlnx,v-tpg-5.0" }, + { } +}; +MODULE_DEVICE_TABLE(of, xtpg_of_id_table); + +static struct platform_driver xtpg_driver = { + .driver = { + .name = "xilinx-tpg", + .pm = &xtpg_pm_ops, + .of_match_table = xtpg_of_id_table, + }, + .probe = xtpg_probe, + .remove = xtpg_remove, +}; + +module_platform_driver(xtpg_driver); + +MODULE_AUTHOR("Laurent Pinchart "); +MODULE_DESCRIPTION("Xilinx Test Pattern Generator Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index 68ceb97c458c..d4cfc17cc414 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -446,5 +446,6 @@ header-y += wireless.h header-y += x25.h header-y += xattr.h header-y += xfrm.h +header-y += xilinx-v4l2-controls.h header-y += zorro.h header-y += zorro_ids.h diff --git a/include/uapi/linux/xilinx-v4l2-controls.h b/include/uapi/linux/xilinx-v4l2-controls.h new file mode 100644 index 000000000000..fb495b91e800 --- /dev/null +++ b/include/uapi/linux/xilinx-v4l2-controls.h @@ -0,0 +1,73 @@ +/* + * Xilinx Controls Header + * + * Copyright (C) 2013-2015 Ideas on Board + * Copyright (C) 2013-2015 Xilinx, Inc. + * + * Contacts: Hyun Kwon + * Laurent Pinchart + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __UAPI_XILINX_V4L2_CONTROLS_H__ +#define __UAPI_XILINX_V4L2_CONTROLS_H__ + +#include + +#define V4L2_CID_XILINX_OFFSET 0xc000 +#define V4L2_CID_XILINX_BASE (V4L2_CID_USER_BASE + V4L2_CID_XILINX_OFFSET) + +/* + * Private Controls for Xilinx Video IPs + */ + +/* + * Xilinx TPG Video IP + */ + +#define V4L2_CID_XILINX_TPG (V4L2_CID_USER_BASE + 0xc000) + +/* Draw cross hairs */ +#define V4L2_CID_XILINX_TPG_CROSS_HAIRS (V4L2_CID_XILINX_TPG + 1) +/* Enable a moving box */ +#define V4L2_CID_XILINX_TPG_MOVING_BOX (V4L2_CID_XILINX_TPG + 2) +/* Mask out a color component */ +#define V4L2_CID_XILINX_TPG_COLOR_MASK (V4L2_CID_XILINX_TPG + 3) +/* Enable a stuck pixel feature */ +#define V4L2_CID_XILINX_TPG_STUCK_PIXEL (V4L2_CID_XILINX_TPG + 4) +/* Enable a noisy output */ +#define V4L2_CID_XILINX_TPG_NOISE (V4L2_CID_XILINX_TPG + 5) +/* Enable the motion feature */ +#define V4L2_CID_XILINX_TPG_MOTION (V4L2_CID_XILINX_TPG + 6) +/* Configure the motion speed of moving patterns */ +#define V4L2_CID_XILINX_TPG_MOTION_SPEED (V4L2_CID_XILINX_TPG + 7) +/* The row of horizontal cross hair location */ +#define V4L2_CID_XILINX_TPG_CROSS_HAIR_ROW (V4L2_CID_XILINX_TPG + 8) +/* The colum of vertical cross hair location */ +#define V4L2_CID_XILINX_TPG_CROSS_HAIR_COLUMN (V4L2_CID_XILINX_TPG + 9) +/* Set starting point of sine wave for horizontal component */ +#define V4L2_CID_XILINX_TPG_ZPLATE_HOR_START (V4L2_CID_XILINX_TPG + 10) +/* Set speed of the horizontal component */ +#define V4L2_CID_XILINX_TPG_ZPLATE_HOR_SPEED (V4L2_CID_XILINX_TPG + 11) +/* Set starting point of sine wave for vertical component */ +#define V4L2_CID_XILINX_TPG_ZPLATE_VER_START (V4L2_CID_XILINX_TPG + 12) +/* Set speed of the vertical component */ +#define V4L2_CID_XILINX_TPG_ZPLATE_VER_SPEED (V4L2_CID_XILINX_TPG + 13) +/* Moving box size */ +#define V4L2_CID_XILINX_TPG_BOX_SIZE (V4L2_CID_XILINX_TPG + 14) +/* Moving box color */ +#define V4L2_CID_XILINX_TPG_BOX_COLOR (V4L2_CID_XILINX_TPG + 15) +/* Upper limit count of generated stuck pixels */ +#define V4L2_CID_XILINX_TPG_STUCK_PIXEL_THRESH (V4L2_CID_XILINX_TPG + 16) +/* Noise level */ +#define V4L2_CID_XILINX_TPG_NOISE_GAIN (V4L2_CID_XILINX_TPG + 17) + +#endif /* __UAPI_XILINX_V4L2_CONTROLS_H__ */ -- cgit v1.2.3 From b6e5b8f1a90230f922de8af59cdaf1ad83e1ac1e Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Fri, 20 Mar 2015 10:45:43 -0300 Subject: [media] media: New flag V4L2_CTRL_FLAG_EXECUTE_ON_WRITE Create a new flag that represent controls which its value needs to be passed to the driver even if it has not changed. They typically represent actions, like triggering a flash or clearing an error flag. So writing to such a control means some action is executed. Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/videodev2.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/uapi') diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 47df18f36c4b..810bade873f4 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -1457,6 +1457,7 @@ struct v4l2_querymenu { #define V4L2_CTRL_FLAG_WRITE_ONLY 0x0040 #define V4L2_CTRL_FLAG_VOLATILE 0x0080 #define V4L2_CTRL_FLAG_HAS_PAYLOAD 0x0100 +#define V4L2_CTRL_FLAG_EXECUTE_ON_WRITE 0x0200 /* Query flags, to be ORed with the control ID */ #define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000 -- cgit v1.2.3 From 5ce65d1f874ddc109780fc781bb3b099bff82001 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 20 Mar 2015 14:05:03 -0300 Subject: [media] videodev2.h/v4l2-dv-timings.h: add V4L2_DV_FL_IS_CE_VIDEO flag In the past the V4L2_DV_BT_STD_CEA861 standard bit was used to determine whether the format is a CE (Consumer Electronics) format or not. However, the 640x480p59.94 format is part of the CEA-861 standard, but it is *not* a CE video format. Add a new flag to make this explicit. This information is needed in order to determine the default R'G'B' encoding for the format: for CE video this is limited range (16-235) instead of full range (0-255). The header with all the timings has been updated with this new flag. Signed-off-by: Hans Verkuil Cc: Martin Bugge Cc: Mats Randgaard Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/v4l2-dv-timings.h | 64 ++++++++++++++++++++++-------------- include/uapi/linux/videodev2.h | 6 ++++ 2 files changed, 45 insertions(+), 25 deletions(-) (limited to 'include/uapi') diff --git a/include/uapi/linux/v4l2-dv-timings.h b/include/uapi/linux/v4l2-dv-timings.h index 6c8f159e416e..c039f1d68a09 100644 --- a/include/uapi/linux/v4l2-dv-timings.h +++ b/include/uapi/linux/v4l2-dv-timings.h @@ -48,14 +48,15 @@ .type = V4L2_DV_BT_656_1120, \ V4L2_INIT_BT_TIMINGS(720, 480, 1, 0, \ 13500000, 19, 62, 57, 4, 3, 15, 4, 3, 16, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_HALF_LINE) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_HALF_LINE | V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_720X480P59_94 { \ .type = V4L2_DV_BT_656_1120, \ V4L2_INIT_BT_TIMINGS(720, 480, 0, 0, \ 27000000, 16, 62, 60, 9, 6, 30, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, 0) \ + V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ } /* Note: these are the nominal timings, for HDMI links this format is typically @@ -64,14 +65,15 @@ .type = V4L2_DV_BT_656_1120, \ V4L2_INIT_BT_TIMINGS(720, 576, 1, 0, \ 13500000, 12, 63, 69, 2, 3, 19, 2, 3, 20, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_HALF_LINE) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_HALF_LINE | V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_720X576P50 { \ .type = V4L2_DV_BT_656_1120, \ V4L2_INIT_BT_TIMINGS(720, 576, 0, 0, \ 27000000, 12, 64, 68, 5, 5, 39, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, 0) \ + V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_1280X720P24 { \ @@ -88,7 +90,7 @@ V4L2_INIT_BT_TIMINGS(1280, 720, 0, \ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 74250000, 2420, 40, 220, 5, 5, 20, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, 0) \ + V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_1280X720P30 { \ @@ -96,7 +98,8 @@ V4L2_INIT_BT_TIMINGS(1280, 720, 0, \ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 74250000, 1760, 40, 220, 5, 5, 20, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_1280X720P50 { \ @@ -104,7 +107,7 @@ V4L2_INIT_BT_TIMINGS(1280, 720, 0, \ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 74250000, 440, 40, 220, 5, 5, 20, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, 0) \ + V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_1280X720P60 { \ @@ -112,7 +115,8 @@ V4L2_INIT_BT_TIMINGS(1280, 720, 0, \ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 74250000, 110, 40, 220, 5, 5, 20, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_1920X1080P24 { \ @@ -120,7 +124,8 @@ V4L2_INIT_BT_TIMINGS(1920, 1080, 0, \ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 74250000, 638, 44, 148, 4, 5, 36, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_1920X1080P25 { \ @@ -128,7 +133,7 @@ V4L2_INIT_BT_TIMINGS(1920, 1080, 0, \ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 74250000, 528, 44, 148, 4, 5, 36, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, 0) \ + V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_1920X1080P30 { \ @@ -136,7 +141,8 @@ V4L2_INIT_BT_TIMINGS(1920, 1080, 0, \ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 74250000, 88, 44, 148, 4, 5, 36, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_1920X1080I50 { \ @@ -144,7 +150,8 @@ V4L2_INIT_BT_TIMINGS(1920, 1080, 1, \ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 74250000, 528, 44, 148, 2, 5, 15, 2, 5, 16, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_HALF_LINE) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_HALF_LINE | V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_1920X1080P50 { \ @@ -152,7 +159,7 @@ V4L2_INIT_BT_TIMINGS(1920, 1080, 0, \ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 148500000, 528, 44, 148, 4, 5, 36, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, 0) \ + V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_1920X1080I60 { \ @@ -161,7 +168,8 @@ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 74250000, 88, 44, 148, 2, 5, 15, 2, 5, 16, \ V4L2_DV_BT_STD_CEA861, \ - V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_HALF_LINE) \ + V4L2_DV_FL_CAN_REDUCE_FPS | \ + V4L2_DV_FL_HALF_LINE | V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_1920X1080P60 { \ @@ -170,77 +178,83 @@ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 148500000, 88, 44, 148, 4, 5, 36, 0, 0, 0, \ V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CEA861, \ - V4L2_DV_FL_CAN_REDUCE_FPS) \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_3840X2160P24 { \ .type = V4L2_DV_BT_656_1120, \ V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ 297000000, 1276, 88, 296, 8, 10, 72, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_3840X2160P25 { \ .type = V4L2_DV_BT_656_1120, \ V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ 297000000, 1056, 88, 296, 8, 10, 72, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, 0) \ + V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_3840X2160P30 { \ .type = V4L2_DV_BT_656_1120, \ V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ 297000000, 176, 88, 296, 8, 10, 72, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_3840X2160P50 { \ .type = V4L2_DV_BT_656_1120, \ V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ 594000000, 1056, 88, 296, 8, 10, 72, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, 0) \ + V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_3840X2160P60 { \ .type = V4L2_DV_BT_656_1120, \ V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ 594000000, 176, 88, 296, 8, 10, 72, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_4096X2160P24 { \ .type = V4L2_DV_BT_656_1120, \ V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ 297000000, 1020, 88, 296, 8, 10, 72, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_4096X2160P25 { \ .type = V4L2_DV_BT_656_1120, \ V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ 297000000, 968, 88, 128, 8, 10, 72, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, 0) \ + V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_4096X2160P30 { \ .type = V4L2_DV_BT_656_1120, \ V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ 297000000, 88, 88, 128, 8, 10, 72, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_4096X2160P50 { \ .type = V4L2_DV_BT_656_1120, \ V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ 594000000, 968, 88, 128, 8, 10, 72, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, 0) \ + V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_4096X2160P60 { \ .type = V4L2_DV_BT_656_1120, \ V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ 594000000, 88, 88, 128, 8, 10, 72, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ } diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 810bade873f4..fa376f7666ba 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -1188,6 +1188,12 @@ struct v4l2_bt_timings { exactly the same number of half-lines. Whether half-lines can be detected or used depends on the hardware. */ #define V4L2_DV_FL_HALF_LINE (1 << 3) +/* If set, then this is a Consumer Electronics (CE) video format. Such formats + * differ from other formats (commonly called IT formats) in that if RGB + * encoding is used then by default the RGB values use limited range (i.e. + * use the range 16-235) as opposed to 0-255. All formats defined in CEA-861 + * except for the 640x480 format are CE formats. */ +#define V4L2_DV_FL_IS_CE_VIDEO (1 << 4) /* A few useful defines to calculate the total blanking and frame sizes */ #define V4L2_DV_BT_BLANKING_WIDTH(bt) \ -- cgit v1.2.3