diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-24 14:21:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-24 14:21:08 -0400 |
commit | c328d54cd4ad120d76284e46dcca6c6cf996154a (patch) | |
tree | 104c023be66faa5fce6e0a56c0a6d13c62fd21e5 /drivers/media/video/cx25840 | |
parent | 346ad4b7fe392571f19314f153db9151dbc1d82b (diff) | |
parent | b0166ab3a6ae6d7af8d9a21a7836154963c69a11 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (452 commits)
V4L/DVB (7731): tuner-xc2028: fix signal strength calculus
V4L/DVB (7730): tuner-xc2028: Fix SCODE load for MTS firmwares
V4L/DVB (7729): Fix VIDIOCGAP corruption in ivtv
V4L/DVB (7728): tea5761: bugzilla #10462: tea5761 autodetection code were broken
V4L/DVB (7726): cx23885: Enable cx23417 support on the HVR1800
V4L/DVB (7725): cx23885: Add generic cx23417 hardware encoder support
V4L/DVB (7723): pvrusb2: Clean up input selection list generation in V4L interface
V4L/DVB (7722): pvrusb2: Implement FM radio support for Gotview USB2.0 DVD 2
V4L/DVB (7721): pvrusb2: Restructure cx23416 firmware loading to have a common exit point
V4L/DVB (7720): pvrusb2: Fix bad error code on cx23416 firmware load failure
V4L/DVB (7719): pvrusb2: Implement input selection enforcement
V4L/DVB (7718): pvrusb2-dvb: update Kbuild selections
V4L/DVB (7717): pvrusb2-dvb: add DVB-T support for Hauppauge pvrusb2 model 73xxx
V4L/DVB (7716): pvrusb2: clean up global functions
V4L/DVB (7715): pvrusb2: Clean out all use of __FUNCTION__
V4L/DVB (7714): pvrusb2: Fix hang on module removal
V4L/DVB (7713): pvrusb2: Implement cleaner DVB kernel thread shutdown
V4L/DVB (7712): pvrusb2: Close connect/disconnect race
V4L/DVB (7711): pvrusb2: Fix race on module unload
V4L/DVB (7710): pvrusb2: Implement critical digital streaming quirk for onair devices
...
Diffstat (limited to 'drivers/media/video/cx25840')
-rw-r--r-- | drivers/media/video/cx25840/cx25840-core.c | 97 | ||||
-rw-r--r-- | drivers/media/video/cx25840/cx25840-core.h | 2 | ||||
-rw-r--r-- | drivers/media/video/cx25840/cx25840-firmware.c | 11 | ||||
-rw-r--r-- | drivers/media/video/cx25840/cx25840-vbi.c | 6 |
4 files changed, 48 insertions, 68 deletions
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 756a1eeb274e..7fde678b2c4a 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c | |||
@@ -352,7 +352,7 @@ static void cx23885_initialize(struct i2c_client *client) | |||
352 | static void input_change(struct i2c_client *client) | 352 | static void input_change(struct i2c_client *client) |
353 | { | 353 | { |
354 | struct cx25840_state *state = i2c_get_clientdata(client); | 354 | struct cx25840_state *state = i2c_get_clientdata(client); |
355 | v4l2_std_id std = cx25840_get_v4lstd(client); | 355 | v4l2_std_id std = state->std; |
356 | 356 | ||
357 | /* Follow step 8c and 8d of section 3.16 in the cx25840 datasheet */ | 357 | /* Follow step 8c and 8d of section 3.16 in the cx25840 datasheet */ |
358 | if (std & V4L2_STD_SECAM) { | 358 | if (std & V4L2_STD_SECAM) { |
@@ -523,32 +523,34 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp | |||
523 | 523 | ||
524 | /* ----------------------------------------------------------------------- */ | 524 | /* ----------------------------------------------------------------------- */ |
525 | 525 | ||
526 | static int set_v4lstd(struct i2c_client *client, v4l2_std_id std) | 526 | static int set_v4lstd(struct i2c_client *client) |
527 | { | 527 | { |
528 | u8 fmt=0; /* zero is autodetect */ | 528 | struct cx25840_state *state = i2c_get_clientdata(client); |
529 | u8 fmt = 0; /* zero is autodetect */ | ||
530 | u8 pal_m = 0; | ||
529 | 531 | ||
530 | /* First tests should be against specific std */ | 532 | /* First tests should be against specific std */ |
531 | if (std == V4L2_STD_NTSC_M_JP) { | 533 | if (state->std == V4L2_STD_NTSC_M_JP) { |
532 | fmt=0x2; | 534 | fmt = 0x2; |
533 | } else if (std == V4L2_STD_NTSC_443) { | 535 | } else if (state->std == V4L2_STD_NTSC_443) { |
534 | fmt=0x3; | 536 | fmt = 0x3; |
535 | } else if (std == V4L2_STD_PAL_M) { | 537 | } else if (state->std == V4L2_STD_PAL_M) { |
536 | fmt=0x5; | 538 | pal_m = 1; |
537 | } else if (std == V4L2_STD_PAL_N) { | 539 | fmt = 0x5; |
538 | fmt=0x6; | 540 | } else if (state->std == V4L2_STD_PAL_N) { |
539 | } else if (std == V4L2_STD_PAL_Nc) { | 541 | fmt = 0x6; |
540 | fmt=0x7; | 542 | } else if (state->std == V4L2_STD_PAL_Nc) { |
541 | } else if (std == V4L2_STD_PAL_60) { | 543 | fmt = 0x7; |
542 | fmt=0x8; | 544 | } else if (state->std == V4L2_STD_PAL_60) { |
545 | fmt = 0x8; | ||
543 | } else { | 546 | } else { |
544 | /* Then, test against generic ones */ | 547 | /* Then, test against generic ones */ |
545 | if (std & V4L2_STD_NTSC) { | 548 | if (state->std & V4L2_STD_NTSC) |
546 | fmt=0x1; | 549 | fmt = 0x1; |
547 | } else if (std & V4L2_STD_PAL) { | 550 | else if (state->std & V4L2_STD_PAL) |
548 | fmt=0x4; | 551 | fmt = 0x4; |
549 | } else if (std & V4L2_STD_SECAM) { | 552 | else if (state->std & V4L2_STD_SECAM) |
550 | fmt=0xc; | 553 | fmt = 0xc; |
551 | } | ||
552 | } | 554 | } |
553 | 555 | ||
554 | v4l_dbg(1, cx25840_debug, client, "changing video std to fmt %i\n",fmt); | 556 | v4l_dbg(1, cx25840_debug, client, "changing video std to fmt %i\n",fmt); |
@@ -563,42 +565,13 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std) | |||
563 | cx25840_and_or(client, 0x47b, ~6, 0); | 565 | cx25840_and_or(client, 0x47b, ~6, 0); |
564 | } | 566 | } |
565 | cx25840_and_or(client, 0x400, ~0xf, fmt); | 567 | cx25840_and_or(client, 0x400, ~0xf, fmt); |
568 | cx25840_and_or(client, 0x403, ~0x3, pal_m); | ||
566 | cx25840_vbi_setup(client); | 569 | cx25840_vbi_setup(client); |
570 | if (!state->is_cx25836) | ||
571 | input_change(client); | ||
567 | return 0; | 572 | return 0; |
568 | } | 573 | } |
569 | 574 | ||
570 | v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client) | ||
571 | { | ||
572 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
573 | /* check VID_FMT_SEL first */ | ||
574 | u8 fmt = cx25840_read(client, 0x400) & 0xf; | ||
575 | |||
576 | if (!fmt) { | ||
577 | /* check AFD_FMT_STAT if set to autodetect */ | ||
578 | fmt = cx25840_read(client, 0x40d) & 0xf; | ||
579 | } | ||
580 | |||
581 | switch (fmt) { | ||
582 | case 0x1: | ||
583 | { | ||
584 | /* if the audio std is A2-M, then this is the South Korean | ||
585 | NTSC standard */ | ||
586 | if (!state->is_cx25836 && cx25840_read(client, 0x805) == 2) | ||
587 | return V4L2_STD_NTSC_M_KR; | ||
588 | return V4L2_STD_NTSC_M; | ||
589 | } | ||
590 | case 0x2: return V4L2_STD_NTSC_M_JP; | ||
591 | case 0x3: return V4L2_STD_NTSC_443; | ||
592 | case 0x4: return V4L2_STD_PAL; | ||
593 | case 0x5: return V4L2_STD_PAL_M; | ||
594 | case 0x6: return V4L2_STD_PAL_N; | ||
595 | case 0x7: return V4L2_STD_PAL_Nc; | ||
596 | case 0x8: return V4L2_STD_PAL_60; | ||
597 | case 0xc: return V4L2_STD_SECAM; | ||
598 | default: return V4L2_STD_UNKNOWN; | ||
599 | } | ||
600 | } | ||
601 | |||
602 | /* ----------------------------------------------------------------------- */ | 575 | /* ----------------------------------------------------------------------- */ |
603 | 576 | ||
604 | static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) | 577 | static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) |
@@ -718,9 +691,10 @@ static int get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) | |||
718 | 691 | ||
719 | static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) | 692 | static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) |
720 | { | 693 | { |
694 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
721 | struct v4l2_pix_format *pix; | 695 | struct v4l2_pix_format *pix; |
722 | int HSC, VSC, Vsrc, Hsrc, filter, Vlines; | 696 | int HSC, VSC, Vsrc, Hsrc, filter, Vlines; |
723 | int is_50Hz = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60); | 697 | int is_50Hz = !(state->std & V4L2_STD_525_60); |
724 | 698 | ||
725 | switch (fmt->type) { | 699 | switch (fmt->type) { |
726 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 700 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
@@ -1096,12 +1070,15 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, | |||
1096 | } | 1070 | } |
1097 | 1071 | ||
1098 | case VIDIOC_G_STD: | 1072 | case VIDIOC_G_STD: |
1099 | *(v4l2_std_id *)arg = cx25840_get_v4lstd(client); | 1073 | *(v4l2_std_id *)arg = state->std; |
1100 | break; | 1074 | break; |
1101 | 1075 | ||
1102 | case VIDIOC_S_STD: | 1076 | case VIDIOC_S_STD: |
1077 | if (state->radio == 0 && state->std == *(v4l2_std_id *)arg) | ||
1078 | return 0; | ||
1103 | state->radio = 0; | 1079 | state->radio = 0; |
1104 | return set_v4lstd(client, *(v4l2_std_id *)arg); | 1080 | state->std = *(v4l2_std_id *)arg; |
1081 | return set_v4lstd(client); | ||
1105 | 1082 | ||
1106 | case AUDC_SET_RADIO: | 1083 | case AUDC_SET_RADIO: |
1107 | state->radio = 1; | 1084 | state->radio = 1; |
@@ -1291,6 +1268,12 @@ static int cx25840_probe(struct i2c_client *client) | |||
1291 | state->id = id; | 1268 | state->id = id; |
1292 | state->rev = device_id; | 1269 | state->rev = device_id; |
1293 | 1270 | ||
1271 | if (state->is_cx23885) { | ||
1272 | /* Drive GPIO2 direction and values */ | ||
1273 | cx25840_write(client, 0x160, 0x1d); | ||
1274 | cx25840_write(client, 0x164, 0x00); | ||
1275 | } | ||
1276 | |||
1294 | return 0; | 1277 | return 0; |
1295 | } | 1278 | } |
1296 | 1279 | ||
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h index 95093edc9186..8bf797f48b09 100644 --- a/drivers/media/video/cx25840/cx25840-core.h +++ b/drivers/media/video/cx25840/cx25840-core.h | |||
@@ -38,6 +38,7 @@ struct cx25840_state { | |||
38 | struct i2c_client *c; | 38 | struct i2c_client *c; |
39 | int pvr150_workaround; | 39 | int pvr150_workaround; |
40 | int radio; | 40 | int radio; |
41 | v4l2_std_id std; | ||
41 | enum cx25840_video_input vid_input; | 42 | enum cx25840_video_input vid_input; |
42 | enum cx25840_audio_input aud_input; | 43 | enum cx25840_audio_input aud_input; |
43 | u32 audclk_freq; | 44 | u32 audclk_freq; |
@@ -60,7 +61,6 @@ int cx25840_write4(struct i2c_client *client, u16 addr, u32 value); | |||
60 | u8 cx25840_read(struct i2c_client *client, u16 addr); | 61 | u8 cx25840_read(struct i2c_client *client, u16 addr); |
61 | u32 cx25840_read4(struct i2c_client *client, u16 addr); | 62 | u32 cx25840_read4(struct i2c_client *client, u16 addr); |
62 | int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned mask, u8 value); | 63 | int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned mask, u8 value); |
63 | v4l2_std_id cx25840_get_v4lstd(struct i2c_client *client); | ||
64 | 64 | ||
65 | /* ----------------------------------------------------------------------- */ | 65 | /* ----------------------------------------------------------------------- */ |
66 | /* cx25850-firmware.c */ | 66 | /* cx25850-firmware.c */ |
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c index 1ddf724a2c74..620d295947ab 100644 --- a/drivers/media/video/cx25840/cx25840-firmware.c +++ b/drivers/media/video/cx25840/cx25840-firmware.c | |||
@@ -79,11 +79,9 @@ static int check_fw_load(struct i2c_client *client, int size) | |||
79 | return 0; | 79 | return 0; |
80 | } | 80 | } |
81 | 81 | ||
82 | static int fw_write(struct i2c_client *client, u8 * data, int size) | 82 | static int fw_write(struct i2c_client *client, u8 *data, int size) |
83 | { | 83 | { |
84 | int sent; | 84 | if (i2c_master_send(client, data, size) < size) { |
85 | |||
86 | if ((sent = i2c_master_send(client, data, size)) < size) { | ||
87 | v4l_err(client, "firmware load i2c failure\n"); | 85 | v4l_err(client, "firmware load i2c failure\n"); |
88 | return -ENOSYS; | 86 | return -ENOSYS; |
89 | } | 87 | } |
@@ -96,7 +94,7 @@ int cx25840_loadfw(struct i2c_client *client) | |||
96 | struct cx25840_state *state = i2c_get_clientdata(client); | 94 | struct cx25840_state *state = i2c_get_clientdata(client); |
97 | const struct firmware *fw = NULL; | 95 | const struct firmware *fw = NULL; |
98 | u8 buffer[4], *ptr; | 96 | u8 buffer[4], *ptr; |
99 | int size, send, retval; | 97 | int size, retval; |
100 | 98 | ||
101 | if (state->is_cx23885) | 99 | if (state->is_cx23885) |
102 | firmware = FWFILE_CX23885; | 100 | firmware = FWFILE_CX23885; |
@@ -124,8 +122,7 @@ int cx25840_loadfw(struct i2c_client *client) | |||
124 | while (size > 0) { | 122 | while (size > 0) { |
125 | ptr[0] = 0x08; | 123 | ptr[0] = 0x08; |
126 | ptr[1] = 0x02; | 124 | ptr[1] = 0x02; |
127 | send = size > (FWSEND - 2) ? FWSEND : size + 2; | 125 | retval = fw_write(client, ptr, min(FWSEND, size + 2)); |
128 | retval = fw_write(client, ptr, send); | ||
129 | 126 | ||
130 | if (retval < 0) { | 127 | if (retval < 0) { |
131 | release_firmware(fw); | 128 | release_firmware(fw); |
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c index 6828f59b9d83..c754b9d13369 100644 --- a/drivers/media/video/cx25840/cx25840-vbi.c +++ b/drivers/media/video/cx25840/cx25840-vbi.c | |||
@@ -85,7 +85,7 @@ static int decode_vps(u8 * dst, u8 * p) | |||
85 | void cx25840_vbi_setup(struct i2c_client *client) | 85 | 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 = state->std; |
89 | int hblank,hactive,burst,vblank,vactive,sc,vblank656,src_decimation; | 89 | int hblank,hactive,burst,vblank,vactive,sc,vblank656,src_decimation; |
90 | int luma_lpf,uv_lpf, comb; | 90 | int luma_lpf,uv_lpf, comb; |
91 | u32 pll_int,pll_frac,pll_post; | 91 | u32 pll_int,pll_frac,pll_post; |
@@ -242,7 +242,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) | |||
242 | 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ | 242 | 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ |
243 | 0, 0, 0, 0 | 243 | 0, 0, 0, 0 |
244 | }; | 244 | }; |
245 | int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60); | 245 | int is_pal = !(state->std & V4L2_STD_525_60); |
246 | int i; | 246 | int i; |
247 | 247 | ||
248 | fmt = arg; | 248 | fmt = arg; |
@@ -279,7 +279,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) | |||
279 | 279 | ||
280 | case VIDIOC_S_FMT: | 280 | case VIDIOC_S_FMT: |
281 | { | 281 | { |
282 | int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60); | 282 | int is_pal = !(state->std & V4L2_STD_525_60); |
283 | int vbi_offset = is_pal ? 1 : 0; | 283 | int vbi_offset = is_pal ? 1 : 0; |
284 | int i, x; | 284 | int i, x; |
285 | u8 lcr[24]; | 285 | u8 lcr[24]; |