diff mbox

V4L: adding digital video timings APIs

Message ID 1256164939-21803-1-git-send-email-m-karicheri2@ti.com (mailing list archive)
State RFC
Headers show

Commit Message

Murali Karicheri Oct. 21, 2009, 10:42 p.m. UTC
None
diff mbox

Patch

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..10b5678 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)
 
@@ -1794,6 +1800,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 469dbd0..3436d4a 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -730,6 +730,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 {
@@ -740,7 +853,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 */
@@ -771,6 +885,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
  */
@@ -781,13 +900,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
  */
@@ -1620,6 +1745,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 d411345..cedcc72 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -206,6 +206,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);
@@ -229,6 +242,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);
 };
 
 struct v4l2_subdev_ops {