diff options
Diffstat (limited to 'drivers/media/video/ivtv')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.c | 5 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-ioctl.c | 21 |
2 files changed, 25 insertions, 1 deletions
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 9a250548be4..1b79475ca13 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c | |||
@@ -1293,7 +1293,6 @@ int ivtv_init_on_first_open(struct ivtv *itv) | |||
1293 | ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1); | 1293 | ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1); |
1294 | ivtv_init_mpeg_decoder(itv); | 1294 | ivtv_init_mpeg_decoder(itv); |
1295 | } | 1295 | } |
1296 | ivtv_s_std(NULL, &fh, &itv->tuner_std); | ||
1297 | 1296 | ||
1298 | /* On a cx23416 this seems to be able to enable DMA to the chip? */ | 1297 | /* On a cx23416 this seems to be able to enable DMA to the chip? */ |
1299 | if (!itv->has_cx23415) | 1298 | if (!itv->has_cx23415) |
@@ -1310,6 +1309,10 @@ int ivtv_init_on_first_open(struct ivtv *itv) | |||
1310 | } | 1309 | } |
1311 | else | 1310 | else |
1312 | ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT); | 1311 | ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT); |
1312 | |||
1313 | /* For cards with video out, this call needs interrupts enabled */ | ||
1314 | ivtv_s_std(NULL, &fh, &itv->tuner_std); | ||
1315 | |||
1313 | return 0; | 1316 | return 0; |
1314 | } | 1317 | } |
1315 | 1318 | ||
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 99f3c39a118..2192bc42c6b 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
@@ -1087,8 +1087,10 @@ static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std) | |||
1087 | 1087 | ||
1088 | int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std) | 1088 | int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std) |
1089 | { | 1089 | { |
1090 | DEFINE_WAIT(wait); | ||
1090 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | 1091 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
1091 | struct yuv_playback_info *yi = &itv->yuv_info; | 1092 | struct yuv_playback_info *yi = &itv->yuv_info; |
1093 | int f; | ||
1092 | 1094 | ||
1093 | if ((*std & V4L2_STD_ALL) == 0) | 1095 | if ((*std & V4L2_STD_ALL) == 0) |
1094 | return -EINVAL; | 1096 | return -EINVAL; |
@@ -1128,6 +1130,25 @@ int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std) | |||
1128 | itv->is_out_60hz = itv->is_60hz; | 1130 | itv->is_out_60hz = itv->is_60hz; |
1129 | itv->is_out_50hz = itv->is_50hz; | 1131 | itv->is_out_50hz = itv->is_50hz; |
1130 | ivtv_call_all(itv, video, s_std_output, itv->std_out); | 1132 | ivtv_call_all(itv, video, s_std_output, itv->std_out); |
1133 | |||
1134 | /* | ||
1135 | * The next firmware call is time sensitive. Time it to | ||
1136 | * avoid risk of a hard lock, by trying to ensure the call | ||
1137 | * happens within the first 100 lines of the top field. | ||
1138 | * Make 4 attempts to sync to the decoder before giving up. | ||
1139 | */ | ||
1140 | for (f = 0; f < 4; f++) { | ||
1141 | prepare_to_wait(&itv->vsync_waitq, &wait, | ||
1142 | TASK_UNINTERRUPTIBLE); | ||
1143 | if ((read_reg(0x28c0) >> 16) < 100) | ||
1144 | break; | ||
1145 | schedule_timeout(msecs_to_jiffies(25)); | ||
1146 | } | ||
1147 | finish_wait(&itv->vsync_waitq, &wait); | ||
1148 | |||
1149 | if (f == 4) | ||
1150 | IVTV_WARN("Mode change failed to sync to decoder\n"); | ||
1151 | |||
1131 | ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz); | 1152 | ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz); |
1132 | itv->main_rect.left = itv->main_rect.top = 0; | 1153 | itv->main_rect.left = itv->main_rect.top = 0; |
1133 | itv->main_rect.width = 720; | 1154 | itv->main_rect.width = 720; |