diff options
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-ioctl.c')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-ioctl.c | 191 |
1 files changed, 155 insertions, 36 deletions
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index dfe0aedc60fd..206eee7542db 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
@@ -25,8 +25,7 @@ | |||
25 | #include "ivtv-queue.h" | 25 | #include "ivtv-queue.h" |
26 | #include "ivtv-fileops.h" | 26 | #include "ivtv-fileops.h" |
27 | #include "ivtv-vbi.h" | 27 | #include "ivtv-vbi.h" |
28 | #include "ivtv-audio.h" | 28 | #include "ivtv-routing.h" |
29 | #include "ivtv-video.h" | ||
30 | #include "ivtv-streams.h" | 29 | #include "ivtv-streams.h" |
31 | #include "ivtv-yuv.h" | 30 | #include "ivtv-yuv.h" |
32 | #include "ivtv-ioctl.h" | 31 | #include "ivtv-ioctl.h" |
@@ -164,7 +163,7 @@ void ivtv_set_osd_alpha(struct ivtv *itv) | |||
164 | { | 163 | { |
165 | ivtv_vapi(itv, CX2341X_OSD_SET_GLOBAL_ALPHA, 3, | 164 | ivtv_vapi(itv, CX2341X_OSD_SET_GLOBAL_ALPHA, 3, |
166 | itv->osd_global_alpha_state, itv->osd_global_alpha, !itv->osd_local_alpha_state); | 165 | itv->osd_global_alpha_state, itv->osd_global_alpha, !itv->osd_local_alpha_state); |
167 | ivtv_vapi(itv, CX2341X_OSD_SET_CHROMA_KEY, 2, itv->osd_color_key_state, itv->osd_color_key); | 166 | ivtv_vapi(itv, CX2341X_OSD_SET_CHROMA_KEY, 2, itv->osd_chroma_key_state, itv->osd_chroma_key); |
168 | } | 167 | } |
169 | 168 | ||
170 | int ivtv_set_speed(struct ivtv *itv, int speed) | 169 | int ivtv_set_speed(struct ivtv *itv, int speed) |
@@ -427,7 +426,7 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm | |||
427 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: | 426 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: |
428 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | 427 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) |
429 | return -EINVAL; | 428 | return -EINVAL; |
430 | fmt->fmt.win.chromakey = itv->osd_color_key; | 429 | fmt->fmt.win.chromakey = itv->osd_chroma_key; |
431 | fmt->fmt.win.global_alpha = itv->osd_global_alpha; | 430 | fmt->fmt.win.global_alpha = itv->osd_global_alpha; |
432 | break; | 431 | break; |
433 | 432 | ||
@@ -547,7 +546,7 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype, | |||
547 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | 546 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) |
548 | return -EINVAL; | 547 | return -EINVAL; |
549 | if (set_fmt) { | 548 | if (set_fmt) { |
550 | itv->osd_color_key = fmt->fmt.win.chromakey; | 549 | itv->osd_chroma_key = fmt->fmt.win.chromakey; |
551 | itv->osd_global_alpha = fmt->fmt.win.global_alpha; | 550 | itv->osd_global_alpha = fmt->fmt.win.global_alpha; |
552 | ivtv_set_osd_alpha(itv); | 551 | ivtv_set_osd_alpha(itv); |
553 | } | 552 | } |
@@ -584,9 +583,7 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype, | |||
584 | 583 | ||
585 | /* set raw VBI format */ | 584 | /* set raw VBI format */ |
586 | if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | 585 | if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { |
587 | if (set_fmt && streamtype == IVTV_ENC_STREAM_TYPE_VBI && | 586 | if (set_fmt && atomic_read(&itv->capturing) > 0) { |
588 | itv->vbi.sliced_in->service_set && | ||
589 | atomic_read(&itv->capturing) > 0) { | ||
590 | return -EBUSY; | 587 | return -EBUSY; |
591 | } | 588 | } |
592 | if (set_fmt) { | 589 | if (set_fmt) { |
@@ -624,7 +621,7 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype, | |||
624 | return 0; | 621 | return 0; |
625 | if (set == 0) | 622 | if (set == 0) |
626 | return -EINVAL; | 623 | return -EINVAL; |
627 | if (atomic_read(&itv->capturing) > 0 && itv->vbi.sliced_in->service_set == 0) { | 624 | if (atomic_read(&itv->capturing) > 0) { |
628 | return -EBUSY; | 625 | return -EBUSY; |
629 | } | 626 | } |
630 | itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); | 627 | itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); |
@@ -677,13 +674,21 @@ static int ivtv_debug_ioctls(struct file *filp, unsigned int cmd, void *arg) | |||
677 | case VIDIOC_INT_S_AUDIO_ROUTING: { | 674 | case VIDIOC_INT_S_AUDIO_ROUTING: { |
678 | struct v4l2_routing *route = arg; | 675 | struct v4l2_routing *route = arg; |
679 | 676 | ||
680 | ivtv_audio_set_route(itv, route); | 677 | ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, route); |
681 | break; | 678 | break; |
682 | } | 679 | } |
683 | 680 | ||
684 | case VIDIOC_INT_RESET: | 681 | case VIDIOC_INT_RESET: { |
685 | ivtv_reset_ir_gpio(itv); | 682 | u32 val = *(u32 *)arg; |
683 | |||
684 | if ((val == 0 && itv->options.newi2c) || (val & 0x01)) { | ||
685 | ivtv_reset_ir_gpio(itv); | ||
686 | } | ||
687 | if (val & 0x02) { | ||
688 | itv->video_dec_func(itv, cmd, 0); | ||
689 | } | ||
686 | break; | 690 | break; |
691 | } | ||
687 | 692 | ||
688 | default: | 693 | default: |
689 | return -EINVAL; | 694 | return -EINVAL; |
@@ -694,6 +699,7 @@ static int ivtv_debug_ioctls(struct file *filp, unsigned int cmd, void *arg) | |||
694 | int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg) | 699 | int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg) |
695 | { | 700 | { |
696 | struct ivtv_open_id *id = NULL; | 701 | struct ivtv_open_id *id = NULL; |
702 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
697 | 703 | ||
698 | if (filp) id = (struct ivtv_open_id *)filp->private_data; | 704 | if (filp) id = (struct ivtv_open_id *)filp->private_data; |
699 | 705 | ||
@@ -898,6 +904,9 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
898 | IVTV_DEBUG_INFO("Input unchanged\n"); | 904 | IVTV_DEBUG_INFO("Input unchanged\n"); |
899 | break; | 905 | break; |
900 | } | 906 | } |
907 | if (atomic_read(&itv->capturing) > 0) { | ||
908 | return -EBUSY; | ||
909 | } | ||
901 | IVTV_DEBUG_INFO("Changing input from %d to %d\n", | 910 | IVTV_DEBUG_INFO("Changing input from %d to %d\n", |
902 | itv->active_input, inp); | 911 | itv->active_input, inp); |
903 | 912 | ||
@@ -1127,12 +1136,14 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
1127 | memset(&enc->raw, 0, sizeof(enc->raw)); | 1136 | memset(&enc->raw, 0, sizeof(enc->raw)); |
1128 | switch (enc->cmd) { | 1137 | switch (enc->cmd) { |
1129 | case V4L2_ENC_CMD_START: | 1138 | case V4L2_ENC_CMD_START: |
1139 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); | ||
1130 | enc->flags = 0; | 1140 | enc->flags = 0; |
1131 | if (try) | 1141 | if (try) |
1132 | return 0; | 1142 | return 0; |
1133 | return ivtv_start_capture(id); | 1143 | return ivtv_start_capture(id); |
1134 | 1144 | ||
1135 | case V4L2_ENC_CMD_STOP: | 1145 | case V4L2_ENC_CMD_STOP: |
1146 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n"); | ||
1136 | enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; | 1147 | enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; |
1137 | if (try) | 1148 | if (try) |
1138 | return 0; | 1149 | return 0; |
@@ -1140,6 +1151,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
1140 | return 0; | 1151 | return 0; |
1141 | 1152 | ||
1142 | case V4L2_ENC_CMD_PAUSE: | 1153 | case V4L2_ENC_CMD_PAUSE: |
1154 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n"); | ||
1143 | enc->flags = 0; | 1155 | enc->flags = 0; |
1144 | if (try) | 1156 | if (try) |
1145 | return 0; | 1157 | return 0; |
@@ -1152,6 +1164,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
1152 | break; | 1164 | break; |
1153 | 1165 | ||
1154 | case V4L2_ENC_CMD_RESUME: | 1166 | case V4L2_ENC_CMD_RESUME: |
1167 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n"); | ||
1155 | enc->flags = 0; | 1168 | enc->flags = 0; |
1156 | if (try) | 1169 | if (try) |
1157 | return 0; | 1170 | return 0; |
@@ -1163,6 +1176,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
1163 | ivtv_unmute(itv); | 1176 | ivtv_unmute(itv); |
1164 | break; | 1177 | break; |
1165 | default: | 1178 | default: |
1179 | IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd); | ||
1166 | return -EINVAL; | 1180 | return -EINVAL; |
1167 | } | 1181 | } |
1168 | break; | 1182 | break; |
@@ -1170,22 +1184,58 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
1170 | 1184 | ||
1171 | case VIDIOC_G_FBUF: { | 1185 | case VIDIOC_G_FBUF: { |
1172 | struct v4l2_framebuffer *fb = arg; | 1186 | struct v4l2_framebuffer *fb = arg; |
1187 | int pixfmt; | ||
1188 | static u32 pixel_format[16] = { | ||
1189 | V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */ | ||
1190 | V4L2_PIX_FMT_RGB565, | ||
1191 | V4L2_PIX_FMT_RGB555, | ||
1192 | V4L2_PIX_FMT_RGB444, | ||
1193 | V4L2_PIX_FMT_RGB32, | ||
1194 | 0, | ||
1195 | 0, | ||
1196 | 0, | ||
1197 | V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */ | ||
1198 | V4L2_PIX_FMT_YUV565, | ||
1199 | V4L2_PIX_FMT_YUV555, | ||
1200 | V4L2_PIX_FMT_YUV444, | ||
1201 | V4L2_PIX_FMT_YUV32, | ||
1202 | 0, | ||
1203 | 0, | ||
1204 | 0, | ||
1205 | }; | ||
1173 | 1206 | ||
1174 | memset(fb, 0, sizeof(*fb)); | 1207 | memset(fb, 0, sizeof(*fb)); |
1175 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) | 1208 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) |
1176 | return -EINVAL; | 1209 | return -EINVAL; |
1177 | fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | | 1210 | fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | |
1178 | V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_GLOBAL_ALPHA; | 1211 | V4L2_FBUF_CAP_GLOBAL_ALPHA; |
1179 | fb->fmt.pixelformat = itv->osd_pixelformat; | 1212 | ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0); |
1213 | data[0] |= (read_reg(0x2a00) >> 7) & 0x40; | ||
1214 | pixfmt = (data[0] >> 3) & 0xf; | ||
1215 | fb->fmt.pixelformat = pixel_format[pixfmt]; | ||
1180 | fb->fmt.width = itv->osd_rect.width; | 1216 | fb->fmt.width = itv->osd_rect.width; |
1181 | fb->fmt.height = itv->osd_rect.height; | 1217 | fb->fmt.height = itv->osd_rect.height; |
1182 | fb->base = (void *)itv->osd_video_pbase; | 1218 | fb->base = (void *)itv->osd_video_pbase; |
1219 | if (itv->osd_chroma_key_state) | ||
1220 | fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY; | ||
1183 | if (itv->osd_global_alpha_state) | 1221 | if (itv->osd_global_alpha_state) |
1184 | fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; | 1222 | fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; |
1185 | if (itv->osd_local_alpha_state) | 1223 | pixfmt &= 7; |
1186 | fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; | 1224 | /* no local alpha for RGB565 or unknown formats */ |
1187 | if (itv->osd_color_key_state) | 1225 | if (pixfmt == 1 || pixfmt > 4) |
1188 | fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY; | 1226 | break; |
1227 | /* 16-bit formats have inverted local alpha */ | ||
1228 | if (pixfmt == 2 || pixfmt == 3) | ||
1229 | fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA; | ||
1230 | else | ||
1231 | fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA; | ||
1232 | if (itv->osd_local_alpha_state) { | ||
1233 | /* 16-bit formats have inverted local alpha */ | ||
1234 | if (pixfmt == 2 || pixfmt == 3) | ||
1235 | fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA; | ||
1236 | else | ||
1237 | fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; | ||
1238 | } | ||
1189 | break; | 1239 | break; |
1190 | } | 1240 | } |
1191 | 1241 | ||
@@ -1195,12 +1245,22 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
1195 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) | 1245 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) |
1196 | return -EINVAL; | 1246 | return -EINVAL; |
1197 | itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; | 1247 | itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; |
1198 | itv->osd_local_alpha_state = (fb->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) != 0; | 1248 | itv->osd_local_alpha_state = |
1199 | itv->osd_color_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; | 1249 | (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0; |
1250 | itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; | ||
1200 | ivtv_set_osd_alpha(itv); | 1251 | ivtv_set_osd_alpha(itv); |
1201 | break; | 1252 | break; |
1202 | } | 1253 | } |
1203 | 1254 | ||
1255 | case VIDIOC_OVERLAY: { | ||
1256 | int *on = arg; | ||
1257 | |||
1258 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) | ||
1259 | return -EINVAL; | ||
1260 | ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, *on != 0); | ||
1261 | break; | ||
1262 | } | ||
1263 | |||
1204 | case VIDIOC_LOG_STATUS: | 1264 | case VIDIOC_LOG_STATUS: |
1205 | { | 1265 | { |
1206 | int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT; | 1266 | int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT; |
@@ -1209,6 +1269,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
1209 | int i; | 1269 | int i; |
1210 | 1270 | ||
1211 | IVTV_INFO("================= START STATUS CARD #%d =================\n", itv->num); | 1271 | IVTV_INFO("================= START STATUS CARD #%d =================\n", itv->num); |
1272 | IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name); | ||
1212 | if (itv->hw_flags & IVTV_HW_TVEEPROM) { | 1273 | if (itv->hw_flags & IVTV_HW_TVEEPROM) { |
1213 | struct tveeprom tv; | 1274 | struct tveeprom tv; |
1214 | 1275 | ||
@@ -1217,32 +1278,72 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
1217 | ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL); | 1278 | ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL); |
1218 | ivtv_get_input(itv, itv->active_input, &vidin); | 1279 | ivtv_get_input(itv, itv->active_input, &vidin); |
1219 | ivtv_get_audio_input(itv, itv->audio_input, &audin); | 1280 | ivtv_get_audio_input(itv, itv->audio_input, &audin); |
1220 | IVTV_INFO("Video Input: %s\n", vidin.name); | 1281 | IVTV_INFO("Video Input: %s\n", vidin.name); |
1221 | IVTV_INFO("Audio Input: %s\n", audin.name); | 1282 | IVTV_INFO("Audio Input: %s%s\n", audin.name, |
1283 | (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : ""); | ||
1222 | if (has_output) { | 1284 | if (has_output) { |
1223 | struct v4l2_output vidout; | 1285 | struct v4l2_output vidout; |
1224 | struct v4l2_audioout audout; | 1286 | struct v4l2_audioout audout; |
1225 | int mode = itv->output_mode; | 1287 | int mode = itv->output_mode; |
1226 | static const char * const output_modes[] = { | 1288 | static const char * const output_modes[5] = { |
1227 | "None", | 1289 | "None", |
1228 | "MPEG Streaming", | 1290 | "MPEG Streaming", |
1229 | "YUV Streaming", | 1291 | "YUV Streaming", |
1230 | "YUV Frames", | 1292 | "YUV Frames", |
1231 | "Passthrough", | 1293 | "Passthrough", |
1232 | }; | 1294 | }; |
1295 | static const char * const audio_modes[5] = { | ||
1296 | "Stereo", | ||
1297 | "Left", | ||
1298 | "Right", | ||
1299 | "Mono", | ||
1300 | "Swapped" | ||
1301 | }; | ||
1302 | static const char * const alpha_mode[4] = { | ||
1303 | "None", | ||
1304 | "Global", | ||
1305 | "Local", | ||
1306 | "Global and Local" | ||
1307 | }; | ||
1308 | static const char * const pixel_format[16] = { | ||
1309 | "ARGB Indexed", | ||
1310 | "RGB 5:6:5", | ||
1311 | "ARGB 1:5:5:5", | ||
1312 | "ARGB 1:4:4:4", | ||
1313 | "ARGB 8:8:8:8", | ||
1314 | "5", | ||
1315 | "6", | ||
1316 | "7", | ||
1317 | "AYUV Indexed", | ||
1318 | "YUV 5:6:5", | ||
1319 | "AYUV 1:5:5:5", | ||
1320 | "AYUV 1:4:4:4", | ||
1321 | "AYUV 8:8:8:8", | ||
1322 | "13", | ||
1323 | "14", | ||
1324 | "15", | ||
1325 | }; | ||
1233 | 1326 | ||
1234 | ivtv_get_output(itv, itv->active_output, &vidout); | 1327 | ivtv_get_output(itv, itv->active_output, &vidout); |
1235 | ivtv_get_audio_output(itv, 0, &audout); | 1328 | ivtv_get_audio_output(itv, 0, &audout); |
1236 | IVTV_INFO("Video Output: %s\n", vidout.name); | 1329 | IVTV_INFO("Video Output: %s\n", vidout.name); |
1237 | IVTV_INFO("Audio Output: %s\n", audout.name); | 1330 | IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name, |
1331 | audio_modes[itv->audio_stereo_mode], | ||
1332 | audio_modes[itv->audio_bilingual_mode]); | ||
1238 | if (mode < 0 || mode > OUT_PASSTHROUGH) | 1333 | if (mode < 0 || mode > OUT_PASSTHROUGH) |
1239 | mode = OUT_NONE; | 1334 | mode = OUT_NONE; |
1240 | IVTV_INFO("Output Mode: %s\n", output_modes[mode]); | 1335 | IVTV_INFO("Output Mode: %s\n", output_modes[mode]); |
1336 | ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0); | ||
1337 | data[0] |= (read_reg(0x2a00) >> 7) & 0x40; | ||
1338 | IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n", | ||
1339 | data[0] & 1 ? "On" : "Off", | ||
1340 | alpha_mode[(data[0] >> 1) & 0x3], | ||
1341 | pixel_format[(data[0] >> 3) & 0xf]); | ||
1241 | } | 1342 | } |
1242 | IVTV_INFO("Tuner: %s\n", | 1343 | IVTV_INFO("Tuner: %s\n", |
1243 | test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV"); | 1344 | test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV"); |
1244 | cx2341x_log_status(&itv->params, itv->name); | 1345 | cx2341x_log_status(&itv->params, itv->name); |
1245 | IVTV_INFO("Version: %s Status flags: 0x%08lx\n", IVTV_VERSION, itv->i_flags); | 1346 | IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags); |
1246 | for (i = 0; i < IVTV_MAX_STREAMS; i++) { | 1347 | for (i = 0; i < IVTV_MAX_STREAMS; i++) { |
1247 | struct ivtv_stream *s = &itv->streams[i]; | 1348 | struct ivtv_stream *s = &itv->streams[i]; |
1248 | 1349 | ||
@@ -1252,7 +1353,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
1252 | (s->buffers - s->q_free.buffers) * 100 / s->buffers, | 1353 | (s->buffers - s->q_free.buffers) * 100 / s->buffers, |
1253 | (s->buffers * s->buf_size) / 1024, s->buffers); | 1354 | (s->buffers * s->buf_size) / 1024, s->buffers); |
1254 | } | 1355 | } |
1255 | IVTV_INFO("Read MPEG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted); | 1356 | IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted); |
1256 | IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num); | 1357 | IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num); |
1257 | break; | 1358 | break; |
1258 | } | 1359 | } |
@@ -1288,6 +1389,8 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) | |||
1288 | ivtv_release_stream(s); | 1389 | ivtv_release_stream(s); |
1289 | return -EBUSY; | 1390 | return -EBUSY; |
1290 | } | 1391 | } |
1392 | /* Mark that this file handle started the UDMA_YUV mode */ | ||
1393 | id->yuv_frames = 1; | ||
1291 | if (args->y_source == NULL) | 1394 | if (args->y_source == NULL) |
1292 | return 0; | 1395 | return 0; |
1293 | return ivtv_yuv_prep_frame(itv, args); | 1396 | return ivtv_yuv_prep_frame(itv, args); |
@@ -1396,9 +1499,9 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) | |||
1396 | int try = (cmd == VIDEO_TRY_COMMAND); | 1499 | int try = (cmd == VIDEO_TRY_COMMAND); |
1397 | 1500 | ||
1398 | if (try) | 1501 | if (try) |
1399 | IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND\n"); | 1502 | IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", vc->cmd); |
1400 | else | 1503 | else |
1401 | IVTV_DEBUG_IOCTL("VIDEO_COMMAND\n"); | 1504 | IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", vc->cmd); |
1402 | return ivtv_video_command(itv, id, vc, try); | 1505 | return ivtv_video_command(itv, id, vc, try); |
1403 | } | 1506 | } |
1404 | 1507 | ||
@@ -1429,11 +1532,15 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) | |||
1429 | return 0; | 1532 | return 0; |
1430 | if (nonblocking) | 1533 | if (nonblocking) |
1431 | return -EAGAIN; | 1534 | return -EAGAIN; |
1432 | /* wait for event */ | 1535 | /* Wait for event. Note that serialize_lock is locked, |
1536 | so to allow other processes to access the driver while | ||
1537 | we are waiting unlock first and later lock again. */ | ||
1538 | mutex_unlock(&itv->serialize_lock); | ||
1433 | prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE); | 1539 | prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE); |
1434 | if ((itv->i_flags & (IVTV_F_I_EV_DEC_STOPPED|IVTV_F_I_EV_VSYNC)) == 0) | 1540 | if ((itv->i_flags & (IVTV_F_I_EV_DEC_STOPPED|IVTV_F_I_EV_VSYNC)) == 0) |
1435 | schedule(); | 1541 | schedule(); |
1436 | finish_wait(&itv->event_waitq, &wait); | 1542 | finish_wait(&itv->event_waitq, &wait); |
1543 | mutex_lock(&itv->serialize_lock); | ||
1437 | if (signal_pending(current)) { | 1544 | if (signal_pending(current)) { |
1438 | /* return if a signal was received */ | 1545 | /* return if a signal was received */ |
1439 | IVTV_DEBUG_INFO("User stopped wait for event\n"); | 1546 | IVTV_DEBUG_INFO("User stopped wait for event\n"); |
@@ -1470,6 +1577,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, | |||
1470 | case VIDIOC_S_AUDOUT: | 1577 | case VIDIOC_S_AUDOUT: |
1471 | case VIDIOC_S_EXT_CTRLS: | 1578 | case VIDIOC_S_EXT_CTRLS: |
1472 | case VIDIOC_S_FBUF: | 1579 | case VIDIOC_S_FBUF: |
1580 | case VIDIOC_OVERLAY: | ||
1473 | ret = v4l2_prio_check(&itv->prio, &id->prio); | 1581 | ret = v4l2_prio_check(&itv->prio, &id->prio); |
1474 | if (ret) | 1582 | if (ret) |
1475 | return ret; | 1583 | return ret; |
@@ -1523,6 +1631,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, | |||
1523 | case VIDIOC_TRY_ENCODER_CMD: | 1631 | case VIDIOC_TRY_ENCODER_CMD: |
1524 | case VIDIOC_G_FBUF: | 1632 | case VIDIOC_G_FBUF: |
1525 | case VIDIOC_S_FBUF: | 1633 | case VIDIOC_S_FBUF: |
1634 | case VIDIOC_OVERLAY: | ||
1526 | if (ivtv_debug & IVTV_DBGFLG_IOCTL) { | 1635 | if (ivtv_debug & IVTV_DBGFLG_IOCTL) { |
1527 | printk(KERN_INFO "ivtv%d ioctl: ", itv->num); | 1636 | printk(KERN_INFO "ivtv%d ioctl: ", itv->num); |
1528 | v4l_printk_ioctl(cmd); | 1637 | v4l_printk_ioctl(cmd); |
@@ -1563,12 +1672,9 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, | |||
1563 | return 0; | 1672 | return 0; |
1564 | } | 1673 | } |
1565 | 1674 | ||
1566 | int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | 1675 | static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct file *filp, |
1567 | unsigned long arg) | 1676 | unsigned int cmd, unsigned long arg) |
1568 | { | 1677 | { |
1569 | struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; | ||
1570 | struct ivtv *itv = id->itv; | ||
1571 | |||
1572 | /* Filter dvb ioctls that cannot be handled by video_usercopy */ | 1678 | /* Filter dvb ioctls that cannot be handled by video_usercopy */ |
1573 | switch (cmd) { | 1679 | switch (cmd) { |
1574 | case VIDEO_SELECT_SOURCE: | 1680 | case VIDEO_SELECT_SOURCE: |
@@ -1603,3 +1709,16 @@ int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |||
1603 | } | 1709 | } |
1604 | return video_usercopy(inode, filp, cmd, arg, ivtv_v4l2_do_ioctl); | 1710 | return video_usercopy(inode, filp, cmd, arg, ivtv_v4l2_do_ioctl); |
1605 | } | 1711 | } |
1712 | |||
1713 | int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | ||
1714 | unsigned long arg) | ||
1715 | { | ||
1716 | struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; | ||
1717 | struct ivtv *itv = id->itv; | ||
1718 | int res; | ||
1719 | |||
1720 | mutex_lock(&itv->serialize_lock); | ||
1721 | res = ivtv_serialized_ioctl(itv, inode, filp, cmd, arg); | ||
1722 | mutex_unlock(&itv->serialize_lock); | ||
1723 | return res; | ||
1724 | } | ||