Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

V4L/DVB (4067): Fixed cx25840 to work with PAL/M

Sub-carrier frequency for PAL/M is slicely different than NTSC/M.
Without this patch, colors don't work on PAL/M.
Setting method also improved to allow other video standards to be included.

Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>

+127 -56
+12 -12
drivers/media/video/cx25840/cx25840-core.c
··· 46 46 static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; 47 47 48 48 49 - static int cx25840_debug; 49 + int cx25840_debug; 50 50 51 51 module_param_named(debug,cx25840_debug, int, 0644); 52 52 ··· 251 251 cx25840_and_or(client, 0x401, ~0x60, 0); 252 252 cx25840_and_or(client, 0x401, ~0x60, 0x60); 253 253 254 - /* Note: perhaps V4L2_STD_PAL_M should be handled as V4L2_STD_NTSC 255 - instead of V4L2_STD_PAL. Someone needs to test this. */ 256 - if (std & V4L2_STD_PAL) { 257 - /* Follow tuner change procedure for PAL */ 258 - cx25840_write(client, 0x808, 0xff); 259 - cx25840_write(client, 0x80b, 0x10); 260 - } else if (std & V4L2_STD_SECAM) { 261 - /* Select autodetect for SECAM */ 262 - cx25840_write(client, 0x808, 0xff); 263 - cx25840_write(client, 0x80b, 0x10); 264 - } else if (std & V4L2_STD_NTSC) { 254 + if (std & V4L2_STD_525_60) { 265 255 /* Certain Hauppauge PVR150 models have a hardware bug 266 256 that causes audio to drop out. For these models the 267 257 audio standard must be set explicitly. ··· 270 280 cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6); 271 281 } 272 282 cx25840_write(client, 0x80b, 0x00); 283 + } else if (std & V4L2_STD_PAL) { 284 + /* Follow tuner change procedure for PAL */ 285 + cx25840_write(client, 0x808, 0xff); 286 + cx25840_write(client, 0x80b, 0x10); 287 + } else if (std & V4L2_STD_SECAM) { 288 + /* Select autodetect for SECAM */ 289 + cx25840_write(client, 0x808, 0xff); 290 + cx25840_write(client, 0x80b, 0x10); 273 291 } 274 292 275 293 if (cx25840_read(client, 0x803) & 0x10) { ··· 384 386 fmt=0xc; 385 387 } 386 388 } 389 + 390 + v4l_dbg(1, cx25840_debug, client, "changing video std to fmt %i\n",fmt); 387 391 388 392 /* Follow step 9 of section 3.16 in the cx25840 datasheet. 389 393 Without this PAL may display a vertical ghosting effect.
+2
drivers/media/video/cx25840/cx25840-core.h
··· 24 24 #include <linux/videodev2.h> 25 25 #include <linux/i2c.h> 26 26 27 + extern int cx25840_debug; 28 + 27 29 /* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is 28 30 present in Hauppauge PVR-150 (and possibly PVR-500) cards that have 29 31 certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The
+113 -44
drivers/media/video/cx25840/cx25840-vbi.c
··· 86 86 { 87 87 struct cx25840_state *state = i2c_get_clientdata(client); 88 88 v4l2_std_id std = cx25840_get_v4lstd(client); 89 + int hblank,hactive,burst,vblank,vactive,sc,vblank656,src_decimation; 90 + int luma_lpf,uv_lpf, comb; 91 + u32 pll_int,pll_frac,pll_post; 89 92 93 + /* datasheet startup, step 8d */ 90 94 if (std & ~V4L2_STD_NTSC) { 91 - /* datasheet startup, step 8d */ 92 95 cx25840_write(client, 0x49f, 0x11); 96 + } else { 97 + cx25840_write(client, 0x49f, 0x14); 98 + } 93 99 94 - cx25840_write(client, 0x470, 0x84); 95 - cx25840_write(client, 0x471, 0x00); 96 - cx25840_write(client, 0x472, 0x2d); 97 - cx25840_write(client, 0x473, 0x5d); 100 + if (std & V4L2_STD_625_50) { 101 + hblank=0x084; 102 + hactive=0x2d0; 103 + burst=0x5d; 104 + vblank=0x024; 105 + vactive=0x244; 106 + vblank656=0x28; 107 + src_decimation=0x21f; 98 108 99 - cx25840_write(client, 0x474, 0x24); 100 - cx25840_write(client, 0x475, 0x40); 101 - cx25840_write(client, 0x476, 0x24); 102 - cx25840_write(client, 0x477, 0x28); 103 - 104 - cx25840_write(client, 0x478, 0x1f); 105 - cx25840_write(client, 0x479, 0x02); 106 - 109 + luma_lpf=2; 107 110 if (std & V4L2_STD_SECAM) { 108 - cx25840_write(client, 0x47a, 0x80); 109 - cx25840_write(client, 0x47b, 0x00); 110 - cx25840_write(client, 0x47c, 0x5f); 111 - cx25840_write(client, 0x47d, 0x42); 111 + uv_lpf=0; 112 + comb=0; 113 + sc=0x0a425f; 112 114 } else { 113 - cx25840_write(client, 0x47a, 0x90); 114 - cx25840_write(client, 0x47b, 0x20); 115 - cx25840_write(client, 0x47c, 0x63); 116 - cx25840_write(client, 0x47d, 0x82); 115 + uv_lpf=1; 116 + comb=0x20; 117 + sc=0x0a8263; 117 118 } 119 + } else { 120 + hactive=720; 121 + hblank=122; 122 + vactive=487; 123 + luma_lpf=1; 124 + uv_lpf=1; 118 125 119 - cx25840_write(client, 0x47e, 0x0a); 126 + src_decimation=0x21f; 127 + if (std == V4L2_STD_PAL_M) { 128 + vblank=20; 129 + vblank656=24; 130 + burst=0x61; 131 + comb=0x20; 132 + 133 + sc=555452; 134 + } else { 135 + vblank=26; 136 + vblank656=26; 137 + burst=0x5b; 138 + comb=0x66; 139 + sc=556063; 140 + } 141 + } 142 + 143 + /* DEBUG: Displays configured PLL frequency */ 144 + pll_int=cx25840_read(client, 0x108); 145 + pll_frac=cx25840_read4(client, 0x10c)&0x1ffffff; 146 + pll_post=cx25840_read(client, 0x109); 147 + v4l_dbg(1, cx25840_debug, client, 148 + "PLL regs = int: %u, frac: %u, post: %u\n", 149 + pll_int,pll_frac,pll_post); 150 + 151 + if (pll_post) { 152 + int fin, fsc; 153 + int pll= (28636363L*((((u64)pll_int)<<25L)+pll_frac)) >>25L; 154 + 155 + pll/=pll_post; 156 + v4l_dbg(1, cx25840_debug, client, "PLL = %d.%06d MHz\n", 157 + pll/1000000, pll%1000000); 158 + v4l_dbg(1, cx25840_debug, client, "PLL/8 = %d.%06d MHz\n", 159 + pll/8000000, (pll/8)%1000000); 160 + 161 + fin=((u64)src_decimation*pll)>>12; 162 + v4l_dbg(1, cx25840_debug, client, "ADC Sampling freq = " 163 + "%d.%06d MHz\n", 164 + fin/1000000,fin%1000000); 165 + 166 + fsc= (((u64)sc)*pll) >> 24L; 167 + v4l_dbg(1, cx25840_debug, client, "Chroma sub-carrier freq = " 168 + "%d.%06d MHz\n", 169 + fsc/1000000,fsc%1000000); 170 + 171 + v4l_dbg(1, cx25840_debug, client, "hblank %i, hactive %i, " 172 + "vblank %i , vactive %i, vblank656 %i, src_dec %i," 173 + "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x," 174 + " sc 0x%06x\n", 175 + hblank, hactive, vblank, vactive, vblank656, 176 + src_decimation, burst, luma_lpf, uv_lpf, comb, sc); 177 + } 178 + 179 + /* Sets horizontal blanking delay and active lines */ 180 + cx25840_write(client, 0x470, hblank); 181 + cx25840_write(client, 0x471, 0xff&(((hblank>>8)&0x3)|(hactive <<4))); 182 + cx25840_write(client, 0x472, hactive>>4); 183 + 184 + /* Sets burst gate delay */ 185 + cx25840_write(client, 0x473, burst); 186 + 187 + /* Sets vertical blanking delay and active duration */ 188 + cx25840_write(client, 0x474, vblank); 189 + cx25840_write(client, 0x475, 0xff&(((vblank>>8)&0x3)|(vactive <<4))); 190 + cx25840_write(client, 0x476, vactive>>4); 191 + cx25840_write(client, 0x477, vblank656); 192 + 193 + /* Sets src decimation rate */ 194 + cx25840_write(client, 0x478, 0xff&src_decimation); 195 + cx25840_write(client, 0x479, 0xff&(src_decimation>>8)); 196 + 197 + /* Sets Luma and UV Low pass filters */ 198 + cx25840_write(client, 0x47a, luma_lpf<<6|((uv_lpf<<4)&0x30)); 199 + 200 + /* Enables comb filters */ 201 + cx25840_write(client, 0x47b, comb); 202 + 203 + /* Sets SC Step*/ 204 + cx25840_write(client, 0x47c, sc); 205 + cx25840_write(client, 0x47d, 0xff&sc>>8); 206 + cx25840_write(client, 0x47e, 0xff&sc>>16); 207 + 208 + /* Sets VBI parameters */ 209 + if (std & V4L2_STD_625_50) { 120 210 cx25840_write(client, 0x47f, 0x01); 121 211 state->vbi_line_offset = 5; 122 212 } else { 123 - /* datasheet startup, step 8d */ 124 - cx25840_write(client, 0x49f, 0x14); 125 - 126 - cx25840_write(client, 0x470, 0x7a); 127 - cx25840_write(client, 0x471, 0x00); 128 - cx25840_write(client, 0x472, 0x2d); 129 - cx25840_write(client, 0x473, 0x5b); 130 - 131 - cx25840_write(client, 0x474, 0x1a); 132 - cx25840_write(client, 0x475, 0x70); 133 - cx25840_write(client, 0x476, 0x1e); 134 - cx25840_write(client, 0x477, 0x1e); 135 - 136 - cx25840_write(client, 0x478, 0x1f); 137 - cx25840_write(client, 0x479, 0x02); 138 - cx25840_write(client, 0x47a, 0x50); 139 - cx25840_write(client, 0x47b, 0x66); 140 - 141 - cx25840_write(client, 0x47c, 0x1f); 142 - cx25840_write(client, 0x47d, 0x7c); 143 - cx25840_write(client, 0x47e, 0x08); 144 213 cx25840_write(client, 0x47f, 0x00); 145 214 state->vbi_line_offset = 8; 146 215 } ··· 255 186 256 187 case VIDIOC_S_FMT: 257 188 { 258 - int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC); 189 + int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60); 259 190 int vbi_offset = is_pal ? 1 : 0; 260 191 int i, x; 261 192 u8 lcr[24];