aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx25840
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-24 14:21:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-24 14:21:08 -0400
commitc328d54cd4ad120d76284e46dcca6c6cf996154a (patch)
tree104c023be66faa5fce6e0a56c0a6d13c62fd21e5 /drivers/media/video/cx25840
parent346ad4b7fe392571f19314f153db9151dbc1d82b (diff)
parentb0166ab3a6ae6d7af8d9a21a7836154963c69a11 (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.c97
-rw-r--r--drivers/media/video/cx25840/cx25840-core.h2
-rw-r--r--drivers/media/video/cx25840/cx25840-firmware.c11
-rw-r--r--drivers/media/video/cx25840/cx25840-vbi.c6
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)
352static void input_change(struct i2c_client *client) 352static 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
526static int set_v4lstd(struct i2c_client *client, v4l2_std_id std) 526static 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
570v4l2_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
604static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) 577static 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
719static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) 692static 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);
60u8 cx25840_read(struct i2c_client *client, u16 addr); 61u8 cx25840_read(struct i2c_client *client, u16 addr);
61u32 cx25840_read4(struct i2c_client *client, u16 addr); 62u32 cx25840_read4(struct i2c_client *client, u16 addr);
62int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned mask, u8 value); 63int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned mask, u8 value);
63v4l2_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
82static int fw_write(struct i2c_client *client, u8 * data, int size) 82static 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)
85void cx25840_vbi_setup(struct i2c_client *client) 85void 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];