diff options
author | Mike Isely <isely@pobox.com> | 2007-01-28 13:42:56 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-02-21 10:35:12 -0500 |
commit | 6fe7d2c4660174110c6872cacc4fc2acb6e00acf (patch) | |
tree | f85b58243303c0dbcf94255160b06cd975f1c256 /drivers/media/video/pvrusb2/pvrusb2-encoder.c | |
parent | c43000ef0c9f21fff090ff3b5428ac31a41dbc99 (diff) |
V4L/DVB (5174): Pvrusb2: video corruption fixes
Tweak the encoder setup in order to stop it from corrupting the video
data when there is a disruption in the data flow (e.g. a channel change).
Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/pvrusb2/pvrusb2-encoder.c')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-encoder.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c index 7cd95e9f914d..5fe17c0344b2 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c | |||
@@ -321,6 +321,73 @@ static int pvr2_encoder_vcmd(struct pvr2_hdw *hdw, int cmd, | |||
321 | return pvr2_encoder_cmd(hdw,cmd,args,0,data); | 321 | return pvr2_encoder_cmd(hdw,cmd,args,0,data); |
322 | } | 322 | } |
323 | 323 | ||
324 | |||
325 | /* This implements some extra setup for the encoder that seems to be | ||
326 | specific to the PVR USB2 hardware. */ | ||
327 | int pvr2_encoder_prep_config(struct pvr2_hdw *hdw) | ||
328 | { | ||
329 | int ret = 0; | ||
330 | int encMisc3Arg = 0; | ||
331 | |||
332 | #if 0 | ||
333 | /* This inexplicable bit happens in the Hauppage windows | ||
334 | driver (for both 24xxx and 29xxx devices). However I | ||
335 | currently see no difference in behavior with or without | ||
336 | this stuff. Leave this here as a note of its existence, | ||
337 | but don't use it. */ | ||
338 | LOCK_TAKE(hdw->ctl_lock); do { | ||
339 | u32 dat[1]; | ||
340 | dat[0] = 0x80000640; | ||
341 | pvr2_encoder_write_words(hdw,0x01fe,dat,1); | ||
342 | pvr2_encoder_write_words(hdw,0x023e,dat,1); | ||
343 | } while(0); LOCK_GIVE(hdw->ctl_lock); | ||
344 | #endif | ||
345 | |||
346 | /* Mike Isely <isely@pobox.com> 26-Jan-2006 The windows driver | ||
347 | sends the following list of ENC_MISC commands (for both | ||
348 | 24xxx and 29xxx devices). Meanings are not entirely clear, | ||
349 | however without the ENC_MISC(3,1) command then we risk | ||
350 | random perpetual video corruption whenever the video input | ||
351 | breaks up for a moment (like when switching channels). */ | ||
352 | |||
353 | |||
354 | #if 0 | ||
355 | /* This ENC_MISC(5,0) command seems to hurt 29xxx sync | ||
356 | performance on channel changes, but is not a problem on | ||
357 | 24xxx devices. */ | ||
358 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 5,0,0,0); | ||
359 | #endif | ||
360 | |||
361 | /* This ENC_MISC(3,encMisc3Arg) command is critical - without | ||
362 | it there will eventually be video corruption. Also, the | ||
363 | 29xxx case is strange - the Windows driver is passing 1 | ||
364 | regardless of device type but if we have 1 for 29xxx device | ||
365 | the video turns sluggish. */ | ||
366 | switch (hdw->hdw_type) { | ||
367 | case PVR2_HDW_TYPE_24XXX: encMisc3Arg = 1; break; | ||
368 | case PVR2_HDW_TYPE_29XXX: encMisc3Arg = 0; break; | ||
369 | default: break; | ||
370 | } | ||
371 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 3, | ||
372 | encMisc3Arg,0,0); | ||
373 | |||
374 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 8,0,0,0); | ||
375 | |||
376 | #if 0 | ||
377 | /* This ENC_MISC(4,1) command is poisonous, so it is commented | ||
378 | out. But I'm leaving it here anyway to document its | ||
379 | existence in the Windows driver. The effect of this | ||
380 | command is that apps displaying the stream become sluggish | ||
381 | with stuttering video. */ | ||
382 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 4,1,0,0); | ||
383 | #endif | ||
384 | |||
385 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 0,3,0,0); | ||
386 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4,15,0,0,0); | ||
387 | |||
388 | return ret; | ||
389 | } | ||
390 | |||
324 | int pvr2_encoder_configure(struct pvr2_hdw *hdw) | 391 | int pvr2_encoder_configure(struct pvr2_hdw *hdw) |
325 | { | 392 | { |
326 | int ret; | 393 | int ret; |
@@ -335,6 +402,8 @@ int pvr2_encoder_configure(struct pvr2_hdw *hdw) | |||
335 | 402 | ||
336 | ret = 0; | 403 | ret = 0; |
337 | 404 | ||
405 | ret |= pvr2_encoder_prep_config(hdw); | ||
406 | |||
338 | if (!ret) ret = pvr2_encoder_vcmd( | 407 | if (!ret) ret = pvr2_encoder_vcmd( |
339 | hdw,CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, | 408 | hdw,CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, |
340 | 0xf0, 0xf0); | 409 | 0xf0, 0xf0); |