I will be sending the patch for documentation today. FYI. Murali Karicheri Software Design Engineer Texas Instruments Inc. Germantown, MD 20874 email: m-karicheri2@xxxxxx >-----Original Message----- >From: Karicheri, Muralidharan >Sent: Wednesday, November 18, 2009 12:04 PM >To: linux-media@xxxxxxxxxxxxxxx; hverkuil@xxxxxxxxx >Cc: davinci-linux-open-source@xxxxxxxxxxxxxxxxxxxx; Karicheri, Muralidharan >Subject: [PATCH v2] V4L - Adding Digital Video Timings APIs > >From: Muralidharan Karicheri <m-karicheri2@xxxxxx> > >This is the second version of the digital video timings APIs implementation. >This adds comment from previous version. I would like to have this >merged to 2.6.33 > >This adds the above APIs to the v4l2 core. This is based on version v1.2 >of the RFC titled "V4L - Support for video timings at the input/output >interface" >Following new ioctls are added:- > > - VIDIOC_ENUM_DV_PRESETS > - VIDIOC_S_DV_PRESET > - VIDIOC_G_DV_PRESET > - VIDIOC_QUERY_DV_PRESET > - VIDIOC_S_DV_TIMINGS > - VIDIOC_G_DV_TIMINGS > >Please refer to the RFC for the details. This code was tested using vpfe >capture driver on TI's DM365. Following is the test configuration used :- > >Blue Ray HD DVD source -> TVP7002 -> DM365 (VPFE) ->DDR > >A draft version of the TVP7002 driver (currently being reviewed in the >mailing >list) was used that supports V4L2_DV_1080I60 & V4L2_DV_720P60 presets. > >A loopback video capture application was used for testing these APIs. This >calls >following IOCTLS :- > > - verify the new v4l2_input capabilities flag added > - Enumerate available presets using VIDIOC_ENUM_DV_PRESETS > - Set one of the supported preset using VIDIOC_S_DV_PRESET > - Get current preset using VIDIOC_G_DV_PRESET > - Detect current preset using VIDIOC_QUERY_DV_PRESET > - Using stub functions in tvp7002, verify VIDIOC_S_DV_TIMINGS > and VIDIOC_G_DV_TIMINGS ioctls are received at the sub device. > >TODOs : > > - Test it on a 64bit platform - I need help here since I don't have the >platform. > - Add documentation (I will send another patch for this today). > - Update v4l2-apps for the new ioctl (will send another patch after > compilation issue is resolved) > >Please review this and let me know your comments. > >Signed-off-by: Muralidharan Karicheri <m-karicheri2@xxxxxx> >Reviewed-by: Hans Verkuil <hverkuil@xxxxxxxxx> >--- >Applies to V4L-DVB linux-next branch > > drivers/media/video/v4l2-compat-ioctl32.c | 7 ++ > drivers/media/video/v4l2-ioctl.c | 148 >+++++++++++++++++++++++++++++ > include/linux/videodev2.h | 136 >++++++++++++++++++++++++++- > include/media/v4l2-ioctl.h | 15 +++ > include/media/v4l2-subdev.h | 21 ++++ > 5 files changed, 325 insertions(+), 2 deletions(-) > >diff --git a/drivers/media/video/v4l2-compat-ioctl32.c >b/drivers/media/video/v4l2-compat-ioctl32.c >index 997975d..9277448 100644 >--- a/drivers/media/video/v4l2-compat-ioctl32.c >+++ b/drivers/media/video/v4l2-compat-ioctl32.c >@@ -1077,6 +1077,13 @@ long v4l2_compat_ioctl32(struct file *file, unsigned >int cmd, unsigned long arg) > case VIDIOC_DBG_G_REGISTER: > case VIDIOC_DBG_G_CHIP_IDENT: > case VIDIOC_S_HW_FREQ_SEEK: >+ case VIDIOC_ENUM_DV_PRESETS: >+ case VIDIOC_S_DV_PRESET: >+ case VIDIOC_G_DV_PRESET: >+ case VIDIOC_QUERY_DV_PRESET: >+ case VIDIOC_S_DV_TIMINGS: >+ case VIDIOC_G_DV_TIMINGS: >+ > ret = do_video_ioctl(file, cmd, arg); > break; > >diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2- >ioctl.c >index 30cc334..9593720 100644 >--- a/drivers/media/video/v4l2-ioctl.c >+++ b/drivers/media/video/v4l2-ioctl.c >@@ -284,6 +284,12 @@ static const char *v4l2_ioctls[] = { > [_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT", > [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK", > #endif >+ [_IOC_NR(VIDIOC_ENUM_DV_PRESETS)] = "VIDIOC_ENUM_DV_PRESETS", >+ [_IOC_NR(VIDIOC_S_DV_PRESET)] = "VIDIOC_S_DV_PRESET", >+ [_IOC_NR(VIDIOC_G_DV_PRESET)] = "VIDIOC_G_DV_PRESET", >+ [_IOC_NR(VIDIOC_QUERY_DV_PRESET)] = "VIDIOC_QUERY_DV_PRESET", >+ [_IOC_NR(VIDIOC_S_DV_TIMINGS)] = "VIDIOC_S_DV_TIMINGS", >+ [_IOC_NR(VIDIOC_G_DV_TIMINGS)] = "VIDIOC_G_DV_TIMINGS", > }; > #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) > >@@ -1135,6 +1141,19 @@ static long __video_do_ioctl(struct file *file, > { > struct v4l2_input *p = arg; > >+ /** >+ * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS & >+ * CAP_STD here based on ioctl handler provided by the >+ * driver. If the driver doesn't support these >+ * for a specific input, it must override these flags. >+ */ >+ if (ops->vidioc_s_std) >+ p->capabilities |= V4L2_IN_CAP_STD; >+ if (ops->vidioc_s_dv_preset) >+ p->capabilities |= V4L2_IN_CAP_PRESETS; >+ if (ops->vidioc_s_dv_timings) >+ p->capabilities |= V4L2_IN_CAP_CUSTOM_TIMINGS; >+ > if (!ops->vidioc_enum_input) > break; > >@@ -1179,6 +1198,19 @@ static long __video_do_ioctl(struct file *file, > if (!ops->vidioc_enum_output) > break; > >+ /** >+ * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS & >+ * CAP_STD here based on ioctl handler provided by the >+ * driver. If the driver doesn't support these >+ * for a specific output , it must override these flags. >+ */ >+ if (ops->vidioc_s_std) >+ p->capabilities |= V4L2_OUT_CAP_STD; >+ if (ops->vidioc_s_dv_preset) >+ p->capabilities |= V4L2_OUT_CAP_PRESETS; >+ if (ops->vidioc_s_dv_timings) >+ p->capabilities |= V4L2_OUT_CAP_CUSTOM_TIMINGS; >+ > ret = ops->vidioc_enum_output(file, fh, p); > if (!ret) > dbgarg(cmd, "index=%d, name=%s, type=%d, " >@@ -1794,6 +1826,122 @@ static long __video_do_ioctl(struct file *file, > } > break; > } >+ case VIDIOC_ENUM_DV_PRESETS: >+ { >+ struct v4l2_dv_enum_preset *p = arg; >+ >+ if (!ops->vidioc_enum_dv_presets) >+ break; >+ >+ ret = ops->vidioc_enum_dv_presets(file, fh, p); >+ if (!ret) >+ dbgarg(cmd, >+ "index=%d, preset=%d, name=%s, width=%d," >+ " height=%d ", >+ p->index, p->preset, p->name, p->width, >+ p->height); >+ break; >+ } >+ case VIDIOC_S_DV_PRESET: >+ { >+ struct v4l2_dv_preset *p = arg; >+ >+ if (!ops->vidioc_s_dv_preset) >+ break; >+ >+ dbgarg(cmd, "preset=%d\n", p->preset); >+ ret = ops->vidioc_s_dv_preset(file, fh, p); >+ break; >+ } >+ case VIDIOC_G_DV_PRESET: >+ { >+ struct v4l2_dv_preset *p = arg; >+ >+ if (!ops->vidioc_g_dv_preset) >+ break; >+ >+ ret = ops->vidioc_g_dv_preset(file, fh, p); >+ if (!ret) >+ dbgarg(cmd, "preset=%d\n", p->preset); >+ break; >+ } >+ case VIDIOC_QUERY_DV_PRESET: >+ { >+ struct v4l2_dv_preset *p = arg; >+ >+ if (!ops->vidioc_query_dv_preset) >+ break; >+ >+ ret = ops->vidioc_query_dv_preset(file, fh, p); >+ if (!ret) >+ dbgarg(cmd, "preset=%d\n", p->preset); >+ break; >+ } >+ case VIDIOC_S_DV_TIMINGS: >+ { >+ struct v4l2_dv_timings *p = arg; >+ >+ if (!ops->vidioc_s_dv_timings) >+ break; >+ >+ dbgarg(cmd, "type=%d", p->type); >+ switch (p->type) { >+ case V4L2_DV_BT_656_1120: >+ dbgarg2("interlaced=%d, pixelclock=%lld," >+ " width=%d, height=%d, polarities=%x," >+ " hfrontporch=%d, hsync=%d, hbackporch=%d," >+ " vfrontporch=%d, vsync=%d, vbackporch=%d," >+ " il_vfrontporch=%d, il_vsync=%d," >+ " il_vbackporch=%d\n", >+ p->bt.interlaced, p->bt.pixelclock, >+ p->bt.width, p->bt.height, p->bt.polarities, >+ p->bt.hfrontporch, p->bt.hsync, >+ p->bt.hbackporch, p->bt.vfrontporch, >+ p->bt.vsync, p->bt.vbackporch, >+ p->bt.il_vfrontporch, p->bt.il_vsync, >+ p->bt.il_vbackporch); >+ ret = ops->vidioc_s_dv_timings(file, fh, p); >+ break; >+ default: >+ dbgarg2("- Unknown type!\n"); >+ break; >+ } >+ break; >+ } >+ case VIDIOC_G_DV_TIMINGS: >+ { >+ struct v4l2_dv_timings *p = arg; >+ >+ if (!ops->vidioc_g_dv_timings) >+ break; >+ >+ dbgarg(cmd, "type=%d", p->type); >+ ret = ops->vidioc_g_dv_timings(file, fh, p); >+ if (!ret) { >+ switch (p->type) { >+ case V4L2_DV_BT_656_1120: >+ dbgarg2("interlaced=%d, pixelclock=%lld," >+ " width=%d, height=%d, polarities=%x," >+ " hfrontporch=%d, hsync=%d," >+ " hbackporch=%d, vfrontporch=%d," >+ " vsync=%d, vbackporch=%d," >+ " il_vfrontporch=%d, il_vsync=%d," >+ " il_vbackporch=%d\n", >+ p->bt.interlaced, p->bt.pixelclock, >+ p->bt.width, p->bt.height, >+ p->bt.polarities, p->bt.hfrontporch, >+ p->bt.hsync, p->bt.hbackporch, >+ p->bt.vfrontporch, p->bt.vsync, >+ p->bt.vbackporch, p->bt.il_vfrontporch, >+ p->bt.il_vsync, p->bt.il_vbackporch); >+ break; >+ default: >+ dbgarg2("- Unknown type!\n"); >+ break; >+ } >+ } >+ break; >+ } > > default: > { >diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h >index cfde111..5bcc4ab 100644 >--- a/include/linux/videodev2.h >+++ b/include/linux/videodev2.h >@@ -731,6 +731,119 @@ struct v4l2_standard { > }; > > /* >+ * V I D E O T I M I N G S D V P R E S E T >+ */ >+struct v4l2_dv_preset { >+ __u32 preset; >+ __u32 reserved[4]; >+}; >+ >+/* >+ * D V P R E S E T S E N U M E R A T I O N >+ */ >+struct v4l2_dv_enum_preset { >+ __u32 index; >+ __u32 preset; >+ __u8 name[32]; /* Name of the preset timing */ >+ __u32 width; >+ __u32 height; >+ __u32 reserved[4]; >+}; >+ >+/* >+ * D V P R E S E T V A L U E S >+ */ >+#define V4L2_DV_PRESET_BASE 0x00000000 >+#define V4L2_DV_INVALID (V4L2_DV_PRESET_BASE + 0) >+/* BT.1362 */ >+#define V4L2_DV_480P59_94 (V4L2_DV_PRESET_BASE + 1) >+/* BT.1362 */ >+#define V4L2_DV_576P50 (V4L2_DV_PRESET_BASE + 2) >+/* SMPTE 296M */ >+#define V4L2_DV_720P24 (V4L2_DV_PRESET_BASE + 3) >+/* SMPTE 296M */ >+#define V4L2_DV_720P25 (V4L2_DV_PRESET_BASE + 4) >+/* SMPTE 296M */ >+#define V4L2_DV_720P30 (V4L2_DV_PRESET_BASE + 5) >+/* SMPTE 296M */ >+#define V4L2_DV_720P50 (V4L2_DV_PRESET_BASE + 6) >+/* SMPTE 274M */ >+#define V4L2_DV_720P59_94 (V4L2_DV_PRESET_BASE + 7) >+/* SMPTE 274M/296M */ >+#define V4L2_DV_720P60 (V4L2_DV_PRESET_BASE + 8) >+/* BT.1120/ SMPTE 274M */ >+#define V4L2_DV_1080I29_97 (V4L2_DV_PRESET_BASE + 9) >+/* BT.1120/ SMPTE 274M */ >+#define V4L2_DV_1080I30 (V4L2_DV_PRESET_BASE + 10) >+/* BT.1120 */ >+#define V4L2_DV_1080I25 (V4L2_DV_PRESET_BASE + 11) >+/* SMPTE 296M */ >+#define V4L2_DV_1080I50 (V4L2_DV_PRESET_BASE + 12) >+/* SMPTE 296M */ >+#define V4L2_DV_1080I60 (V4L2_DV_PRESET_BASE + 13) >+/* SMPTE 296M */ >+#define V4L2_DV_1080P24 (V4L2_DV_PRESET_BASE + 14) >+/* SMPTE 296M */ >+#define V4L2_DV_1080P25 (V4L2_DV_PRESET_BASE + 15) >+/* SMPTE 296M */ >+#define V4L2_DV_1080P30 (V4L2_DV_PRESET_BASE + 16) >+/* BT.1120 */ >+#define V4L2_DV_1080P50 (V4L2_DV_PRESET_BASE + 17) >+/* BT.1120 */ >+#define V4L2_DV_1080P60 (V4L2_DV_PRESET_BASE + 18) >+ >+/* >+ * D V B T T I M I N G S >+ */ >+ >+/* BT.656/BT.1120 timing data */ >+struct v4l2_bt_timings { >+ __u32 width; /* width in pixels */ >+ __u32 height; /* height in lines */ >+ __u32 interlaced; /* Interlaced or progressive */ >+ __u32 polarities; /* Positive or negative polarity */ >+ __u64 pixelclock; /* Pixel clock in HZ. Ex. 74.25MHz->74250000 */ >+ __u32 hfrontporch; /* Horizpontal front porch in pixels */ >+ __u32 hsync; /* Horizontal Sync length in pixels */ >+ __u32 hbackporch; /* Horizontal back porch in pixels */ >+ __u32 vfrontporch; /* Vertical front porch in pixels */ >+ __u32 vsync; /* Vertical Sync length in lines */ >+ __u32 vbackporch; /* Vertical back porch in lines */ >+ __u32 il_vfrontporch; /* Vertical front porch for bottom field of >+ * interlaced field formats >+ */ >+ __u32 il_vsync; /* Vertical sync length for bottom field of >+ * interlaced field formats >+ */ >+ __u32 il_vbackporch; /* Vertical back porch for bottom field of >+ * interlaced field formats >+ */ >+ __u32 reserved[16]; >+}; >+ >+/* Interlaced or progressive format */ >+#define V4L2_DV_PROGRESSIVE 0 >+#define V4L2_DV_INTERLACED 1 >+ >+/* Polarities. If bit is not set, it is assumed to be negative polarity */ >+#define V4L2_DV_VSYNC_POS_POL 0x00000001 >+#define V4L2_DV_HSYNC_POS_POL 0x00000002 >+ >+/* BT.656/1120 timing type */ >+enum v4l2_dv_timings_type { >+ V4L2_DV_BT_656_1120, >+}; >+ >+/* DV timings */ >+struct v4l2_dv_timings { >+ enum v4l2_dv_timings_type type; >+ union { >+ struct v4l2_bt_timings bt; >+ __u32 reserved[32]; >+ }; >+}; >+ >+/* > * V I D E O I N P U T S > */ > struct v4l2_input { >@@ -741,7 +854,8 @@ struct v4l2_input { > __u32 tuner; /* Associated tuner */ > v4l2_std_id std; > __u32 status; >- __u32 reserved[4]; >+ __u32 capabilities; >+ __u32 reserved[3]; > }; > > /* Values for the 'type' field */ >@@ -772,6 +886,11 @@ struct v4l2_input { > #define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */ > #define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */ > >+/* capabilities flags */ >+#define V4L2_IN_CAP_PRESETS 0x00000001 /* Supports DV_PRESETS */ >+#define V4L2_IN_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports Custom timings >*/ >+#define V4L2_IN_CAP_STD 0x00000004 /* Supports STD */ >+ > /* > * V I D E O O U T P U T S > */ >@@ -782,13 +901,19 @@ struct v4l2_output { > __u32 audioset; /* Associated audios (bitfield) */ > __u32 modulator; /* Associated modulator */ > v4l2_std_id std; >- __u32 reserved[4]; >+ __u32 capabilities; >+ __u32 reserved[3]; > }; > /* Values for the 'type' field */ > #define V4L2_OUTPUT_TYPE_MODULATOR 1 > #define V4L2_OUTPUT_TYPE_ANALOG 2 > #define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3 > >+/* capabilities flags */ >+#define V4L2_OUT_CAP_PRESETS 0x00000001 /* Supports DV_PRESETS */ >+#define V4L2_OUT_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports Custom >timings */ >+#define V4L2_OUT_CAP_STD 0x00000004 /* Supports STD */ >+ > /* > * C O N T R O L S > */ >@@ -1621,6 +1746,13 @@ struct v4l2_dbg_chip_ident { > #endif > > #define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct >v4l2_hw_freq_seek) >+#define VIDIOC_ENUM_DV_PRESETS _IOWR('V', 83, struct >v4l2_dv_enum_preset) >+#define VIDIOC_S_DV_PRESET _IOWR('V', 84, struct v4l2_dv_preset) >+#define VIDIOC_G_DV_PRESET _IOWR('V', 85, struct v4l2_dv_preset) >+#define VIDIOC_QUERY_DV_PRESET _IOR('V', 86, struct v4l2_dv_preset) >+#define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings) >+#define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings) >+ > /* Reminder: when adding new ioctls please add support for them to > drivers/media/video/v4l2-compat-ioctl32.c as well! */ > >diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h >index 7a4529d..e8ba0f2 100644 >--- a/include/media/v4l2-ioctl.h >+++ b/include/media/v4l2-ioctl.h >@@ -239,6 +239,21 @@ struct v4l2_ioctl_ops { > int (*vidioc_enum_frameintervals) (struct file *file, void *fh, > struct v4l2_frmivalenum *fival); > >+ /* DV Timings IOCTLs */ >+ int (*vidioc_enum_dv_presets) (struct file *file, void *fh, >+ struct v4l2_dv_enum_preset *preset); >+ >+ int (*vidioc_s_dv_preset) (struct file *file, void *fh, >+ struct v4l2_dv_preset *preset); >+ int (*vidioc_g_dv_preset) (struct file *file, void *fh, >+ struct v4l2_dv_preset *preset); >+ int (*vidioc_query_dv_preset) (struct file *file, void *fh, >+ struct v4l2_dv_preset *qpreset); >+ int (*vidioc_s_dv_timings) (struct file *file, void *fh, >+ struct v4l2_dv_timings *timings); >+ int (*vidioc_g_dv_timings) (struct file *file, void *fh, >+ struct v4l2_dv_timings *timings); >+ > /* For other private ioctls */ > long (*vidioc_default) (struct file *file, void *fh, > int cmd, void *arg); >diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h >index 88c13d6..92634da 100644 >--- a/include/media/v4l2-subdev.h >+++ b/include/media/v4l2-subdev.h >@@ -217,6 +217,19 @@ struct v4l2_subdev_audio_ops { > > s_routing: see s_routing in audio_ops, except this version is for video > devices. >+ >+ s_dv_preset: set dv (Digital Video) preset in the sub device. Similar >to >+ s_std() >+ >+ query_dv_preset: query dv preset in the sub device. This is similar to >+ querystd() >+ >+ s_dv_timings(): Set custom dv timings in the sub device. This is used >+ when sub device is capable of setting detailed timing information >+ in the hardware to generate/detect the video signal. >+ >+ g_dv_timings(): Get custom dv timings in the sub device. >+ > */ > struct v4l2_subdev_video_ops { > int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 >config); >@@ -240,6 +253,14 @@ struct v4l2_subdev_video_ops { > int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); > int (*enum_framesizes)(struct v4l2_subdev *sd, struct >v4l2_frmsizeenum *fsize); > int (*enum_frameintervals)(struct v4l2_subdev *sd, struct >v4l2_frmivalenum *fival); >+ int (*s_dv_preset)(struct v4l2_subdev *sd, >+ struct v4l2_dv_preset *preset); >+ int (*query_dv_preset)(struct v4l2_subdev *sd, >+ struct v4l2_dv_preset *preset); >+ int (*s_dv_timings)(struct v4l2_subdev *sd, >+ struct v4l2_dv_timings *timings); >+ int (*g_dv_timings)(struct v4l2_subdev *sd, >+ struct v4l2_dv_timings *timings); > }; > > /* >-- >1.6.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html