aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pvrusb2/pvrusb2-encoder.c
diff options
context:
space:
mode:
authorMike Isely <isely@pobox.com>2007-11-25 23:48:52 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-01-25 16:03:01 -0500
commit681c739944018d80dbcf7f19997eba97676c7116 (patch)
tree4c2f3ab63bfd852fba0ec87f69fe76e52fa4aa48 /drivers/media/video/pvrusb2/pvrusb2-encoder.c
parent493977f016f2ff52fdca38d031c7211b4da658fd (diff)
V4L/DVB (6691): pvrusb2: Rework pipeline state control
This is a new implementation for video pipeline control within the pvrusb2 driver. Actual start/stop of the pipeline is moved to the driver's kernel thread. Pipeline stages are controlled autonomously based on surrounding pipeline or application control state. Kernel thread management is also cleaned up and moved into the internal control structure of the driver, solving a set up / tear down race along the way. Better failure recovery is implemented with this new control strategy. Also with this change comes better control of the cx23416 encoder, building on additional information learned about the peculiarities of controlling this part (this information was the original trigger for this rework). With this change, overall encoder stability should be considerably improved. Yes, this is a large change for this driver, but due to the nature of the feature being worked on, the changes are fairly pervasive and would be difficult to break into smaller pieces with any semblence of step-wise stability. 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.c54
1 files changed, 29 insertions, 25 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
index 205087a3e136..5ca548cc7e7f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -209,7 +209,7 @@ static int pvr2_encoder_cmd(void *ctxt,
209 209
210 LOCK_TAKE(hdw->ctl_lock); do { 210 LOCK_TAKE(hdw->ctl_lock); do {
211 211
212 if (!hdw->flag_encoder_ok) { 212 if (!hdw->state_encoder_ok) {
213 ret = -EIO; 213 ret = -EIO;
214 break; 214 break;
215 } 215 }
@@ -278,7 +278,11 @@ static int pvr2_encoder_cmd(void *ctxt,
278 ret = -EBUSY; 278 ret = -EBUSY;
279 } 279 }
280 if (ret) { 280 if (ret) {
281 hdw->flag_encoder_ok = 0; 281 hdw->state_encoder_ok = 0;
282 pvr2_trace(PVR2_TRACE_STBITS,
283 "State bit %s <-- %s",
284 "state_encoder_ok",
285 (hdw->state_encoder_ok ? "true" : "false"));
282 pvr2_trace( 286 pvr2_trace(
283 PVR2_TRACE_ERROR_LEGS, 287 PVR2_TRACE_ERROR_LEGS,
284 "Giving up on command." 288 "Giving up on command."
@@ -394,6 +398,24 @@ static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw)
394 return ret; 398 return ret;
395} 399}
396 400
401int pvr2_encoder_adjust(struct pvr2_hdw *hdw)
402{
403 int ret;
404 ret = cx2341x_update(hdw,pvr2_encoder_cmd,
405 (hdw->enc_cur_valid ? &hdw->enc_cur_state : NULL),
406 &hdw->enc_ctl_state);
407 if (ret) {
408 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
409 "Error from cx2341x module code=%d",ret);
410 } else {
411 memcpy(&hdw->enc_cur_state,&hdw->enc_ctl_state,
412 sizeof(struct cx2341x_mpeg_params));
413 hdw->enc_cur_valid = !0;
414 }
415 return ret;
416}
417
418
397int pvr2_encoder_configure(struct pvr2_hdw *hdw) 419int pvr2_encoder_configure(struct pvr2_hdw *hdw)
398{ 420{
399 int ret; 421 int ret;
@@ -436,18 +458,10 @@ int pvr2_encoder_configure(struct pvr2_hdw *hdw)
436 return ret; 458 return ret;
437 } 459 }
438 460
439 ret = cx2341x_update(hdw,pvr2_encoder_cmd, 461 ret = pvr2_encoder_adjust(hdw);
440 (hdw->enc_cur_valid ? &hdw->enc_cur_state : NULL), 462 if (ret) return ret;
441 &hdw->enc_ctl_state);
442 if (ret) {
443 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
444 "Error from cx2341x module code=%d",ret);
445 return ret;
446 }
447
448 ret = 0;
449 463
450 if (!ret) ret = pvr2_encoder_vcmd( 464 ret = pvr2_encoder_vcmd(
451 hdw, CX2341X_ENC_INITIALIZE_INPUT, 0); 465 hdw, CX2341X_ENC_INITIALIZE_INPUT, 0);
452 466
453 if (ret) { 467 if (ret) {
@@ -456,10 +470,6 @@ int pvr2_encoder_configure(struct pvr2_hdw *hdw)
456 return ret; 470 return ret;
457 } 471 }
458 472
459 hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
460 memcpy(&hdw->enc_cur_state,&hdw->enc_ctl_state,
461 sizeof(struct cx2341x_mpeg_params));
462 hdw->enc_cur_valid = !0;
463 return 0; 473 return 0;
464} 474}
465 475
@@ -478,7 +488,7 @@ int pvr2_encoder_start(struct pvr2_hdw *hdw)
478 pvr2_encoder_vcmd(hdw,CX2341X_ENC_MUTE_VIDEO,1, 488 pvr2_encoder_vcmd(hdw,CX2341X_ENC_MUTE_VIDEO,1,
479 hdw->input_val == PVR2_CVAL_INPUT_RADIO ? 1 : 0); 489 hdw->input_val == PVR2_CVAL_INPUT_RADIO ? 1 : 0);
480 490
481 switch (hdw->config) { 491 switch (hdw->active_stream_type) {
482 case pvr2_config_vbi: 492 case pvr2_config_vbi:
483 status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2, 493 status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2,
484 0x01,0x14); 494 0x01,0x14);
@@ -492,9 +502,6 @@ int pvr2_encoder_start(struct pvr2_hdw *hdw)
492 0,0x13); 502 0,0x13);
493 break; 503 break;
494 } 504 }
495 if (!status) {
496 hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_RUN);
497 }
498 return status; 505 return status;
499} 506}
500 507
@@ -505,7 +512,7 @@ int pvr2_encoder_stop(struct pvr2_hdw *hdw)
505 /* mask all interrupts */ 512 /* mask all interrupts */
506 pvr2_write_register(hdw, 0x0048, 0xffffffff); 513 pvr2_write_register(hdw, 0x0048, 0xffffffff);
507 514
508 switch (hdw->config) { 515 switch (hdw->active_stream_type) {
509 case pvr2_config_vbi: 516 case pvr2_config_vbi:
510 status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3, 517 status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3,
511 0x01,0x01,0x14); 518 0x01,0x01,0x14);
@@ -526,9 +533,6 @@ int pvr2_encoder_stop(struct pvr2_hdw *hdw)
526 pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000401); 533 pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000401);
527 pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000); 534 pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000);
528 535
529 if (!status) {
530 hdw->subsys_enabled_mask &= ~(1<<PVR2_SUBSYS_B_ENC_RUN);
531 }
532 return status; 536 return status;
533} 537}
534 538