aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2006-06-04 11:15:55 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-06-25 01:05:04 -0400
commit839e4a4acb90fd34e3f6765bef6fe03ee82dbc58 (patch)
tree50f3c4529a21ed9b149b60167263093d94bda593 /drivers/media
parentc820cc45366377a84a5f66066db4e16b7a6e5b8c (diff)
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>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c24
-rw-r--r--drivers/media/video/cx25840/cx25840-core.h2
-rw-r--r--drivers/media/video/cx25840/cx25840-vbi.c155
3 files changed, 126 insertions, 55 deletions
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 6d7207e67d6f..cb9e8625708d 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -46,7 +46,7 @@ MODULE_LICENSE("GPL");
46static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; 46static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
47 47
48 48
49static int cx25840_debug; 49int cx25840_debug;
50 50
51module_param_named(debug,cx25840_debug, int, 0644); 51module_param_named(debug,cx25840_debug, int, 0644);
52 52
@@ -251,17 +251,7 @@ static void input_change(struct i2c_client *client)
251 cx25840_and_or(client, 0x401, ~0x60, 0); 251 cx25840_and_or(client, 0x401, ~0x60, 0);
252 cx25840_and_or(client, 0x401, ~0x60, 0x60); 252 cx25840_and_or(client, 0x401, ~0x60, 0x60);
253 253
254 /* Note: perhaps V4L2_STD_PAL_M should be handled as V4L2_STD_NTSC 254 if (std & V4L2_STD_525_60) {
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) {
265 /* Certain Hauppauge PVR150 models have a hardware bug 255 /* Certain Hauppauge PVR150 models have a hardware bug
266 that causes audio to drop out. For these models the 256 that causes audio to drop out. For these models the
267 audio standard must be set explicitly. 257 audio standard must be set explicitly.
@@ -280,6 +270,14 @@ static void input_change(struct i2c_client *client)
280 cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6); 270 cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6);
281 } 271 }
282 cx25840_write(client, 0x80b, 0x00); 272 cx25840_write(client, 0x80b, 0x00);
273 } else if (std & V4L2_STD_PAL) {
274 /* Follow tuner change procedure for PAL */
275 cx25840_write(client, 0x808, 0xff);
276 cx25840_write(client, 0x80b, 0x10);
277 } else if (std & V4L2_STD_SECAM) {
278 /* Select autodetect for SECAM */
279 cx25840_write(client, 0x808, 0xff);
280 cx25840_write(client, 0x80b, 0x10);
283 } 281 }
284 282
285 if (cx25840_read(client, 0x803) & 0x10) { 283 if (cx25840_read(client, 0x803) & 0x10) {
@@ -387,6 +385,8 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std)
387 } 385 }
388 } 386 }
389 387
388 v4l_dbg(1, cx25840_debug, client, "changing video std to fmt %i\n",fmt);
389
390 /* Follow step 9 of section 3.16 in the cx25840 datasheet. 390 /* Follow step 9 of section 3.16 in the cx25840 datasheet.
391 Without this PAL may display a vertical ghosting effect. 391 Without this PAL may display a vertical ghosting effect.
392 This happens for example with the Yuan MPC622. */ 392 This happens for example with the Yuan MPC622. */
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h
index b1321920dfe7..28049064dd7d 100644
--- a/drivers/media/video/cx25840/cx25840-core.h
+++ b/drivers/media/video/cx25840/cx25840-core.h
@@ -24,6 +24,8 @@
24#include <linux/videodev2.h> 24#include <linux/videodev2.h>
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26 26
27extern int cx25840_debug;
28
27/* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is 29/* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is
28 present in Hauppauge PVR-150 (and possibly PVR-500) cards that have 30 present in Hauppauge PVR-150 (and possibly PVR-500) cards that have
29 certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The 31 certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c
index c124974c55b1..6cc8bf215e85 100644
--- a/drivers/media/video/cx25840/cx25840-vbi.c
+++ b/drivers/media/video/cx25840/cx25840-vbi.c
@@ -86,61 +86,130 @@ void cx25840_vbi_setup(struct i2c_client *client)
86{ 86{
87 struct cx25840_state *state = i2c_get_clientdata(client); 87 struct cx25840_state *state = i2c_get_clientdata(client);
88 v4l2_std_id std = cx25840_get_v4lstd(client); 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 if (std & ~V4L2_STD_NTSC) { 94 if (std & ~V4L2_STD_NTSC) {
91 /* datasheet startup, step 8d */
92 cx25840_write(client, 0x49f, 0x11); 95 cx25840_write(client, 0x49f, 0x11);
96 } else {
97 cx25840_write(client, 0x49f, 0x14);
98 }
93 99
94 cx25840_write(client, 0x470, 0x84); 100 if (std & V4L2_STD_625_50) {
95 cx25840_write(client, 0x471, 0x00); 101 hblank=0x084;
96 cx25840_write(client, 0x472, 0x2d); 102 hactive=0x2d0;
97 cx25840_write(client, 0x473, 0x5d); 103 burst=0x5d;
98 104 vblank=0x024;
99 cx25840_write(client, 0x474, 0x24); 105 vactive=0x244;
100 cx25840_write(client, 0x475, 0x40); 106 vblank656=0x28;
101 cx25840_write(client, 0x476, 0x24); 107 src_decimation=0x21f;
102 cx25840_write(client, 0x477, 0x28);
103
104 cx25840_write(client, 0x478, 0x1f);
105 cx25840_write(client, 0x479, 0x02);
106 108
109 luma_lpf=2;
107 if (std & V4L2_STD_SECAM) { 110 if (std & V4L2_STD_SECAM) {
108 cx25840_write(client, 0x47a, 0x80); 111 uv_lpf=0;
109 cx25840_write(client, 0x47b, 0x00); 112 comb=0;
110 cx25840_write(client, 0x47c, 0x5f); 113 sc=0x0a425f;
111 cx25840_write(client, 0x47d, 0x42);
112 } else { 114 } else {
113 cx25840_write(client, 0x47a, 0x90); 115 uv_lpf=1;
114 cx25840_write(client, 0x47b, 0x20); 116 comb=0x20;
115 cx25840_write(client, 0x47c, 0x63); 117 sc=0x0a8263;
116 cx25840_write(client, 0x47d, 0x82);
117 } 118 }
118
119 cx25840_write(client, 0x47e, 0x0a);
120 cx25840_write(client, 0x47f, 0x01);
121 state->vbi_line_offset = 5;
122 } else { 119 } else {
123 /* datasheet startup, step 8d */ 120 hactive=720;
124 cx25840_write(client, 0x49f, 0x14); 121 hblank=122;
122 vactive=487;
123 luma_lpf=1;
124 uv_lpf=1;
125
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);
125 186
126 cx25840_write(client, 0x470, 0x7a); 187 /* Sets vertical blanking delay and active duration */
127 cx25840_write(client, 0x471, 0x00); 188 cx25840_write(client, 0x474, vblank);
128 cx25840_write(client, 0x472, 0x2d); 189 cx25840_write(client, 0x475, 0xff&(((vblank>>8)&0x3)|(vactive <<4)));
129 cx25840_write(client, 0x473, 0x5b); 190 cx25840_write(client, 0x476, vactive>>4);
191 cx25840_write(client, 0x477, vblank656);
130 192
131 cx25840_write(client, 0x474, 0x1a); 193 /* Sets src decimation rate */
132 cx25840_write(client, 0x475, 0x70); 194 cx25840_write(client, 0x478, 0xff&src_decimation);
133 cx25840_write(client, 0x476, 0x1e); 195 cx25840_write(client, 0x479, 0xff&(src_decimation>>8));
134 cx25840_write(client, 0x477, 0x1e);
135 196
136 cx25840_write(client, 0x478, 0x1f); 197 /* Sets Luma and UV Low pass filters */
137 cx25840_write(client, 0x479, 0x02); 198 cx25840_write(client, 0x47a, luma_lpf<<6|((uv_lpf<<4)&0x30));
138 cx25840_write(client, 0x47a, 0x50);
139 cx25840_write(client, 0x47b, 0x66);
140 199
141 cx25840_write(client, 0x47c, 0x1f); 200 /* Enables comb filters */
142 cx25840_write(client, 0x47d, 0x7c); 201 cx25840_write(client, 0x47b, comb);
143 cx25840_write(client, 0x47e, 0x08); 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) {
210 cx25840_write(client, 0x47f, 0x01);
211 state->vbi_line_offset = 5;
212 } else {
144 cx25840_write(client, 0x47f, 0x00); 213 cx25840_write(client, 0x47f, 0x00);
145 state->vbi_line_offset = 8; 214 state->vbi_line_offset = 8;
146 } 215 }
@@ -186,7 +255,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
186 255
187 case VIDIOC_S_FMT: 256 case VIDIOC_S_FMT:
188 { 257 {
189 int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC); 258 int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60);
190 int vbi_offset = is_pal ? 1 : 0; 259 int vbi_offset = is_pal ? 1 : 0;
191 int i, x; 260 int i, x;
192 u8 lcr[24]; 261 u8 lcr[24];