diff options
-rw-r--r-- | drivers/media/video/cx25840/cx25840-core.c | 24 | ||||
-rw-r--r-- | drivers/media/video/cx25840/cx25840-core.h | 2 | ||||
-rw-r--r-- | drivers/media/video/cx25840/cx25840-vbi.c | 155 |
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"); | |||
46 | static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; | 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 | module_param_named(debug,cx25840_debug, int, 0644); | 51 | module_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 | ||
27 | extern 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]; |