V4L/DVB (7709): pvrusb2: New device attribute for encoder usage in digital mode
authorMike Isely <isely@pobox.com>
Thu, 3 Apr 2008 07:51:19 +0000 (04:51 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Thu, 24 Apr 2008 17:09:48 +0000 (14:09 -0300)
Some tuners seem to not work in digital mode unless the encoder is
healthy.  Implement a device attribute to represent this flag and
modify the core state machines to enforce this requirement.

Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/video/pvrusb2/pvrusb2-devattr.c
drivers/media/video/pvrusb2/pvrusb2-devattr.h
drivers/media/video/pvrusb2/pvrusb2-hdw.c

index 64a29ad..74c92a4 100644 (file)
@@ -201,6 +201,7 @@ static const struct pvr2_device_desc pvr2_device_onair_creator = {
                .flag_has_analogtuner = !0,
                .flag_has_composite = !0,
                .flag_has_svideo = !0,
+               .flag_digital_requires_cx23416 = !0,
                .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
                .digital_control_scheme = PVR2_DIGITAL_SCHEME_ONAIR,
                .default_std_mask = V4L2_STD_NTSC_M,
@@ -262,6 +263,7 @@ static const struct pvr2_device_desc pvr2_device_onair_usb2 = {
                .flag_has_analogtuner = !0,
                .flag_has_composite = !0,
                .flag_has_svideo = !0,
+               .flag_digital_requires_cx23416 = !0,
                .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
                .digital_control_scheme = PVR2_DIGITAL_SCHEME_ONAIR,
                .default_std_mask = V4L2_STD_NTSC_M,
index 3891351..c2e2b06 100644 (file)
@@ -106,6 +106,13 @@ struct pvr2_device_desc {
        /* If set, we don't bother trying to load cx23416 firmware. */
        int flag_skip_cx23416_firmware:1;
 
+       /* If set, the encoder must be healthy in order for digital mode to
+          work (otherwise we assume that digital streaming will work even
+          if we fail to locate firmware for the encoder).  If the device
+          doesn't support digital streaming then this flag has no
+          effect. */
+       int flag_digital_requires_cx23416:1;
+
        /* Device has a hauppauge eeprom which we can interrogate. */
        int flag_has_hauppauge_rom:1;
 
index 195e974..539fe17 100644 (file)
@@ -3502,7 +3502,12 @@ static int state_eval_encoder_ok(struct pvr2_hdw *hdw)
        if (hdw->state_encoder_config) return 0;
        if (hdw->state_decoder_run) return 0;
        if (hdw->state_usbstream_run) return 0;
-       if (hdw->pathway_state != PVR2_PATHWAY_ANALOG) return 0;
+       if (hdw->pathway_state == PVR2_PATHWAY_DIGITAL) {
+               if (!hdw->hdw_desc->flag_digital_requires_cx23416) return 0;
+       } else if (hdw->pathway_state != PVR2_PATHWAY_ANALOG) {
+               return 0;
+       }
+
        if (pvr2_upload_firmware2(hdw) < 0) {
                hdw->flag_tripped = !0;
                trace_stbit("flag_tripped",hdw->flag_tripped);
@@ -3687,14 +3692,19 @@ static int state_eval_decoder_run(struct pvr2_hdw *hdw)
 static int state_eval_usbstream_run(struct pvr2_hdw *hdw)
 {
        if (hdw->state_usbstream_run) {
+               int fl = !0;
                if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) {
-                       if (hdw->state_encoder_ok &&
-                           hdw->state_encoder_run &&
-                           hdw->state_pathway_ok) return 0;
-               } else {
-                       if (hdw->state_pipeline_req &&
-                           !hdw->state_pipeline_pause &&
-                           hdw->state_pathway_ok) return 0;
+                       fl = (hdw->state_encoder_ok &&
+                             hdw->state_encoder_run);
+               } else if ((hdw->pathway_state == PVR2_PATHWAY_DIGITAL) &&
+                          (hdw->hdw_desc->flag_digital_requires_cx23416)) {
+                       fl = hdw->state_encoder_ok;
+               }
+               if (fl &&
+                   hdw->state_pipeline_req &&
+                   !hdw->state_pipeline_pause &&
+                   hdw->state_pathway_ok) {
+                       return 0;
                }
                pvr2_hdw_cmd_usbstream(hdw,0);
                hdw->state_usbstream_run = 0;
@@ -3705,6 +3715,9 @@ static int state_eval_usbstream_run(struct pvr2_hdw *hdw)
                if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) {
                        if (!hdw->state_encoder_ok ||
                            !hdw->state_encoder_run) return 0;
+               } else if ((hdw->pathway_state == PVR2_PATHWAY_DIGITAL) &&
+                          (hdw->hdw_desc->flag_digital_requires_cx23416)) {
+                       if (!hdw->state_encoder_ok) return 0;
                }
                if (pvr2_hdw_cmd_usbstream(hdw,!0) < 0) return 0;
                hdw->state_usbstream_run = !0;
@@ -3943,7 +3956,9 @@ static int pvr2_hdw_state_eval(struct pvr2_hdw *hdw)
                st = PVR2_STATE_DEAD;
        } else if (hdw->fw1_state != FW1_STATE_OK) {
                st = PVR2_STATE_COLD;
-       } else if (analog_mode && !hdw->state_encoder_ok) {
+       } else if ((analog_mode ||
+                   hdw->hdw_desc->flag_digital_requires_cx23416) &&
+                  !hdw->state_encoder_ok) {
                st = PVR2_STATE_WARM;
        } else if (hdw->flag_tripped ||
                   (analog_mode && hdw->flag_decoder_missed)) {