diff options
-rw-r--r-- | drivers/media/video/cx25840/cx25840-core.c | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 8a257978056f..bcb7ef85eb23 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c | |||
@@ -176,9 +176,9 @@ static void cx25840_initialize(struct i2c_client *client, int loadfw) | |||
176 | cx25840_write(client, 0x4a5, 0x00); | 176 | cx25840_write(client, 0x4a5, 0x00); |
177 | cx25840_write(client, 0x402, 0x00); | 177 | cx25840_write(client, 0x402, 0x00); |
178 | /* 8. */ | 178 | /* 8. */ |
179 | cx25840_write(client, 0x401, 0x18); | 179 | cx25840_and_or(client, 0x401, ~0x18, 0); |
180 | cx25840_write(client, 0x4a2, 0x10); | 180 | cx25840_and_or(client, 0x4a2, ~0x10, 0x10); |
181 | cx25840_write(client, 0x402, 0x04); | 181 | /* steps 8c and 8d are done in change_input() */ |
182 | /* 10. */ | 182 | /* 10. */ |
183 | cx25840_write(client, 0x8d3, 0x1f); | 183 | cx25840_write(client, 0x8d3, 0x1f); |
184 | cx25840_write(client, 0x8e3, 0x03); | 184 | cx25840_write(client, 0x8e3, 0x03); |
@@ -209,6 +209,17 @@ static void input_change(struct i2c_client *client) | |||
209 | struct cx25840_state *state = i2c_get_clientdata(client); | 209 | struct cx25840_state *state = i2c_get_clientdata(client); |
210 | v4l2_std_id std = cx25840_get_v4lstd(client); | 210 | v4l2_std_id std = cx25840_get_v4lstd(client); |
211 | 211 | ||
212 | /* Follow step 8c and 8d of section 3.16 in the cx25840 datasheet */ | ||
213 | if (std & V4L2_STD_SECAM) { | ||
214 | cx25840_write(client, 0x402, 0); | ||
215 | } | ||
216 | else { | ||
217 | cx25840_write(client, 0x402, 0x04); | ||
218 | cx25840_write(client, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11); | ||
219 | } | ||
220 | cx25840_and_or(client, 0x401, ~0x60, 0); | ||
221 | cx25840_and_or(client, 0x401, ~0x60, 0x60); | ||
222 | |||
212 | /* Note: perhaps V4L2_STD_PAL_M should be handled as V4L2_STD_NTSC | 223 | /* Note: perhaps V4L2_STD_PAL_M should be handled as V4L2_STD_NTSC |
213 | instead of V4L2_STD_PAL. Someone needs to test this. */ | 224 | instead of V4L2_STD_PAL. Someone needs to test this. */ |
214 | if (std & V4L2_STD_PAL) { | 225 | if (std & V4L2_STD_PAL) { |
@@ -343,6 +354,15 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std) | |||
343 | } | 354 | } |
344 | } | 355 | } |
345 | 356 | ||
357 | /* Follow step 9 of section 3.16 in the cx25840 datasheet. | ||
358 | Without this PAL may display a vertical ghosting effect. | ||
359 | This happens for example with the Yuan MPC622. */ | ||
360 | if (fmt >= 4 && fmt < 8) { | ||
361 | /* Set format to NTSC-M */ | ||
362 | cx25840_and_or(client, 0x400, ~0xf, 1); | ||
363 | /* Turn off LCOMB */ | ||
364 | cx25840_and_or(client, 0x47b, ~6, 0); | ||
365 | } | ||
346 | cx25840_and_or(client, 0x400, ~0xf, fmt); | 366 | cx25840_and_or(client, 0x400, ~0xf, fmt); |
347 | cx25840_vbi_setup(client); | 367 | cx25840_vbi_setup(client); |
348 | return 0; | 368 | return 0; |
@@ -359,7 +379,14 @@ v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client) | |||
359 | } | 379 | } |
360 | 380 | ||
361 | switch (fmt) { | 381 | switch (fmt) { |
362 | case 0x1: return V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR; | 382 | case 0x1: |
383 | { | ||
384 | /* if the audio std is A2-M, then this is the South Korean | ||
385 | NTSC standard */ | ||
386 | if (cx25840_read(client, 0x805) == 2) | ||
387 | return V4L2_STD_NTSC_M_KR; | ||
388 | return V4L2_STD_NTSC_M; | ||
389 | } | ||
363 | case 0x2: return V4L2_STD_NTSC_M_JP; | 390 | case 0x2: return V4L2_STD_NTSC_M_JP; |
364 | case 0x3: return V4L2_STD_NTSC_443; | 391 | case 0x3: return V4L2_STD_NTSC_443; |
365 | case 0x4: return V4L2_STD_PAL; | 392 | case 0x4: return V4L2_STD_PAL; |