diff options
Diffstat (limited to 'drivers/media/video/ivtv')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.h | 1 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-fileops.c | 10 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-firmware.c | 2 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-ioctl.c | 11 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-mailbox.c | 14 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-streams.c | 11 |
6 files changed, 33 insertions, 16 deletions
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 91b588d261ae..8abb34a35816 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h | |||
@@ -417,6 +417,7 @@ struct ivtv_mailbox_data { | |||
417 | #define IVTV_F_I_WORK_HANDLER_YUV 17 /* there is work to be done for YUV */ | 417 | #define IVTV_F_I_WORK_HANDLER_YUV 17 /* there is work to be done for YUV */ |
418 | #define IVTV_F_I_WORK_HANDLER_PIO 18 /* there is work to be done for PIO */ | 418 | #define IVTV_F_I_WORK_HANDLER_PIO 18 /* there is work to be done for PIO */ |
419 | #define IVTV_F_I_PIO 19 /* PIO in progress */ | 419 | #define IVTV_F_I_PIO 19 /* PIO in progress */ |
420 | #define IVTV_F_I_DEC_PAUSED 20 /* the decoder is paused */ | ||
420 | 421 | ||
421 | /* Event notifications */ | 422 | /* Event notifications */ |
422 | #define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */ | 423 | #define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */ |
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 8e97a938398f..5dd519caf81d 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
@@ -757,6 +757,7 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts) | |||
757 | itv->output_mode = OUT_NONE; | 757 | itv->output_mode = OUT_NONE; |
758 | 758 | ||
759 | itv->speed = 0; | 759 | itv->speed = 0; |
760 | clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags); | ||
760 | ivtv_release_stream(s); | 761 | ivtv_release_stream(s); |
761 | } | 762 | } |
762 | 763 | ||
@@ -799,7 +800,16 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp) | |||
799 | ivtv_unmute(itv); | 800 | ivtv_unmute(itv); |
800 | ivtv_release_stream(s); | 801 | ivtv_release_stream(s); |
801 | } else if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) { | 802 | } else if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) { |
803 | struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT]; | ||
804 | |||
802 | ivtv_stop_decoding(id, VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0); | 805 | ivtv_stop_decoding(id, VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0); |
806 | |||
807 | /* If all output streams are closed, and if the user doesn't have | ||
808 | IVTV_DEC_STREAM_TYPE_VOUT open, then disable VBI on TV-out. */ | ||
809 | if (itv->output_mode == OUT_NONE && !test_bit(IVTV_F_S_APPL_IO, &s_vout->s_flags)) { | ||
810 | /* disable VBI on TV-out */ | ||
811 | ivtv_disable_vbi(itv); | ||
812 | } | ||
803 | } else { | 813 | } else { |
804 | ivtv_stop_capture(id, 0); | 814 | ivtv_stop_capture(id, 0); |
805 | } | 815 | } |
diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/video/ivtv/ivtv-firmware.c index d0feabf93080..425eb1063904 100644 --- a/drivers/media/video/ivtv/ivtv-firmware.c +++ b/drivers/media/video/ivtv/ivtv-firmware.c | |||
@@ -72,8 +72,8 @@ retry: | |||
72 | dst++; | 72 | dst++; |
73 | src++; | 73 | src++; |
74 | } | 74 | } |
75 | release_firmware(fw); | ||
76 | IVTV_INFO("Loaded %s firmware (%zd bytes)\n", fn, fw->size); | 75 | IVTV_INFO("Loaded %s firmware (%zd bytes)\n", fn, fw->size); |
76 | release_firmware(fw); | ||
77 | return size; | 77 | return size; |
78 | } | 78 | } |
79 | IVTV_ERR("Unable to open firmware %s (must be %ld bytes)\n", fn, size); | 79 | IVTV_ERR("Unable to open firmware %s (must be %ld bytes)\n", fn, size); |
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 4773453e8dab..047624b9e271 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
@@ -285,6 +285,10 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id, | |||
285 | 285 | ||
286 | if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG) | 286 | if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG) |
287 | return -EBUSY; | 287 | return -EBUSY; |
288 | if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) { | ||
289 | /* forces ivtv_set_speed to be called */ | ||
290 | itv->speed = 0; | ||
291 | } | ||
288 | return ivtv_start_decoding(id, vc->play.speed); | 292 | return ivtv_start_decoding(id, vc->play.speed); |
289 | } | 293 | } |
290 | 294 | ||
@@ -309,6 +313,7 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id, | |||
309 | if (atomic_read(&itv->decoding) > 0) { | 313 | if (atomic_read(&itv->decoding) > 0) { |
310 | ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, | 314 | ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, |
311 | (vc->flags & VIDEO_CMD_FREEZE_TO_BLACK) ? 1 : 0); | 315 | (vc->flags & VIDEO_CMD_FREEZE_TO_BLACK) ? 1 : 0); |
316 | set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags); | ||
312 | } | 317 | } |
313 | break; | 318 | break; |
314 | 319 | ||
@@ -317,8 +322,10 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id, | |||
317 | if (try) break; | 322 | if (try) break; |
318 | if (itv->output_mode != OUT_MPG) | 323 | if (itv->output_mode != OUT_MPG) |
319 | return -EBUSY; | 324 | return -EBUSY; |
320 | if (atomic_read(&itv->decoding) > 0) { | 325 | if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) { |
321 | ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, 0, 0); | 326 | int speed = itv->speed; |
327 | itv->speed = 0; | ||
328 | return ivtv_start_decoding(id, speed); | ||
322 | } | 329 | } |
323 | break; | 330 | break; |
324 | 331 | ||
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.c b/drivers/media/video/ivtv/ivtv-mailbox.c index 814a673712b3..5e3b679202ae 100644 --- a/drivers/media/video/ivtv/ivtv-mailbox.c +++ b/drivers/media/video/ivtv/ivtv-mailbox.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #define API_HIGH_VOL (1 << 5) /* High volume command (i.e. called during encoding or decoding) */ | 40 | #define API_HIGH_VOL (1 << 5) /* High volume command (i.e. called during encoding or decoding) */ |
41 | #define API_NO_WAIT_MB (1 << 4) /* Command may not wait for a free mailbox */ | 41 | #define API_NO_WAIT_MB (1 << 4) /* Command may not wait for a free mailbox */ |
42 | #define API_NO_WAIT_RES (1 << 5) /* Command may not wait for the result */ | 42 | #define API_NO_WAIT_RES (1 << 5) /* Command may not wait for the result */ |
43 | #define API_NO_POLL (1 << 6) /* Avoid pointless polling */ | ||
43 | 44 | ||
44 | struct ivtv_api_info { | 45 | struct ivtv_api_info { |
45 | int flags; /* Flags, see above */ | 46 | int flags; /* Flags, see above */ |
@@ -51,7 +52,7 @@ struct ivtv_api_info { | |||
51 | static const struct ivtv_api_info api_info[256] = { | 52 | static const struct ivtv_api_info api_info[256] = { |
52 | /* MPEG encoder API */ | 53 | /* MPEG encoder API */ |
53 | API_ENTRY(CX2341X_ENC_PING_FW, API_FAST_RESULT), | 54 | API_ENTRY(CX2341X_ENC_PING_FW, API_FAST_RESULT), |
54 | API_ENTRY(CX2341X_ENC_START_CAPTURE, API_RESULT), | 55 | API_ENTRY(CX2341X_ENC_START_CAPTURE, API_RESULT | API_NO_POLL), |
55 | API_ENTRY(CX2341X_ENC_STOP_CAPTURE, API_RESULT), | 56 | API_ENTRY(CX2341X_ENC_STOP_CAPTURE, API_RESULT), |
56 | API_ENTRY(CX2341X_ENC_SET_AUDIO_ID, API_CACHE), | 57 | API_ENTRY(CX2341X_ENC_SET_AUDIO_ID, API_CACHE), |
57 | API_ENTRY(CX2341X_ENC_SET_VIDEO_ID, API_CACHE), | 58 | API_ENTRY(CX2341X_ENC_SET_VIDEO_ID, API_CACHE), |
@@ -96,7 +97,7 @@ static const struct ivtv_api_info api_info[256] = { | |||
96 | 97 | ||
97 | /* MPEG decoder API */ | 98 | /* MPEG decoder API */ |
98 | API_ENTRY(CX2341X_DEC_PING_FW, API_FAST_RESULT), | 99 | API_ENTRY(CX2341X_DEC_PING_FW, API_FAST_RESULT), |
99 | API_ENTRY(CX2341X_DEC_START_PLAYBACK, API_RESULT), | 100 | API_ENTRY(CX2341X_DEC_START_PLAYBACK, API_RESULT | API_NO_POLL), |
100 | API_ENTRY(CX2341X_DEC_STOP_PLAYBACK, API_RESULT), | 101 | API_ENTRY(CX2341X_DEC_STOP_PLAYBACK, API_RESULT), |
101 | API_ENTRY(CX2341X_DEC_SET_PLAYBACK_SPEED, API_RESULT), | 102 | API_ENTRY(CX2341X_DEC_SET_PLAYBACK_SPEED, API_RESULT), |
102 | API_ENTRY(CX2341X_DEC_STEP_VIDEO, API_RESULT), | 103 | API_ENTRY(CX2341X_DEC_STEP_VIDEO, API_RESULT), |
@@ -290,6 +291,13 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) | |||
290 | /* Get results */ | 291 | /* Get results */ |
291 | then = jiffies; | 292 | then = jiffies; |
292 | 293 | ||
294 | if (!(flags & API_NO_POLL)) { | ||
295 | /* First try to poll, then switch to delays */ | ||
296 | for (i = 0; i < 100; i++) { | ||
297 | if (readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE) | ||
298 | break; | ||
299 | } | ||
300 | } | ||
293 | while (!(readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE)) { | 301 | while (!(readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE)) { |
294 | if (jiffies - then > api_timeout) { | 302 | if (jiffies - then > api_timeout) { |
295 | IVTV_DEBUG_WARN("Could not get result (%s)\n", api_info[cmd].name); | 303 | IVTV_DEBUG_WARN("Could not get result (%s)\n", api_info[cmd].name); |
@@ -301,7 +309,7 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) | |||
301 | if (flags & API_NO_WAIT_RES) | 309 | if (flags & API_NO_WAIT_RES) |
302 | mdelay(1); | 310 | mdelay(1); |
303 | else | 311 | else |
304 | ivtv_msleep_timeout(10, 0); | 312 | ivtv_msleep_timeout(1, 0); |
305 | } | 313 | } |
306 | if (jiffies - then > msecs_to_jiffies(100)) | 314 | if (jiffies - then > msecs_to_jiffies(100)) |
307 | IVTV_DEBUG_WARN("%s took %u jiffies\n", | 315 | IVTV_DEBUG_WARN("%s took %u jiffies\n", |
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index 322b347b67c2..51df3f855031 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c | |||
@@ -603,10 +603,6 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) | |||
603 | 603 | ||
604 | IVTV_DEBUG_INFO("Setting some initial decoder settings\n"); | 604 | IVTV_DEBUG_INFO("Setting some initial decoder settings\n"); |
605 | 605 | ||
606 | /* disable VBI signals, if the MPEG stream contains VBI data, | ||
607 | then that data will be processed automatically for you. */ | ||
608 | ivtv_disable_vbi(itv); | ||
609 | |||
610 | /* set audio mode to left/stereo for dual/stereo mode. */ | 606 | /* set audio mode to left/stereo for dual/stereo mode. */ |
611 | ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); | 607 | ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); |
612 | 608 | ||
@@ -639,7 +635,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) | |||
639 | } | 635 | } |
640 | if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype, | 636 | if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype, |
641 | itv->params.width, itv->params.height, itv->params.audio_properties)) { | 637 | itv->params.width, itv->params.height, itv->params.audio_properties)) { |
642 | IVTV_DEBUG_WARN("COULDN'T INITIALIZE DECODER SOURCE\n"); | 638 | IVTV_DEBUG_WARN("Couldn't initialize decoder source\n"); |
643 | } | 639 | } |
644 | return 0; | 640 | return 0; |
645 | } | 641 | } |
@@ -909,11 +905,6 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts) | |||
909 | clear_bit(IVTV_F_S_STREAMING, &s->s_flags); | 905 | clear_bit(IVTV_F_S_STREAMING, &s->s_flags); |
910 | ivtv_flush_queues(s); | 906 | ivtv_flush_queues(s); |
911 | 907 | ||
912 | if (!test_bit(IVTV_F_S_PASSTHROUGH, &s->s_flags)) { | ||
913 | /* disable VBI on TV-out */ | ||
914 | ivtv_disable_vbi(itv); | ||
915 | } | ||
916 | |||
917 | /* decrement decoding */ | 908 | /* decrement decoding */ |
918 | atomic_dec(&itv->decoding); | 909 | atomic_dec(&itv->decoding); |
919 | 910 | ||