aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/ivtv')
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h1
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c10
-rw-r--r--drivers/media/video/ivtv/ivtv-firmware.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c11
-rw-r--r--drivers/media/video/ivtv/ivtv-mailbox.c14
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c11
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
44struct ivtv_api_info { 45struct ivtv_api_info {
45 int flags; /* Flags, see above */ 46 int flags; /* Flags, see above */
@@ -51,7 +52,7 @@ struct ivtv_api_info {
51static const struct ivtv_api_info api_info[256] = { 52static 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