diff options
author | Muralidharan Karicheri <m-karicheri2@ti.com> | 2009-11-19 10:00:31 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-12-15 21:18:03 -0500 |
commit | b6456c0cfe9d94e6d2bf684e6e6c031fc0b10031 (patch) | |
tree | e5742dc96ec8b2a74708787e6cb4ceefcc3e2bac /drivers/media/video/v4l2-ioctl.c | |
parent | 20d15a200d34cfb7141fb4558895d7d5233db84b (diff) |
V4L/DVB (13571): v4l: Adding Digital Video Timings APIs
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 :-
Blu-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.
- Tested on 64bit platform by Hans Verkuil
Signed-off-by: Muralidharan Karicheri <m-karicheri2@ti.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Reviewed-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/v4l2-ioctl.c')
-rw-r--r-- | drivers/media/video/v4l2-ioctl.c | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 30cc3347ae52..4b11257c3184 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c | |||
@@ -284,6 +284,12 @@ static const char *v4l2_ioctls[] = { | |||
284 | [_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT", | 284 | [_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT", |
285 | [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK", | 285 | [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK", |
286 | #endif | 286 | #endif |
287 | [_IOC_NR(VIDIOC_ENUM_DV_PRESETS)] = "VIDIOC_ENUM_DV_PRESETS", | ||
288 | [_IOC_NR(VIDIOC_S_DV_PRESET)] = "VIDIOC_S_DV_PRESET", | ||
289 | [_IOC_NR(VIDIOC_G_DV_PRESET)] = "VIDIOC_G_DV_PRESET", | ||
290 | [_IOC_NR(VIDIOC_QUERY_DV_PRESET)] = "VIDIOC_QUERY_DV_PRESET", | ||
291 | [_IOC_NR(VIDIOC_S_DV_TIMINGS)] = "VIDIOC_S_DV_TIMINGS", | ||
292 | [_IOC_NR(VIDIOC_G_DV_TIMINGS)] = "VIDIOC_G_DV_TIMINGS", | ||
287 | }; | 293 | }; |
288 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) | 294 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) |
289 | 295 | ||
@@ -1135,6 +1141,19 @@ static long __video_do_ioctl(struct file *file, | |||
1135 | { | 1141 | { |
1136 | struct v4l2_input *p = arg; | 1142 | struct v4l2_input *p = arg; |
1137 | 1143 | ||
1144 | /* | ||
1145 | * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS & | ||
1146 | * CAP_STD here based on ioctl handler provided by the | ||
1147 | * driver. If the driver doesn't support these | ||
1148 | * for a specific input, it must override these flags. | ||
1149 | */ | ||
1150 | if (ops->vidioc_s_std) | ||
1151 | p->capabilities |= V4L2_IN_CAP_STD; | ||
1152 | if (ops->vidioc_s_dv_preset) | ||
1153 | p->capabilities |= V4L2_IN_CAP_PRESETS; | ||
1154 | if (ops->vidioc_s_dv_timings) | ||
1155 | p->capabilities |= V4L2_IN_CAP_CUSTOM_TIMINGS; | ||
1156 | |||
1138 | if (!ops->vidioc_enum_input) | 1157 | if (!ops->vidioc_enum_input) |
1139 | break; | 1158 | break; |
1140 | 1159 | ||
@@ -1179,6 +1198,19 @@ static long __video_do_ioctl(struct file *file, | |||
1179 | if (!ops->vidioc_enum_output) | 1198 | if (!ops->vidioc_enum_output) |
1180 | break; | 1199 | break; |
1181 | 1200 | ||
1201 | /* | ||
1202 | * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS & | ||
1203 | * CAP_STD here based on ioctl handler provided by the | ||
1204 | * driver. If the driver doesn't support these | ||
1205 | * for a specific output, it must override these flags. | ||
1206 | */ | ||
1207 | if (ops->vidioc_s_std) | ||
1208 | p->capabilities |= V4L2_OUT_CAP_STD; | ||
1209 | if (ops->vidioc_s_dv_preset) | ||
1210 | p->capabilities |= V4L2_OUT_CAP_PRESETS; | ||
1211 | if (ops->vidioc_s_dv_timings) | ||
1212 | p->capabilities |= V4L2_OUT_CAP_CUSTOM_TIMINGS; | ||
1213 | |||
1182 | ret = ops->vidioc_enum_output(file, fh, p); | 1214 | ret = ops->vidioc_enum_output(file, fh, p); |
1183 | if (!ret) | 1215 | if (!ret) |
1184 | dbgarg(cmd, "index=%d, name=%s, type=%d, " | 1216 | dbgarg(cmd, "index=%d, name=%s, type=%d, " |
@@ -1794,6 +1826,121 @@ static long __video_do_ioctl(struct file *file, | |||
1794 | } | 1826 | } |
1795 | break; | 1827 | break; |
1796 | } | 1828 | } |
1829 | case VIDIOC_ENUM_DV_PRESETS: | ||
1830 | { | ||
1831 | struct v4l2_dv_enum_preset *p = arg; | ||
1832 | |||
1833 | if (!ops->vidioc_enum_dv_presets) | ||
1834 | break; | ||
1835 | |||
1836 | ret = ops->vidioc_enum_dv_presets(file, fh, p); | ||
1837 | if (!ret) | ||
1838 | dbgarg(cmd, | ||
1839 | "index=%d, preset=%d, name=%s, width=%d," | ||
1840 | " height=%d ", | ||
1841 | p->index, p->preset, p->name, p->width, | ||
1842 | p->height); | ||
1843 | break; | ||
1844 | } | ||
1845 | case VIDIOC_S_DV_PRESET: | ||
1846 | { | ||
1847 | struct v4l2_dv_preset *p = arg; | ||
1848 | |||
1849 | if (!ops->vidioc_s_dv_preset) | ||
1850 | break; | ||
1851 | |||
1852 | dbgarg(cmd, "preset=%d\n", p->preset); | ||
1853 | ret = ops->vidioc_s_dv_preset(file, fh, p); | ||
1854 | break; | ||
1855 | } | ||
1856 | case VIDIOC_G_DV_PRESET: | ||
1857 | { | ||
1858 | struct v4l2_dv_preset *p = arg; | ||
1859 | |||
1860 | if (!ops->vidioc_g_dv_preset) | ||
1861 | break; | ||
1862 | |||
1863 | ret = ops->vidioc_g_dv_preset(file, fh, p); | ||
1864 | if (!ret) | ||
1865 | dbgarg(cmd, "preset=%d\n", p->preset); | ||
1866 | break; | ||
1867 | } | ||
1868 | case VIDIOC_QUERY_DV_PRESET: | ||
1869 | { | ||
1870 | struct v4l2_dv_preset *p = arg; | ||
1871 | |||
1872 | if (!ops->vidioc_query_dv_preset) | ||
1873 | break; | ||
1874 | |||
1875 | ret = ops->vidioc_query_dv_preset(file, fh, p); | ||
1876 | if (!ret) | ||
1877 | dbgarg(cmd, "preset=%d\n", p->preset); | ||
1878 | break; | ||
1879 | } | ||
1880 | case VIDIOC_S_DV_TIMINGS: | ||
1881 | { | ||
1882 | struct v4l2_dv_timings *p = arg; | ||
1883 | |||
1884 | if (!ops->vidioc_s_dv_timings) | ||
1885 | break; | ||
1886 | |||
1887 | switch (p->type) { | ||
1888 | case V4L2_DV_BT_656_1120: | ||
1889 | dbgarg2("bt-656/1120:interlaced=%d, pixelclock=%lld," | ||
1890 | " width=%d, height=%d, polarities=%x," | ||
1891 | " hfrontporch=%d, hsync=%d, hbackporch=%d," | ||
1892 | " vfrontporch=%d, vsync=%d, vbackporch=%d," | ||
1893 | " il_vfrontporch=%d, il_vsync=%d," | ||
1894 | " il_vbackporch=%d\n", | ||
1895 | p->bt.interlaced, p->bt.pixelclock, | ||
1896 | p->bt.width, p->bt.height, p->bt.polarities, | ||
1897 | p->bt.hfrontporch, p->bt.hsync, | ||
1898 | p->bt.hbackporch, p->bt.vfrontporch, | ||
1899 | p->bt.vsync, p->bt.vbackporch, | ||
1900 | p->bt.il_vfrontporch, p->bt.il_vsync, | ||
1901 | p->bt.il_vbackporch); | ||
1902 | ret = ops->vidioc_s_dv_timings(file, fh, p); | ||
1903 | break; | ||
1904 | default: | ||
1905 | dbgarg2("Unknown type %d!\n", p->type); | ||
1906 | break; | ||
1907 | } | ||
1908 | break; | ||
1909 | } | ||
1910 | case VIDIOC_G_DV_TIMINGS: | ||
1911 | { | ||
1912 | struct v4l2_dv_timings *p = arg; | ||
1913 | |||
1914 | if (!ops->vidioc_g_dv_timings) | ||
1915 | break; | ||
1916 | |||
1917 | ret = ops->vidioc_g_dv_timings(file, fh, p); | ||
1918 | if (!ret) { | ||
1919 | switch (p->type) { | ||
1920 | case V4L2_DV_BT_656_1120: | ||
1921 | dbgarg2("bt-656/1120:interlaced=%d," | ||
1922 | " pixelclock=%lld," | ||
1923 | " width=%d, height=%d, polarities=%x," | ||
1924 | " hfrontporch=%d, hsync=%d," | ||
1925 | " hbackporch=%d, vfrontporch=%d," | ||
1926 | " vsync=%d, vbackporch=%d," | ||
1927 | " il_vfrontporch=%d, il_vsync=%d," | ||
1928 | " il_vbackporch=%d\n", | ||
1929 | p->bt.interlaced, p->bt.pixelclock, | ||
1930 | p->bt.width, p->bt.height, | ||
1931 | p->bt.polarities, p->bt.hfrontporch, | ||
1932 | p->bt.hsync, p->bt.hbackporch, | ||
1933 | p->bt.vfrontporch, p->bt.vsync, | ||
1934 | p->bt.vbackporch, p->bt.il_vfrontporch, | ||
1935 | p->bt.il_vsync, p->bt.il_vbackporch); | ||
1936 | break; | ||
1937 | default: | ||
1938 | dbgarg2("Unknown type %d!\n", p->type); | ||
1939 | break; | ||
1940 | } | ||
1941 | } | ||
1942 | break; | ||
1943 | } | ||
1797 | 1944 | ||
1798 | default: | 1945 | default: |
1799 | { | 1946 | { |