diff options
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-ioctl.c')
-rw-r--r-- | drivers/media/v4l2-core/v4l2-ioctl.c | 91 |
1 files changed, 77 insertions, 14 deletions
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 707aef705a47..d9113cc71c77 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c | |||
@@ -152,6 +152,7 @@ const char *v4l2_type_names[] = { | |||
152 | [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay", | 152 | [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay", |
153 | [V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane", | 153 | [V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane", |
154 | [V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane", | 154 | [V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane", |
155 | [V4L2_BUF_TYPE_SDR_CAPTURE] = "sdr-cap", | ||
155 | }; | 156 | }; |
156 | EXPORT_SYMBOL(v4l2_type_names); | 157 | EXPORT_SYMBOL(v4l2_type_names); |
157 | 158 | ||
@@ -245,6 +246,7 @@ static void v4l_print_format(const void *arg, bool write_only) | |||
245 | const struct v4l2_vbi_format *vbi; | 246 | const struct v4l2_vbi_format *vbi; |
246 | const struct v4l2_sliced_vbi_format *sliced; | 247 | const struct v4l2_sliced_vbi_format *sliced; |
247 | const struct v4l2_window *win; | 248 | const struct v4l2_window *win; |
249 | const struct v4l2_sdr_format *sdr; | ||
248 | unsigned i; | 250 | unsigned i; |
249 | 251 | ||
250 | pr_cont("type=%s", prt_names(p->type, v4l2_type_names)); | 252 | pr_cont("type=%s", prt_names(p->type, v4l2_type_names)); |
@@ -318,6 +320,14 @@ static void v4l_print_format(const void *arg, bool write_only) | |||
318 | sliced->service_lines[0][i], | 320 | sliced->service_lines[0][i], |
319 | sliced->service_lines[1][i]); | 321 | sliced->service_lines[1][i]); |
320 | break; | 322 | break; |
323 | case V4L2_BUF_TYPE_SDR_CAPTURE: | ||
324 | sdr = &p->fmt.sdr; | ||
325 | pr_cont(", pixelformat=%c%c%c%c\n", | ||
326 | (sdr->pixelformat >> 0) & 0xff, | ||
327 | (sdr->pixelformat >> 8) & 0xff, | ||
328 | (sdr->pixelformat >> 16) & 0xff, | ||
329 | (sdr->pixelformat >> 24) & 0xff); | ||
330 | break; | ||
321 | } | 331 | } |
322 | } | 332 | } |
323 | 333 | ||
@@ -834,6 +844,14 @@ static void v4l_print_freq_band(const void *arg, bool write_only) | |||
834 | p->rangehigh, p->modulation); | 844 | p->rangehigh, p->modulation); |
835 | } | 845 | } |
836 | 846 | ||
847 | static void v4l_print_edid(const void *arg, bool write_only) | ||
848 | { | ||
849 | const struct v4l2_edid *p = arg; | ||
850 | |||
851 | pr_cont("pad=%u, start_block=%u, blocks=%u\n", | ||
852 | p->pad, p->start_block, p->blocks); | ||
853 | } | ||
854 | |||
837 | static void v4l_print_u32(const void *arg, bool write_only) | 855 | static void v4l_print_u32(const void *arg, bool write_only) |
838 | { | 856 | { |
839 | pr_cont("value=%u\n", *(const u32 *)arg); | 857 | pr_cont("value=%u\n", *(const u32 *)arg); |
@@ -881,6 +899,7 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type) | |||
881 | const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; | 899 | const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; |
882 | bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER; | 900 | bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER; |
883 | bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI; | 901 | bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI; |
902 | bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; | ||
884 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; | 903 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; |
885 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; | 904 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; |
886 | 905 | ||
@@ -930,6 +949,10 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type) | |||
930 | if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out) | 949 | if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out) |
931 | return 0; | 950 | return 0; |
932 | break; | 951 | break; |
952 | case V4L2_BUF_TYPE_SDR_CAPTURE: | ||
953 | if (is_sdr && is_rx && ops->vidioc_g_fmt_sdr_cap) | ||
954 | return 0; | ||
955 | break; | ||
933 | default: | 956 | default: |
934 | break; | 957 | break; |
935 | } | 958 | } |
@@ -1049,6 +1072,10 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops, | |||
1049 | if (unlikely(!is_tx || !ops->vidioc_enum_fmt_vid_out_mplane)) | 1072 | if (unlikely(!is_tx || !ops->vidioc_enum_fmt_vid_out_mplane)) |
1050 | break; | 1073 | break; |
1051 | return ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg); | 1074 | return ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg); |
1075 | case V4L2_BUF_TYPE_SDR_CAPTURE: | ||
1076 | if (unlikely(!is_rx || !ops->vidioc_enum_fmt_sdr_cap)) | ||
1077 | break; | ||
1078 | return ops->vidioc_enum_fmt_sdr_cap(file, fh, arg); | ||
1052 | } | 1079 | } |
1053 | return -EINVAL; | 1080 | return -EINVAL; |
1054 | } | 1081 | } |
@@ -1059,6 +1086,7 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops, | |||
1059 | struct v4l2_format *p = arg; | 1086 | struct v4l2_format *p = arg; |
1060 | struct video_device *vfd = video_devdata(file); | 1087 | struct video_device *vfd = video_devdata(file); |
1061 | bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER; | 1088 | bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER; |
1089 | bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; | ||
1062 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; | 1090 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; |
1063 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; | 1091 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; |
1064 | 1092 | ||
@@ -1103,6 +1131,10 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops, | |||
1103 | if (unlikely(!is_tx || is_vid || !ops->vidioc_g_fmt_sliced_vbi_out)) | 1131 | if (unlikely(!is_tx || is_vid || !ops->vidioc_g_fmt_sliced_vbi_out)) |
1104 | break; | 1132 | break; |
1105 | return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg); | 1133 | return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg); |
1134 | case V4L2_BUF_TYPE_SDR_CAPTURE: | ||
1135 | if (unlikely(!is_rx || !is_sdr || !ops->vidioc_g_fmt_sdr_cap)) | ||
1136 | break; | ||
1137 | return ops->vidioc_g_fmt_sdr_cap(file, fh, arg); | ||
1106 | } | 1138 | } |
1107 | return -EINVAL; | 1139 | return -EINVAL; |
1108 | } | 1140 | } |
@@ -1113,6 +1145,7 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops, | |||
1113 | struct v4l2_format *p = arg; | 1145 | struct v4l2_format *p = arg; |
1114 | struct video_device *vfd = video_devdata(file); | 1146 | struct video_device *vfd = video_devdata(file); |
1115 | bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER; | 1147 | bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER; |
1148 | bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; | ||
1116 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; | 1149 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; |
1117 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; | 1150 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; |
1118 | 1151 | ||
@@ -1167,6 +1200,11 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops, | |||
1167 | break; | 1200 | break; |
1168 | CLEAR_AFTER_FIELD(p, fmt.sliced); | 1201 | CLEAR_AFTER_FIELD(p, fmt.sliced); |
1169 | return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg); | 1202 | return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg); |
1203 | case V4L2_BUF_TYPE_SDR_CAPTURE: | ||
1204 | if (unlikely(!is_rx || !is_sdr || !ops->vidioc_s_fmt_sdr_cap)) | ||
1205 | break; | ||
1206 | CLEAR_AFTER_FIELD(p, fmt.sdr); | ||
1207 | return ops->vidioc_s_fmt_sdr_cap(file, fh, arg); | ||
1170 | } | 1208 | } |
1171 | return -EINVAL; | 1209 | return -EINVAL; |
1172 | } | 1210 | } |
@@ -1177,6 +1215,7 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops, | |||
1177 | struct v4l2_format *p = arg; | 1215 | struct v4l2_format *p = arg; |
1178 | struct video_device *vfd = video_devdata(file); | 1216 | struct video_device *vfd = video_devdata(file); |
1179 | bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER; | 1217 | bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER; |
1218 | bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; | ||
1180 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; | 1219 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; |
1181 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; | 1220 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; |
1182 | 1221 | ||
@@ -1231,6 +1270,11 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops, | |||
1231 | break; | 1270 | break; |
1232 | CLEAR_AFTER_FIELD(p, fmt.sliced); | 1271 | CLEAR_AFTER_FIELD(p, fmt.sliced); |
1233 | return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg); | 1272 | return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg); |
1273 | case V4L2_BUF_TYPE_SDR_CAPTURE: | ||
1274 | if (unlikely(!is_rx || !is_sdr || !ops->vidioc_try_fmt_sdr_cap)) | ||
1275 | break; | ||
1276 | CLEAR_AFTER_FIELD(p, fmt.sdr); | ||
1277 | return ops->vidioc_try_fmt_sdr_cap(file, fh, arg); | ||
1234 | } | 1278 | } |
1235 | return -EINVAL; | 1279 | return -EINVAL; |
1236 | } | 1280 | } |
@@ -1291,8 +1335,11 @@ static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops, | |||
1291 | struct video_device *vfd = video_devdata(file); | 1335 | struct video_device *vfd = video_devdata(file); |
1292 | struct v4l2_frequency *p = arg; | 1336 | struct v4l2_frequency *p = arg; |
1293 | 1337 | ||
1294 | p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? | 1338 | if (vfd->vfl_type == VFL_TYPE_SDR) |
1295 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | 1339 | p->type = V4L2_TUNER_ADC; |
1340 | else | ||
1341 | p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? | ||
1342 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
1296 | return ops->vidioc_g_frequency(file, fh, p); | 1343 | return ops->vidioc_g_frequency(file, fh, p); |
1297 | } | 1344 | } |
1298 | 1345 | ||
@@ -1303,10 +1350,15 @@ static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops, | |||
1303 | const struct v4l2_frequency *p = arg; | 1350 | const struct v4l2_frequency *p = arg; |
1304 | enum v4l2_tuner_type type; | 1351 | enum v4l2_tuner_type type; |
1305 | 1352 | ||
1306 | type = (vfd->vfl_type == VFL_TYPE_RADIO) ? | 1353 | if (vfd->vfl_type == VFL_TYPE_SDR) { |
1307 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | 1354 | if (p->type != V4L2_TUNER_ADC && p->type != V4L2_TUNER_RF) |
1308 | if (p->type != type) | 1355 | return -EINVAL; |
1309 | return -EINVAL; | 1356 | } else { |
1357 | type = (vfd->vfl_type == VFL_TYPE_RADIO) ? | ||
1358 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
1359 | if (type != p->type) | ||
1360 | return -EINVAL; | ||
1361 | } | ||
1310 | return ops->vidioc_s_frequency(file, fh, p); | 1362 | return ops->vidioc_s_frequency(file, fh, p); |
1311 | } | 1363 | } |
1312 | 1364 | ||
@@ -1386,6 +1438,10 @@ static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops, | |||
1386 | struct v4l2_hw_freq_seek *p = arg; | 1438 | struct v4l2_hw_freq_seek *p = arg; |
1387 | enum v4l2_tuner_type type; | 1439 | enum v4l2_tuner_type type; |
1388 | 1440 | ||
1441 | /* s_hw_freq_seek is not supported for SDR for now */ | ||
1442 | if (vfd->vfl_type == VFL_TYPE_SDR) | ||
1443 | return -EINVAL; | ||
1444 | |||
1389 | type = (vfd->vfl_type == VFL_TYPE_RADIO) ? | 1445 | type = (vfd->vfl_type == VFL_TYPE_RADIO) ? |
1390 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | 1446 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; |
1391 | if (p->type != type) | 1447 | if (p->type != type) |
@@ -1885,11 +1941,16 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops, | |||
1885 | enum v4l2_tuner_type type; | 1941 | enum v4l2_tuner_type type; |
1886 | int err; | 1942 | int err; |
1887 | 1943 | ||
1888 | type = (vfd->vfl_type == VFL_TYPE_RADIO) ? | 1944 | if (vfd->vfl_type == VFL_TYPE_SDR) { |
1889 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | 1945 | if (p->type != V4L2_TUNER_ADC && p->type != V4L2_TUNER_RF) |
1890 | 1946 | return -EINVAL; | |
1891 | if (type != p->type) | 1947 | type = p->type; |
1892 | return -EINVAL; | 1948 | } else { |
1949 | type = (vfd->vfl_type == VFL_TYPE_RADIO) ? | ||
1950 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
1951 | if (type != p->type) | ||
1952 | return -EINVAL; | ||
1953 | } | ||
1893 | if (ops->vidioc_enum_freq_bands) | 1954 | if (ops->vidioc_enum_freq_bands) |
1894 | return ops->vidioc_enum_freq_bands(file, fh, p); | 1955 | return ops->vidioc_enum_freq_bands(file, fh, p); |
1895 | if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) { | 1956 | if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) { |
@@ -2009,6 +2070,8 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = { | |||
2009 | IOCTL_INFO_FNC(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)), | 2070 | IOCTL_INFO_FNC(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)), |
2010 | IOCTL_INFO_STD(VIDIOC_G_INPUT, vidioc_g_input, v4l_print_u32, 0), | 2071 | IOCTL_INFO_STD(VIDIOC_G_INPUT, vidioc_g_input, v4l_print_u32, 0), |
2011 | IOCTL_INFO_FNC(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO), | 2072 | IOCTL_INFO_FNC(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO), |
2073 | IOCTL_INFO_STD(VIDIOC_G_EDID, vidioc_g_edid, v4l_print_edid, INFO_FL_CLEAR(v4l2_edid, edid)), | ||
2074 | IOCTL_INFO_STD(VIDIOC_S_EDID, vidioc_s_edid, v4l_print_edid, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_edid, edid)), | ||
2012 | IOCTL_INFO_STD(VIDIOC_G_OUTPUT, vidioc_g_output, v4l_print_u32, 0), | 2075 | IOCTL_INFO_STD(VIDIOC_G_OUTPUT, vidioc_g_output, v4l_print_u32, 0), |
2013 | IOCTL_INFO_FNC(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO), | 2076 | IOCTL_INFO_FNC(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO), |
2014 | IOCTL_INFO_FNC(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)), | 2077 | IOCTL_INFO_FNC(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)), |
@@ -2221,9 +2284,9 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size, | |||
2221 | break; | 2284 | break; |
2222 | } | 2285 | } |
2223 | 2286 | ||
2224 | case VIDIOC_SUBDEV_G_EDID: | 2287 | case VIDIOC_G_EDID: |
2225 | case VIDIOC_SUBDEV_S_EDID: { | 2288 | case VIDIOC_S_EDID: { |
2226 | struct v4l2_subdev_edid *edid = parg; | 2289 | struct v4l2_edid *edid = parg; |
2227 | 2290 | ||
2228 | if (edid->blocks) { | 2291 | if (edid->blocks) { |
2229 | if (edid->blocks > 256) { | 2292 | if (edid->blocks > 256) { |