diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-12-17 21:30:47 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-12-27 11:19:26 -0500 |
commit | 315eb962d2e9438bc10da2488b604f04a1c0006f (patch) | |
tree | dc72d7f95e3b69cf5955fa3eeaeafcb0e4ae873d | |
parent | ed00b41dc8bc286682d31ad64060ccc70513e90b (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.c | 35 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88.h | 2 |
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 | ||
634 | static unsigned int inline norm_swidth(struct cx88_tvnorm *norm) | 634 | static 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 | ||
639 | static unsigned int inline norm_hdelay(struct cx88_tvnorm *norm) | 639 | static 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 | ||
644 | static unsigned int inline norm_vdelay(struct cx88_tvnorm *norm) | 644 | static 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 | ||
649 | static unsigned int inline norm_fsc8(struct cx88_tvnorm *norm) | 649 | static 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 | ||
661 | static unsigned int inline norm_htotal(struct cx88_tvnorm *norm) | 669 | static 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 | ||
671 | static unsigned int inline norm_vbipack(struct cx88_tvnorm *norm) | 680 | static 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 | ||
92 | static unsigned int inline norm_maxw(struct cx88_tvnorm *norm) | 92 | static 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 | ||