Browse Source

V4L/DVB (7709): pvrusb2: New device attribute for encoder usage in digital mode

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>
Mike Isely 17 years ago
parent
commit
72998b7109

+ 2 - 0
drivers/media/video/pvrusb2/pvrusb2-devattr.c

@@ -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,

+ 7 - 0
drivers/media/video/pvrusb2/pvrusb2-devattr.h

@@ -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;
 

+ 24 - 9
drivers/media/video/pvrusb2/pvrusb2-hdw.c

@@ -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)) {