V4L/DVB (7299): pvrusb2: Improve logic which handles input choice availability

Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index d7a216b..aa374c7 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -323,6 +323,9 @@
 	int v4l_minor_number_vbi;
 	int v4l_minor_number_radio;
 
+	/* Bit mask of PVR2_CVAL_INPUT choices which are valid */
+	unsigned int input_avail_mask;
+
 	/* Location of eeprom or a negative number if none */
 	int eeprom_addr;
 
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 66945f7..94cb0a7 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -370,23 +370,7 @@
 
 static int ctrl_check_input(struct pvr2_ctrl *cptr,int v)
 {
-	struct pvr2_hdw *hdw = cptr->hdw;
-	const struct pvr2_device_desc *dsc = hdw->hdw_desc;
-
-	switch (v) {
-	case PVR2_CVAL_INPUT_TV:
-		return dsc->flag_has_analogtuner != 0;
-	case PVR2_CVAL_INPUT_DTV:
-		return dsc->flag_has_digitaltuner != 0;
-	case PVR2_CVAL_INPUT_SVIDEO:
-		return dsc->flag_has_svideo != 0;
-	case PVR2_CVAL_INPUT_COMPOSITE:
-		return dsc->flag_has_composite != 0;
-	case PVR2_CVAL_INPUT_RADIO:
-		return dsc->flag_has_fmradio != 0;
-	default:
-		return 0;
-	}
+	return ((1 << v) & cptr->hdw->input_avail_mask) != 0;
 }
 
 static int ctrl_set_input(struct pvr2_ctrl *cptr,int m,int v)
@@ -1834,7 +1818,7 @@
 struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
 				 const struct usb_device_id *devid)
 {
-	unsigned int idx,cnt1,cnt2;
+	unsigned int idx,cnt1,cnt2,m;
 	struct pvr2_hdw *hdw;
 	int valid_std_mask;
 	struct pvr2_ctrl *cptr;
@@ -1865,6 +1849,15 @@
 	hdw->tuner_signal_stale = !0;
 	cx2341x_fill_defaults(&hdw->enc_ctl_state);
 
+	/* Calculate which inputs are OK */
+	m = 0;
+	if (hdw_desc->flag_has_analogtuner) m |= 1 << PVR2_CVAL_INPUT_TV;
+	if (hdw_desc->flag_has_digitaltuner) m |= 1 << PVR2_CVAL_INPUT_DTV;
+	if (hdw_desc->flag_has_svideo) m |= 1 << PVR2_CVAL_INPUT_SVIDEO;
+	if (hdw_desc->flag_has_composite) m |= 1 << PVR2_CVAL_INPUT_COMPOSITE;
+	if (hdw_desc->flag_has_fmradio) m |= 1 << PVR2_CVAL_INPUT_RADIO;
+	hdw->input_avail_mask = m;
+
 	hdw->control_cnt = CTRLDEF_COUNT;
 	hdw->control_cnt += MPEGDEF_COUNT;
 	hdw->controls = kzalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt,
@@ -3780,6 +3773,12 @@
 }
 
 
+unsigned int pvr2_hdw_get_input_available(struct pvr2_hdw *hdw)
+{
+	return hdw->input_avail_mask;
+}
+
+
 /* Find I2C address of eeprom */
 static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
 {
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index d33b3139..59f3858 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -147,6 +147,10 @@
 /* Commit all control changes made up to this point */
 int pvr2_hdw_commit_ctl(struct pvr2_hdw *);
 
+/* Return a bit mask of valid input selections for this device.  Mask bits
+ * will be according to PVR_CVAL_INPUT_xxxx definitions. */
+unsigned int pvr2_hdw_get_input_available(struct pvr2_hdw *);
+
 /* Return name for this driver instance */
 const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *);