From e17d787c513f41f59969247062561fff6340f211 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 20 Jun 2009 14:45:52 -0300 Subject: V4L/DVB (12118): pvrusb2: Fix hardware scaling when used with cx25840 The cx25840 module requires that its VBI initialization entry point be called in order for hardware-scaled video capture to work properly - even if we don't care about VBI. Making this behavior even more subtle is that if the capture resolution is set to 720x480 - which is the default that the pvrusb2 driver sets up - then the cx25840 bypasses the hardware scaler. Therefore this problem does not manifest itself until some other resolution, e.g. 640x480, is tried. MythTV typically defaults to 640x480 or 480x480, which means that things break whenever the driver is used with MythTV. This all has been known for a while (since at least Nov 2006), but recent changes in the pvrusb2 driver (specifically in regards to sub-device support) caused this to break again. VBI initialization must happen *after* the chip's firmware is loaded, not before. With this fix, 24xxx devices work correctly again. A related fix that is part of this changeset is that now we re-initialize VBI any time after we issue a reset to the cx25840 driver. Issuing a chip reset erases the state that the VBI setup previously did. Until the HVR-1950 came along this subtlety went unnoticed, because the pvrusb2 driver previously never issued such a reset. But with the HVR-1950 we have to do that reset in order to correctly transition from digital back to analog mode - and since the HVR-1950 always starts in digital mode (required for the DVB side to initialize correctly) then this device has never had a chance to work correctly in analog mode! Analog capture on the HVR-1950 has been broken this *ENTIRE* time. I had missed it until now because I've usually been testing at the default 720x480 resolution which does not require scaling... What fun. By re-initializing VBI after a cx25840 chip reset, correct behavior is restored. Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-hdw.c | 55 +++++++++++++++++-------------- 1 file changed, 31 insertions(+), 24 deletions(-) (limited to 'drivers/media/video/pvrusb2/pvrusb2-hdw.c') diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 0c745b142fb..e97f8e0e466 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -1987,6 +1987,34 @@ static unsigned int pvr2_copy_i2c_addr_list( } +static void pvr2_hdw_cx25840_vbi_hack(struct pvr2_hdw *hdw) +{ + /* + Mike Isely 19-Nov-2006 - This bit of nuttiness + for cx25840 causes that module to correctly set up its video + scaling. This is really a problem in the cx25840 module itself, + but we work around it here. The problem has not been seen in + ivtv because there VBI is supported and set up. We don't do VBI + here (at least not yet) and thus we never attempted to even set + it up. + */ + struct v4l2_format fmt; + if (hdw->decoder_client_id != PVR2_CLIENT_ID_CX25840) { + /* We're not using a cx25840 so don't enable the hack */ + return; + } + + pvr2_trace(PVR2_TRACE_INIT, + "Module ID %u:" + " Executing cx25840 VBI hack", + hdw->decoder_client_id); + memset(&fmt, 0, sizeof(fmt)); + fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; + v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id, + video, s_fmt, &fmt); +} + + static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw, const struct pvr2_device_client_desc *cd) { @@ -2078,30 +2106,6 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw, /* client-specific setup... */ switch (mid) { case PVR2_CLIENT_ID_CX25840: - hdw->decoder_client_id = mid; - { - /* - Mike Isely 19-Nov-2006 - This - bit of nuttiness for cx25840 causes that module - to correctly set up its video scaling. This is - really a problem in the cx25840 module itself, - but we work around it here. The problem has not - been seen in ivtv because there VBI is supported - and set up. We don't do VBI here (at least not - yet) and thus we never attempted to even set it - up. - */ - struct v4l2_format fmt; - pvr2_trace(PVR2_TRACE_INIT, - "Module ID %u:" - " Executing cx25840 VBI hack", - mid); - memset(&fmt, 0, sizeof(fmt)); - fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; - v4l2_device_call_all(&hdw->v4l2_dev, mid, - video, s_fmt, &fmt); - } - break; case PVR2_CLIENT_ID_SAA7115: hdw->decoder_client_id = mid; break; @@ -2202,6 +2206,8 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) cptr->info->set_value(cptr,~0,cptr->info->default_value); } + pvr2_hdw_cx25840_vbi_hack(hdw); + /* Set up special default values for the television and radio frequencies here. It's not really important what these defaults are, but I set them to something usable in the Chicago area just @@ -4076,6 +4082,7 @@ int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw) if (hdw->decoder_client_id) { v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id, core, reset, 0); + pvr2_hdw_cx25840_vbi_hack(hdw); return 0; } pvr2_trace(PVR2_TRACE_INIT, -- cgit v1.2.3 From a6862da2f3c7ce3ec6644958bc8937b630b9e2c1 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 20 Jun 2009 14:50:14 -0300 Subject: V4L/DVB (12119): pvrusb2: Re-fix hardware scaling on video standard change The cx25840 module's VBI initialization logic uses the current video standard as part of its internal algorithm. This therefore means that we probably need to make sure that the correct video standard has been set before initializing VBI. (Normally we would not care about VBI, but as described in an earlier changeset, VBI must be initialized correctly on the cx25840 in order for the chip's hardware scaler to operate correctly.) It's kind of messy to force the video standard to be set before initializing VBI (mainly because we can't know what the app really wants that early in the initialization process). So this patch does the next best thing: VBI is re-initialized after any point where the video standard has been set. Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-hdw.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media/video/pvrusb2/pvrusb2-hdw.c') diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index e97f8e0e466..44da3f9b5b6 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -2960,6 +2960,7 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw) vs = hdw->std_mask_cur; v4l2_device_call_all(&hdw->v4l2_dev, 0, core, s_std, vs); + pvr2_hdw_cx25840_vbi_hack(hdw); } hdw->tuner_signal_stale = !0; hdw->cropcap_stale = !0; -- cgit v1.2.3 From 6f441ed78e28ea02940e58ffa89fbbc734ab6da3 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 20 Jun 2009 14:51:29 -0300 Subject: V4L/DVB (12120): pvrusb2: Change initial default frequency setting Change default frequency to be US Broadcast channel 3 - with the transition to d igital the previous value has now become useless. This change is PURELY to help with my testing (I need to set some kind of default so it might as well be some thing usable). Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-hdw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/video/pvrusb2/pvrusb2-hdw.c') diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 44da3f9b5b6..cbc388729d7 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -85,8 +85,8 @@ MODULE_PARM_DESC(video_std,"specify initial video standard"); module_param_array(tolerance, int, NULL, 0444); MODULE_PARM_DESC(tolerance,"specify stream error tolerance"); -/* US Broadcast channel 7 (175.25 MHz) */ -static int default_tv_freq = 175250000L; +/* US Broadcast channel 3 (61.25 MHz), to help with testing */ +static int default_tv_freq = 61250000L; /* 104.3 MHz, a usable FM station for my area */ static int default_radio_freq = 104300000L; -- cgit v1.2.3