if (freq != 32000 && freq != 44100 && freq != 48000)
                return -EINVAL;
 
-       /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
-       cx18_av_write(cx, 0x127, 0x50);
+       /*
+        * The PLL parameters are based on the external crystal frequency that
+        * would ideally be:
+        *
+        * NTSC Color subcarrier freq * 8 =
+        *      4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
+        *
+        * The accidents of history and rationale that explain from where this
+        * combination of magic numbers originate can be found in:
+        *
+        * [1] Abrahams, I. C., "Choice of Chrominance Subcarrier Frequency in
+        * the NTSC Standards", Proceedings of the I-R-E, January 1954, pp 79-80
+        *
+        * [2] Abrahams, I. C., "The 'Frequency Interleaving' Principle in the
+        * NTSC Standards", Proceedings of the I-R-E, January 1954, pp 81-83
+        *
+        * As Mike Bradley has rightly pointed out, it's not the exact crystal
+        * frequency that matters, only that all parts of the driver and
+        * firmware are using the same value (close to the ideal value).
+        *
+        * Since I have a strong suspicion that, if the firmware ever assumes a
+        * crystal value at all, it will assume 28.636360 MHz, the crystal
+        * freq used in calculations in this driver will be:
+        *
+        *      xtal_freq = 28.636360 MHz
+        *
+        * an error of less than 0.13 ppm which is way, way better than any off
+        * the shelf crystal will have for accuracy anyway.
+        *
+        * Below I aim to run the PLLs' VCOs near 400 MHz to minimze error.
+        *
+        * Many thanks to Jeff Campbell and Mike Bradley for their extensive
+        * investigation, experimentation, testing, and suggested solutions of
+        * of audio/video sync problems with SVideo and CVBS captures.
+        */
 
        if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
                switch (freq) {
                case 32000:
-                       /* VID_PLL and AUX_PLL */
-                       cx18_av_write4(cx, 0x108, 0x1408040f);
+                       /*
+                        * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
+                        * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x20
+                        */
+                       cx18_av_write4(cx, 0x108, 0x200d040f);
+
+                       /* VID_PLL Fraction = 0x2be2fe */
+                       /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
+                       cx18_av_write4(cx, 0x10c, 0x002be2fe);
 
-                       /* AUX_PLL_FRAC */
-                       /* 0x8.9504318a * 28,636,363.636 / 0x14 = 32000 * 384 */
-                       cx18_av_write4(cx, 0x110, 0x012a0863);
+                       /* AUX_PLL Fraction = 0x176740c */
+                       /* xtal * 0xd.bb3a060/0x20 = 32000 * 384: 393 MHz p-pd*/
+                       cx18_av_write4(cx, 0x110, 0x0176740c);
 
                        /* src3/4/6_ctl */
-                       /* 0x1.f77f = (4 * 15734.26) / 32000 */
+                       /* 0x1.f77f = (4 * xtal/8*2/455) / 32000 */
                        cx18_av_write4(cx, 0x900, 0x0801f77f);
                        cx18_av_write4(cx, 0x904, 0x0801f77f);
                        cx18_av_write4(cx, 0x90c, 0x0801f77f);
 
-                       /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
-                       cx18_av_write(cx, 0x127, 0x54);
+                       /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x20 */
+                       cx18_av_write(cx, 0x127, 0x60);
 
                        /* AUD_COUNT = 0x2fff = 8 samples * 4 * 384 - 1 */
                        cx18_av_write4(cx, 0x12c, 0x11202fff);
                        break;
 
                case 44100:
-                       /* VID_PLL and AUX_PLL */
-                       cx18_av_write4(cx, 0x108, 0x1009040f);
+                       /*
+                        * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
+                        * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x18
+                        */
+                       cx18_av_write4(cx, 0x108, 0x180e040f);
+
+                       /* VID_PLL Fraction = 0x2be2fe */
+                       /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
+                       cx18_av_write4(cx, 0x10c, 0x002be2fe);
 
-                       /* AUX_PLL_FRAC */
-                       /* 0x9.7635e7 * 28,636,363.63 / 0x10 = 44100 * 384 */
-                       cx18_av_write4(cx, 0x110, 0x00ec6bce);
+                       /* AUX_PLL Fraction = 0x062a1f2 */
+                       /* xtal * 0xe.3150f90/0x18 = 44100 * 384: 406 MHz p-pd*/
+                       cx18_av_write4(cx, 0x110, 0x0062a1f2);
 
                        /* src3/4/6_ctl */
-                       /* 0x1.6d59 = (4 * 15734.26) / 44100 */
+                       /* 0x1.6d59 = (4 * xtal/8*2/455) / 44100 */
                        cx18_av_write4(cx, 0x900, 0x08016d59);
                        cx18_av_write4(cx, 0x904, 0x08016d59);
                        cx18_av_write4(cx, 0x90c, 0x08016d59);
 
+                       /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x18 */
+                       cx18_av_write(cx, 0x127, 0x58);
+
                        /* AUD_COUNT = 0x92ff = 49 samples * 2 * 384 - 1 */
                        cx18_av_write4(cx, 0x12c, 0x112092ff);
 
                        break;
 
                case 48000:
-                       /* VID_PLL and AUX_PLL */
-                       cx18_av_write4(cx, 0x108, 0x100a040f);
+                       /*
+                        * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
+                        * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x16
+                        */
+                       cx18_av_write4(cx, 0x108, 0x160e040f);
 
-                       /* AUX_PLL_FRAC */
-                       /* 0xa.4c6b6ea * 28,636,363.63 / 0x10 = 48000 * 384 */
-                       cx18_av_write4(cx, 0x110, 0x0098d6dd);
+                       /* VID_PLL Fraction = 0x2be2fe */
+                       /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
+                       cx18_av_write4(cx, 0x10c, 0x002be2fe);
+
+                       /* AUX_PLL Fraction = 0x05227ad */
+                       /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz p-pd*/
+                       cx18_av_write4(cx, 0x110, 0x005227ad);
 
                        /* src3/4/6_ctl */
-                       /* 0x1.4faa = (4 * 15734.26) / 48000 */
+                       /* 0x1.4faa = (4 * xtal/8*2/455) / 48000 */
                        cx18_av_write4(cx, 0x900, 0x08014faa);
                        cx18_av_write4(cx, 0x904, 0x08014faa);
                        cx18_av_write4(cx, 0x90c, 0x08014faa);
 
+                       /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
+                       cx18_av_write(cx, 0x127, 0x56);
+
                        /* AUD_COUNT = 0x5fff = 4 samples * 16 * 384 - 1 */
                        cx18_av_write4(cx, 0x12c, 0x11205fff);
 
        } else {
                switch (freq) {
                case 32000:
-                       /* VID_PLL and AUX_PLL */
-                       cx18_av_write4(cx, 0x108, 0x1e08040f);
+                       /*
+                        * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
+                        * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x30
+                        */
+                       cx18_av_write4(cx, 0x108, 0x300d040f);
+
+                       /* VID_PLL Fraction = 0x2be2fe */
+                       /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
+                       cx18_av_write4(cx, 0x10c, 0x002be2fe);
 
-                       /* AUX_PLL_FRAC */
-                       /* 0x8.9504318 * 28,636,363.63 / 0x1e = 32000 * 256 */
-                       cx18_av_write4(cx, 0x110, 0x012a0863);
+                       /* AUX_PLL Fraction = 0x176740c */
+                       /* xtal * 0xd.bb3a060/0x30 = 32000 * 256: 393 MHz p-pd*/
+                       cx18_av_write4(cx, 0x110, 0x0176740c);
 
                        /* src1_ctl */
                        /* 0x1.0000 = 32000/32000 */
                        cx18_av_write4(cx, 0x904, 0x08020000);
                        cx18_av_write4(cx, 0x90c, 0x08020000);
 
-                       /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
-                       cx18_av_write(cx, 0x127, 0x54);
+                       /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x30 */
+                       cx18_av_write(cx, 0x127, 0x70);
 
                        /* AUD_COUNT = 0x1fff = 8 samples * 4 * 256 - 1 */
                        cx18_av_write4(cx, 0x12c, 0x11201fff);
                        break;
 
                case 44100:
-                       /* VID_PLL and AUX_PLL */
-                       cx18_av_write4(cx, 0x108, 0x1809040f);
+                       /*
+                        * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
+                        * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x24
+                        */
+                       cx18_av_write4(cx, 0x108, 0x240e040f);
+
+                       /* VID_PLL Fraction = 0x2be2fe */
+                       /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
+                       cx18_av_write4(cx, 0x10c, 0x002be2fe);
 
-                       /* AUX_PLL_FRAC */
-                       /* 0x9.7635e74 * 28,636,363.63 / 0x18 = 44100 * 256 */
-                       cx18_av_write4(cx, 0x110, 0x00ec6bce);
+                       /* AUX_PLL Fraction = 0x062a1f2 */
+                       /* xtal * 0xe.3150f90/0x24 = 44100 * 256: 406 MHz p-pd*/
+                       cx18_av_write4(cx, 0x110, 0x0062a1f2);
 
                        /* src1_ctl */
                        /* 0x1.60cd = 44100/32000 */
                        cx18_av_write4(cx, 0x904, 0x08017385);
                        cx18_av_write4(cx, 0x90c, 0x08017385);
 
+                       /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x24 */
+                       cx18_av_write(cx, 0x127, 0x64);
+
                        /* AUD_COUNT = 0x61ff = 49 samples * 2 * 256 - 1 */
                        cx18_av_write4(cx, 0x12c, 0x112061ff);
 
                        break;
 
                case 48000:
-                       /* VID_PLL and AUX_PLL */
-                       cx18_av_write4(cx, 0x108, 0x180a040f);
+                       /*
+                        * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
+                        * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x20
+                        */
+                       cx18_av_write4(cx, 0x108, 0x200d040f);
 
-                       /* AUX_PLL_FRAC */
-                       /* 0xa.4c6b6ea * 28,636,363.63 / 0x18 = 48000 * 256 */
-                       cx18_av_write4(cx, 0x110, 0x0098d6dd);
+                       /* VID_PLL Fraction = 0x2be2fe */
+                       /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/
+                       cx18_av_write4(cx, 0x10c, 0x002be2fe);
+
+                       /* AUX_PLL Fraction = 0x176740c */
+                       /* xtal * 0xd.bb3a060/0x20 = 48000 * 256: 393 MHz p-pd*/
+                       cx18_av_write4(cx, 0x110, 0x0176740c);
 
                        /* src1_ctl */
                        /* 0x1.8000 = 48000/32000 */
                        cx18_av_write4(cx, 0x904, 0x08015555);
                        cx18_av_write4(cx, 0x90c, 0x08015555);
 
+                       /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x20 */
+                       cx18_av_write(cx, 0x127, 0x60);
+
                        /* AUD_COUNT = 0x3fff = 4 samples * 16 * 256 - 1 */
                        cx18_av_write4(cx, 0x12c, 0x11203fff);
 
 
 #include "cx18-irq.h"
 #include "cx18-firmware.h"
 #include "cx18-cards.h"
+#include "cx18-av-core.h"
 #include <linux/firmware.h>
 
 #define CX18_PROC_SOFT_RESET           0xc70010
        cx18_write_reg_expect(cx, 0x00020000, CX18_ADEC_CONTROL,
                                  0x00000000, 0x00020002);
 
-       /* The fast clock is at 200/245 MHz */
+       /*
+        * The PLL parameters are based on the external crystal frequency that
+        * would ideally be:
+        *
+        * NTSC Color subcarrier freq * 8 =
+        *      4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
+        *
+        * The accidents of history and rationale that explain from where this
+        * combination of magic numbers originate can be found in:
+        *
+        * [1] Abrahams, I. C., "Choice of Chrominance Subcarrier Frequency in
+        * the NTSC Standards", Proceedings of the I-R-E, January 1954, pp 79-80
+        *
+        * [2] Abrahams, I. C., "The 'Frequency Interleaving' Principle in the
+        * NTSC Standards", Proceedings of the I-R-E, January 1954, pp 81-83
+        *
+        * As Mike Bradley has rightly pointed out, it's not the exact crystal
+        * frequency that matters, only that all parts of the driver and
+        * firmware are using the same value (close to the ideal value).
+        *
+        * Since I have a strong suspicion that, if the firmware ever assumes a
+        * crystal value at all, it will assume 28.636360 MHz, the crystal
+        * freq used in calculations in this driver will be:
+        *
+        *      xtal_freq = 28.636360 MHz
+        *
+        * an error of less than 0.13 ppm which is way, way better than any off
+        * the shelf crystal will have for accuracy anyway.
+        *
+        * Below I aim to run the PLLs' VCOs near 400 MHz to minimze errors.
+        *
+        * Many thanks to Jeff Campbell and Mike Bradley for their extensive
+        * investigation, experimentation, testing, and suggested solutions of
+        * of audio/video sync problems with SVideo and CVBS captures.
+        */
+
+       /* the fast clock is at 200/245 MHz */
+       /* 1 * xtal_freq * 0x0d.f7df9b8 / 2 = 200 MHz: 400 MHz pre post-divide*/
+       /* 1 * xtal_freq * 0x11.1c71eb8 / 2 = 245 MHz: 490 MHz pre post-divide*/
        cx18_write_reg(cx, lowpwr ? 0xD : 0x11, CX18_FAST_CLOCK_PLL_INT);
        cx18_write_reg(cx, lowpwr ? 0x1EFBF37 : 0x038E3D7,
                                                CX18_FAST_CLOCK_PLL_FRAC);
        cx18_write_reg(cx, 4, CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH);
 
        /* set slow clock to 125/120 MHz */
-       cx18_write_reg(cx, lowpwr ? 0x11 : 0x10, CX18_SLOW_CLOCK_PLL_INT);
-       cx18_write_reg(cx, lowpwr ? 0xEBAF05 : 0x18618A8,
+       /* xtal_freq * 0x0d.1861a20 / 3 = 125 MHz: 375 MHz before post-divide */
+       /* xtal_freq * 0x0c.92493f8 / 3 = 120 MHz: 360 MHz before post-divide */
+       cx18_write_reg(cx, lowpwr ? 0xD : 0xC, CX18_SLOW_CLOCK_PLL_INT);
+       cx18_write_reg(cx, lowpwr ? 0x30C344 : 0x124927F,
                                                CX18_SLOW_CLOCK_PLL_FRAC);
-       cx18_write_reg(cx, 4, CX18_SLOW_CLOCK_PLL_POST);
+       cx18_write_reg(cx, 3, CX18_SLOW_CLOCK_PLL_POST);
 
        /* mpeg clock pll 54MHz */
+       /* xtal_freq * 0xf.15f17f0 / 8 = 54 MHz: 432 MHz before post-divide */
        cx18_write_reg(cx, 0xF, CX18_MPEG_CLOCK_PLL_INT);
-       cx18_write_reg(cx, 0x2BCFEF, CX18_MPEG_CLOCK_PLL_FRAC);
+       cx18_write_reg(cx, 0x2BE2FE, CX18_MPEG_CLOCK_PLL_FRAC);
        cx18_write_reg(cx, 8, CX18_MPEG_CLOCK_PLL_POST);
 
+       /*
+        * VDCLK  Integer = 0x0f, Post Divider = 0x04
+        * AIMCLK Integer = 0x0e, Post Divider = 0x16
+        */
+       cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
+
+       /* VDCLK Fraction = 0x2be2fe */
+       /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
+       cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
+
+       /* AIMCLK Fraction = 0x05227ad */
+       /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz before post-divide */
+       cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
+
+       /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
+       cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
+
        /* Defaults */
        /* APU = SC or SC/2 = 125/62.5 */
        /* EPU = SC = 125 */