diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-05-15 07:06:44 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-20 07:22:30 -0400 |
commit | 5d7758eed2307f7b9934c6b64fbdbfaab52e436d (patch) | |
tree | 6f0405a3da7a7463b81e65a9fc9475492c75db24 | |
parent | 7dcc606b2a980222d9816d092a5c20b7c98cbd1a (diff) |
[media] v4l2 framework: add support for the new dv_timings ioctls
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Reviewed-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/v4l2-compat-ioctl32.c | 3 | ||||
-rw-r--r-- | drivers/media/video/v4l2-ioctl.c | 126 | ||||
-rw-r--r-- | include/media/v4l2-ioctl.h | 6 | ||||
-rw-r--r-- | include/media/v4l2-subdev.h | 6 |
4 files changed, 104 insertions, 37 deletions
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c index 89ae433877e6..5327ad3a6390 100644 --- a/drivers/media/video/v4l2-compat-ioctl32.c +++ b/drivers/media/video/v4l2-compat-ioctl32.c | |||
@@ -1023,6 +1023,9 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) | |||
1023 | case VIDIOC_UNSUBSCRIBE_EVENT: | 1023 | case VIDIOC_UNSUBSCRIBE_EVENT: |
1024 | case VIDIOC_CREATE_BUFS32: | 1024 | case VIDIOC_CREATE_BUFS32: |
1025 | case VIDIOC_PREPARE_BUF32: | 1025 | case VIDIOC_PREPARE_BUF32: |
1026 | case VIDIOC_ENUM_DV_TIMINGS: | ||
1027 | case VIDIOC_QUERY_DV_TIMINGS: | ||
1028 | case VIDIOC_DV_TIMINGS_CAP: | ||
1026 | ret = do_video_ioctl(file, cmd, arg); | 1029 | ret = do_video_ioctl(file, cmd, arg); |
1027 | break; | 1030 | break; |
1028 | 1031 | ||
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 623d280ce095..91be4e871f43 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c | |||
@@ -281,6 +281,9 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = { | |||
281 | IOCTL_INFO(VIDIOC_UNSUBSCRIBE_EVENT, 0), | 281 | IOCTL_INFO(VIDIOC_UNSUBSCRIBE_EVENT, 0), |
282 | IOCTL_INFO(VIDIOC_CREATE_BUFS, INFO_FL_PRIO), | 282 | IOCTL_INFO(VIDIOC_CREATE_BUFS, INFO_FL_PRIO), |
283 | IOCTL_INFO(VIDIOC_PREPARE_BUF, 0), | 283 | IOCTL_INFO(VIDIOC_PREPARE_BUF, 0), |
284 | IOCTL_INFO(VIDIOC_ENUM_DV_TIMINGS, 0), | ||
285 | IOCTL_INFO(VIDIOC_QUERY_DV_TIMINGS, 0), | ||
286 | IOCTL_INFO(VIDIOC_DV_TIMINGS_CAP, 0), | ||
284 | }; | 287 | }; |
285 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) | 288 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) |
286 | 289 | ||
@@ -368,6 +371,34 @@ static inline void dbgrect(struct video_device *vfd, char *s, | |||
368 | r->width, r->height); | 371 | r->width, r->height); |
369 | }; | 372 | }; |
370 | 373 | ||
374 | static void dbgtimings(struct video_device *vfd, | ||
375 | const struct v4l2_dv_timings *p) | ||
376 | { | ||
377 | switch (p->type) { | ||
378 | case V4L2_DV_BT_656_1120: | ||
379 | dbgarg2("bt-656/1120:interlaced=%d," | ||
380 | " pixelclock=%lld," | ||
381 | " width=%d, height=%d, polarities=%x," | ||
382 | " hfrontporch=%d, hsync=%d," | ||
383 | " hbackporch=%d, vfrontporch=%d," | ||
384 | " vsync=%d, vbackporch=%d," | ||
385 | " il_vfrontporch=%d, il_vsync=%d," | ||
386 | " il_vbackporch=%d, standards=%x, flags=%x\n", | ||
387 | p->bt.interlaced, p->bt.pixelclock, | ||
388 | p->bt.width, p->bt.height, | ||
389 | p->bt.polarities, p->bt.hfrontporch, | ||
390 | p->bt.hsync, p->bt.hbackporch, | ||
391 | p->bt.vfrontporch, p->bt.vsync, | ||
392 | p->bt.vbackporch, p->bt.il_vfrontporch, | ||
393 | p->bt.il_vsync, p->bt.il_vbackporch, | ||
394 | p->bt.standards, p->bt.flags); | ||
395 | break; | ||
396 | default: | ||
397 | dbgarg2("Unknown type %d!\n", p->type); | ||
398 | break; | ||
399 | } | ||
400 | } | ||
401 | |||
371 | static inline void v4l_print_pix_fmt(struct video_device *vfd, | 402 | static inline void v4l_print_pix_fmt(struct video_device *vfd, |
372 | struct v4l2_pix_format *fmt) | 403 | struct v4l2_pix_format *fmt) |
373 | { | 404 | { |
@@ -1916,25 +1947,13 @@ static long __video_do_ioctl(struct file *file, | |||
1916 | { | 1947 | { |
1917 | struct v4l2_dv_timings *p = arg; | 1948 | struct v4l2_dv_timings *p = arg; |
1918 | 1949 | ||
1950 | dbgtimings(vfd, p); | ||
1919 | switch (p->type) { | 1951 | switch (p->type) { |
1920 | case V4L2_DV_BT_656_1120: | 1952 | case V4L2_DV_BT_656_1120: |
1921 | dbgarg2("bt-656/1120:interlaced=%d, pixelclock=%lld," | ||
1922 | " width=%d, height=%d, polarities=%x," | ||
1923 | " hfrontporch=%d, hsync=%d, hbackporch=%d," | ||
1924 | " vfrontporch=%d, vsync=%d, vbackporch=%d," | ||
1925 | " il_vfrontporch=%d, il_vsync=%d," | ||
1926 | " il_vbackporch=%d\n", | ||
1927 | p->bt.interlaced, p->bt.pixelclock, | ||
1928 | p->bt.width, p->bt.height, p->bt.polarities, | ||
1929 | p->bt.hfrontporch, p->bt.hsync, | ||
1930 | p->bt.hbackporch, p->bt.vfrontporch, | ||
1931 | p->bt.vsync, p->bt.vbackporch, | ||
1932 | p->bt.il_vfrontporch, p->bt.il_vsync, | ||
1933 | p->bt.il_vbackporch); | ||
1934 | ret = ops->vidioc_s_dv_timings(file, fh, p); | 1953 | ret = ops->vidioc_s_dv_timings(file, fh, p); |
1935 | break; | 1954 | break; |
1936 | default: | 1955 | default: |
1937 | dbgarg2("Unknown type %d!\n", p->type); | 1956 | ret = -EINVAL; |
1938 | break; | 1957 | break; |
1939 | } | 1958 | } |
1940 | break; | 1959 | break; |
@@ -1944,29 +1963,60 @@ static long __video_do_ioctl(struct file *file, | |||
1944 | struct v4l2_dv_timings *p = arg; | 1963 | struct v4l2_dv_timings *p = arg; |
1945 | 1964 | ||
1946 | ret = ops->vidioc_g_dv_timings(file, fh, p); | 1965 | ret = ops->vidioc_g_dv_timings(file, fh, p); |
1966 | if (!ret) | ||
1967 | dbgtimings(vfd, p); | ||
1968 | break; | ||
1969 | } | ||
1970 | case VIDIOC_ENUM_DV_TIMINGS: | ||
1971 | { | ||
1972 | struct v4l2_enum_dv_timings *p = arg; | ||
1973 | |||
1974 | if (!ops->vidioc_enum_dv_timings) | ||
1975 | break; | ||
1976 | |||
1977 | ret = ops->vidioc_enum_dv_timings(file, fh, p); | ||
1947 | if (!ret) { | 1978 | if (!ret) { |
1948 | switch (p->type) { | 1979 | dbgarg(cmd, "index=%d: ", p->index); |
1949 | case V4L2_DV_BT_656_1120: | 1980 | dbgtimings(vfd, &p->timings); |
1950 | dbgarg2("bt-656/1120:interlaced=%d," | 1981 | } |
1951 | " pixelclock=%lld," | 1982 | break; |
1952 | " width=%d, height=%d, polarities=%x," | 1983 | } |
1953 | " hfrontporch=%d, hsync=%d," | 1984 | case VIDIOC_QUERY_DV_TIMINGS: |
1954 | " hbackporch=%d, vfrontporch=%d," | 1985 | { |
1955 | " vsync=%d, vbackporch=%d," | 1986 | struct v4l2_dv_timings *p = arg; |
1956 | " il_vfrontporch=%d, il_vsync=%d," | 1987 | |
1957 | " il_vbackporch=%d\n", | 1988 | if (!ops->vidioc_query_dv_timings) |
1958 | p->bt.interlaced, p->bt.pixelclock, | 1989 | break; |
1959 | p->bt.width, p->bt.height, | 1990 | |
1960 | p->bt.polarities, p->bt.hfrontporch, | 1991 | ret = ops->vidioc_query_dv_timings(file, fh, p); |
1961 | p->bt.hsync, p->bt.hbackporch, | 1992 | if (!ret) |
1962 | p->bt.vfrontporch, p->bt.vsync, | 1993 | dbgtimings(vfd, p); |
1963 | p->bt.vbackporch, p->bt.il_vfrontporch, | 1994 | break; |
1964 | p->bt.il_vsync, p->bt.il_vbackporch); | 1995 | } |
1965 | break; | 1996 | case VIDIOC_DV_TIMINGS_CAP: |
1966 | default: | 1997 | { |
1967 | dbgarg2("Unknown type %d!\n", p->type); | 1998 | struct v4l2_dv_timings_cap *p = arg; |
1968 | break; | 1999 | |
1969 | } | 2000 | if (!ops->vidioc_dv_timings_cap) |
2001 | break; | ||
2002 | |||
2003 | ret = ops->vidioc_dv_timings_cap(file, fh, p); | ||
2004 | if (ret) | ||
2005 | break; | ||
2006 | switch (p->type) { | ||
2007 | case V4L2_DV_BT_656_1120: | ||
2008 | dbgarg(cmd, | ||
2009 | "type=%d, width=%u-%u, height=%u-%u, " | ||
2010 | "pixelclock=%llu-%llu, standards=%x, capabilities=%x ", | ||
2011 | p->type, | ||
2012 | p->bt.min_width, p->bt.max_width, | ||
2013 | p->bt.min_height, p->bt.max_height, | ||
2014 | p->bt.min_pixelclock, p->bt.max_pixelclock, | ||
2015 | p->bt.standards, p->bt.capabilities); | ||
2016 | break; | ||
2017 | default: | ||
2018 | dbgarg(cmd, "unknown type "); | ||
2019 | break; | ||
1970 | } | 2020 | } |
1971 | break; | 2021 | break; |
1972 | } | 2022 | } |
@@ -2215,7 +2265,9 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg, | |||
2215 | err = -EFAULT; | 2265 | err = -EFAULT; |
2216 | goto out_array_args; | 2266 | goto out_array_args; |
2217 | } | 2267 | } |
2218 | if (err < 0) | 2268 | /* VIDIOC_QUERY_DV_TIMINGS can return an error, but still have valid |
2269 | results that must be returned. */ | ||
2270 | if (err < 0 && cmd != VIDIOC_QUERY_DV_TIMINGS) | ||
2219 | goto out; | 2271 | goto out; |
2220 | 2272 | ||
2221 | out_array_args: | 2273 | out_array_args: |
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index 3cb939cd03f9..d8b76f7392f8 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h | |||
@@ -271,6 +271,12 @@ struct v4l2_ioctl_ops { | |||
271 | struct v4l2_dv_timings *timings); | 271 | struct v4l2_dv_timings *timings); |
272 | int (*vidioc_g_dv_timings) (struct file *file, void *fh, | 272 | int (*vidioc_g_dv_timings) (struct file *file, void *fh, |
273 | struct v4l2_dv_timings *timings); | 273 | struct v4l2_dv_timings *timings); |
274 | int (*vidioc_query_dv_timings) (struct file *file, void *fh, | ||
275 | struct v4l2_dv_timings *timings); | ||
276 | int (*vidioc_enum_dv_timings) (struct file *file, void *fh, | ||
277 | struct v4l2_enum_dv_timings *timings); | ||
278 | int (*vidioc_dv_timings_cap) (struct file *file, void *fh, | ||
279 | struct v4l2_dv_timings_cap *cap); | ||
274 | 280 | ||
275 | int (*vidioc_subscribe_event) (struct v4l2_fh *fh, | 281 | int (*vidioc_subscribe_event) (struct v4l2_fh *fh, |
276 | struct v4l2_event_subscription *sub); | 282 | struct v4l2_event_subscription *sub); |
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 1c2318b15bd2..c35a3545e273 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h | |||
@@ -307,6 +307,12 @@ struct v4l2_subdev_video_ops { | |||
307 | struct v4l2_dv_timings *timings); | 307 | struct v4l2_dv_timings *timings); |
308 | int (*g_dv_timings)(struct v4l2_subdev *sd, | 308 | int (*g_dv_timings)(struct v4l2_subdev *sd, |
309 | struct v4l2_dv_timings *timings); | 309 | struct v4l2_dv_timings *timings); |
310 | int (*enum_dv_timings)(struct v4l2_subdev *sd, | ||
311 | struct v4l2_enum_dv_timings *timings); | ||
312 | int (*query_dv_timings)(struct v4l2_subdev *sd, | ||
313 | struct v4l2_dv_timings *timings); | ||
314 | int (*dv_timings_cap)(struct v4l2_subdev *sd, | ||
315 | struct v4l2_dv_timings_cap *cap); | ||
310 | int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index, | 316 | int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index, |
311 | enum v4l2_mbus_pixelcode *code); | 317 | enum v4l2_mbus_pixelcode *code); |
312 | int (*enum_mbus_fsizes)(struct v4l2_subdev *sd, | 318 | int (*enum_mbus_fsizes)(struct v4l2_subdev *sd, |