summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Isely <isely@pobox.com>2007-09-08 22:28:51 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-10-09 22:14:34 -0300
commit9f66d4eac6be2428901ab6e0cbb6747d5b6794ef (patch)
treeff790fe0c5c650dfdd4e202c87397f8497990561
parent1d643a372259749ce2029e386ed5760d5d7f8b89 (diff)
downloadop-kernel-dev-9f66d4eac6be2428901ab6e0cbb6747d5b6794ef.zip
op-kernel-dev-9f66d4eac6be2428901ab6e0cbb6747d5b6794ef.tar.gz
V4L/DVB (6210): pvrusb2: Do a far better job at setting the default initial video standard
The v4l tveeprom logic tells us what video standards are supported by the hardware, however it doesn't directly tell us what should be the preferred initial standard. For example "NTSC/NTSC-J" devices are reported by tveeprom as support NTSC-M and PAL-M, and while that might be true, in the vast majority of cases NTSC-M is really what the user is going to want. However the driver previously just arbitrarily picked the "lowest numbered" standard as the initial default, which in that case would have been PAL-M. (And making matters more confusing - this only caused real problems on 24xxx devices because the saa7115 on 29xxx seems to autodetect the right answer anyway.) This change implements an algorithm that uses the set of "supported" standards as a hint to decide on the initial standard. This algorithm ONLY comes into play if the driver isn't specifically told what to do; said another way - the user can always still change the standard via the sysfs interface, via the usual V4L methods, or even specified as a module parameter. The idea here is only to pick a better starting point if the user (or app) doesn't otherwise do something to set the standard; otherwise this change has no real impact. Signed-off-by: Mike Isely <isely@pobox.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index c8ee379..20dc573 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -1694,6 +1694,44 @@ static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw)
return result == 0;
}
+struct pvr2_std_hack {
+ v4l2_std_id pat; /* Pattern to match */
+ v4l2_std_id msk; /* Which bits we care about */
+ v4l2_std_id std; /* What additional standards or default to set */
+};
+
+/* This data structure labels specific combinations of standards from
+ tveeprom that we'll try to recognize. If we recognize one, then assume
+ a specified default standard to use. This is here because tveeprom only
+ tells us about available standards not the intended default standard (if
+ any) for the device in question. We guess the default based on what has
+ been reported as available. Note that this is only for guessing a
+ default - which can always be overridden explicitly - and if the user
+ has otherwise named a default then that default will always be used in
+ place of this table. */
+const static struct pvr2_std_hack std_eeprom_maps[] = {
+ { /* PAL(B/G) */
+ .pat = V4L2_STD_B|V4L2_STD_GH,
+ .std = V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_PAL_G,
+ },
+ { /* NTSC(M) */
+ .pat = V4L2_STD_MN,
+ .std = V4L2_STD_NTSC_M,
+ },
+ { /* PAL(I) */
+ .pat = V4L2_STD_PAL_I,
+ .std = V4L2_STD_PAL_I,
+ },
+ { /* SECAM(L/L') */
+ .pat = V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC,
+ .std = V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC,
+ },
+ { /* PAL(D/D1/K) */
+ .pat = V4L2_STD_DK,
+ .std = V4L2_STD_PAL_D/V4L2_STD_PAL_D1|V4L2_STD_PAL_K,
+ },
+};
+
static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
{
char buf[40];
@@ -1732,6 +1770,27 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
return;
}
+ {
+ unsigned int idx;
+ for (idx = 0; idx < ARRAY_SIZE(std_eeprom_maps); idx++) {
+ if (std_eeprom_maps[idx].msk ?
+ ((std_eeprom_maps[idx].pat ^
+ hdw->std_mask_eeprom) &
+ std_eeprom_maps[idx].msk) :
+ (std_eeprom_maps[idx].pat !=
+ hdw->std_mask_eeprom)) continue;
+ bcnt = pvr2_std_id_to_str(buf,sizeof(buf),
+ std_eeprom_maps[idx].std);
+ pvr2_trace(PVR2_TRACE_INIT,
+ "Initial video standard guessed as %.*s",
+ bcnt,buf);
+ hdw->std_mask_cur = std_eeprom_maps[idx].std;
+ hdw->std_dirty = !0;
+ pvr2_hdw_internal_find_stdenum(hdw);
+ return;
+ }
+ }
+
if (hdw->std_enum_cnt > 1) {
// Autoselect the first listed standard
hdw->std_enum_cur = 1;
OpenPOWER on IntegriCloud