aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2006-12-17 21:30:47 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-12-27 11:19:26 -0500
commit315eb962d2e9438bc10da2488b604f04a1c0006f (patch)
treedc72d7f95e3b69cf5955fa3eeaeafcb0e4ae873d
parented00b41dc8bc286682d31ad64060ccc70513e90b (diff)
V4L/DVB (4980): Fixes bug 7267: PAL/60 is not working
On cx88 driver, sampling rate should be at chroma subcarrier freq (FSC). However, driver were programming wrong values for PAL/60, PAL/Nc and NTSC 4.43. This patch do the proper calculation. It also calculates htotal, hdelay and hactive constants, according with the sampling rate. It is tested with PAL/60 by Piotr Maksymuk and Olivier. Also tested with the already-supported standards. Test is still required for PAL/Nc. Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/video/cx88/cx88-core.c35
-rw-r--r--drivers/media/video/cx88/cx88.h2
2 files changed, 23 insertions, 14 deletions
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 453af5e943ff..18997361c75a 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -633,12 +633,12 @@ int cx88_reset(struct cx88_core *core)
633 633
634static unsigned int inline norm_swidth(struct cx88_tvnorm *norm) 634static unsigned int inline norm_swidth(struct cx88_tvnorm *norm)
635{ 635{
636 return (norm->id & V4L2_STD_625_50) ? 922 : 754; 636 return (norm->id & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922;
637} 637}
638 638
639static unsigned int inline norm_hdelay(struct cx88_tvnorm *norm) 639static unsigned int inline norm_hdelay(struct cx88_tvnorm *norm)
640{ 640{
641 return (norm->id & V4L2_STD_625_50) ? 186 : 135; 641 return (norm->id & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 135 : 186;
642} 642}
643 643
644static unsigned int inline norm_vdelay(struct cx88_tvnorm *norm) 644static unsigned int inline norm_vdelay(struct cx88_tvnorm *norm)
@@ -648,24 +648,33 @@ static unsigned int inline norm_vdelay(struct cx88_tvnorm *norm)
648 648
649static unsigned int inline norm_fsc8(struct cx88_tvnorm *norm) 649static unsigned int inline norm_fsc8(struct cx88_tvnorm *norm)
650{ 650{
651 static const unsigned int ntsc = 28636360;
652 static const unsigned int pal = 35468950;
653 static const unsigned int palm = 28604892;
654
655 if (norm->id & V4L2_STD_PAL_M) 651 if (norm->id & V4L2_STD_PAL_M)
656 return palm; 652 return 28604892; // 3.575611 MHz
653
654 if (norm->id & (V4L2_STD_PAL_Nc))
655 return 28656448; // 3.582056 MHz
656
657 if (norm->id & V4L2_STD_NTSC) // All NTSC/M and variants
658 return 28636360; // 3.57954545 MHz +/- 10 Hz
657 659
658 return (norm->id & V4L2_STD_625_50) ? pal : ntsc; 660 /* SECAM have also different sub carrier for chroma,
661 but step_db and step_dr, at cx88_set_tvnorm already handles that.
662
663 The same FSC applies to PAL/BGDKIH, PAL/60, NTSC/4.43 and PAL/N
664 */
665
666 return 35468950; // 4.43361875 MHz +/- 5 Hz
659} 667}
660 668
661static unsigned int inline norm_htotal(struct cx88_tvnorm *norm) 669static unsigned int inline norm_htotal(struct cx88_tvnorm *norm)
662{ 670{
663 /* Should always be Line Draw Time / (4*FSC) */
664 671
665 if (norm->id & V4L2_STD_PAL_M) 672 unsigned int fsc4=norm_fsc8(norm)/2;
666 return 909;
667 673
668 return (norm->id & V4L2_STD_625_50) ? 1135 : 910; 674 /* returns 4*FSC / vtotal / frames per seconds */
675 return (norm->id & V4L2_STD_625_50) ?
676 ((fsc4+312)/625+12)/25 :
677 ((fsc4+262)/525*1001+15000)/30000;
669} 678}
670 679
671static unsigned int inline norm_vbipack(struct cx88_tvnorm *norm) 680static unsigned int inline norm_vbipack(struct cx88_tvnorm *norm)
@@ -692,7 +701,7 @@ int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int heig
692 value &= 0x3fe; 701 value &= 0x3fe;
693 cx_write(MO_HDELAY_EVEN, value); 702 cx_write(MO_HDELAY_EVEN, value);
694 cx_write(MO_HDELAY_ODD, value); 703 cx_write(MO_HDELAY_ODD, value);
695 dprintk(1,"set_scale: hdelay 0x%04x\n", value); 704 dprintk(1,"set_scale: hdelay 0x%04x (width %d)\n", value,swidth);
696 705
697 value = (swidth * 4096 / width) - 4096; 706 value = (swidth * 4096 / width) - 4096;
698 cx_write(MO_HSCALE_EVEN, value); 707 cx_write(MO_HSCALE_EVEN, value);
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 7054e941f1d7..a9575ad8ca27 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -91,7 +91,7 @@ struct cx88_tvnorm {
91 91
92static unsigned int inline norm_maxw(struct cx88_tvnorm *norm) 92static unsigned int inline norm_maxw(struct cx88_tvnorm *norm)
93{ 93{
94 return (norm->id & V4L2_STD_625_50) ? 768 : 640; 94 return (norm->id & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 720 : 768;
95} 95}
96 96
97 97