aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx25840/cx25840-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx25840/cx25840-core.c')
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c306
1 files changed, 152 insertions, 154 deletions
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index a961bb2ab0fd..5c2036b40ea1 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -10,6 +10,9 @@
10 * 10 *
11 * VBI support by Hans Verkuil <hverkuil@xs4all.nl>. 11 * VBI support by Hans Verkuil <hverkuil@xs4all.nl>.
12 * 12 *
13 * NTSC sliced VBI support by Christopher Neufeld <television@cneufeld.ca>
14 * with additional fixes by Hans Verkuil <hverkuil@xs4all.nl>.
15 *
13 * This program is free software; you can redistribute it and/or 16 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License 17 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2 18 * as published by the Free Software Foundation; either version 2
@@ -43,7 +46,7 @@ MODULE_LICENSE("GPL");
43static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; 46static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
44 47
45 48
46static int cx25840_debug; 49int cx25840_debug;
47 50
48module_param_named(debug,cx25840_debug, int, 0644); 51module_param_named(debug,cx25840_debug, int, 0644);
49 52
@@ -105,7 +108,7 @@ u32 cx25840_read4(struct i2c_client * client, u16 addr)
105 (buffer[2] << 8) | buffer[3]; 108 (buffer[2] << 8) | buffer[3];
106} 109}
107 110
108int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask, 111int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned and_mask,
109 u8 or_value) 112 u8 or_value)
110{ 113{
111 return cx25840_write(client, addr, 114 return cx25840_write(client, addr,
@@ -117,7 +120,8 @@ int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask,
117 120
118static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input, 121static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
119 enum cx25840_audio_input aud_input); 122 enum cx25840_audio_input aud_input);
120static void log_status(struct i2c_client *client); 123static void log_audio_status(struct i2c_client *client);
124static void log_video_status(struct i2c_client *client);
121 125
122/* ----------------------------------------------------------------------- */ 126/* ----------------------------------------------------------------------- */
123 127
@@ -147,6 +151,33 @@ static void init_dll2(struct i2c_client *client)
147 cx25840_write(client, 0x15d, 0xe1); 151 cx25840_write(client, 0x15d, 0xe1);
148} 152}
149 153
154static void cx25836_initialize(struct i2c_client *client)
155{
156 /* reset configuration is described on page 3-77 of the CX25836 datasheet */
157 /* 2. */
158 cx25840_and_or(client, 0x000, ~0x01, 0x01);
159 cx25840_and_or(client, 0x000, ~0x01, 0x00);
160 /* 3a. */
161 cx25840_and_or(client, 0x15a, ~0x70, 0x00);
162 /* 3b. */
163 cx25840_and_or(client, 0x15b, ~0x1e, 0x06);
164 /* 3c. */
165 cx25840_and_or(client, 0x159, ~0x02, 0x02);
166 /* 3d. */
167 /* There should be a 10-us delay here, but since the
168 i2c bus already has a 10-us delay we don't need to do
169 anything */
170 /* 3e. */
171 cx25840_and_or(client, 0x159, ~0x02, 0x00);
172 /* 3f. */
173 cx25840_and_or(client, 0x159, ~0xc0, 0xc0);
174 /* 3g. */
175 cx25840_and_or(client, 0x159, ~0x01, 0x00);
176 cx25840_and_or(client, 0x159, ~0x01, 0x01);
177 /* 3h. */
178 cx25840_and_or(client, 0x15b, ~0x1e, 0x10);
179}
180
150static void cx25840_initialize(struct i2c_client *client, int loadfw) 181static void cx25840_initialize(struct i2c_client *client, int loadfw)
151{ 182{
152 struct cx25840_state *state = i2c_get_clientdata(client); 183 struct cx25840_state *state = i2c_get_clientdata(client);
@@ -220,17 +251,7 @@ static void input_change(struct i2c_client *client)
220 cx25840_and_or(client, 0x401, ~0x60, 0); 251 cx25840_and_or(client, 0x401, ~0x60, 0);
221 cx25840_and_or(client, 0x401, ~0x60, 0x60); 252 cx25840_and_or(client, 0x401, ~0x60, 0x60);
222 253
223 /* Note: perhaps V4L2_STD_PAL_M should be handled as V4L2_STD_NTSC 254 if (std & V4L2_STD_525_60) {
224 instead of V4L2_STD_PAL. Someone needs to test this. */
225 if (std & V4L2_STD_PAL) {
226 /* Follow tuner change procedure for PAL */
227 cx25840_write(client, 0x808, 0xff);
228 cx25840_write(client, 0x80b, 0x10);
229 } else if (std & V4L2_STD_SECAM) {
230 /* Select autodetect for SECAM */
231 cx25840_write(client, 0x808, 0xff);
232 cx25840_write(client, 0x80b, 0x10);
233 } else if (std & V4L2_STD_NTSC) {
234 /* Certain Hauppauge PVR150 models have a hardware bug 255 /* Certain Hauppauge PVR150 models have a hardware bug
235 that causes audio to drop out. For these models the 256 that causes audio to drop out. For these models the
236 audio standard must be set explicitly. 257 audio standard must be set explicitly.
@@ -249,6 +270,14 @@ static void input_change(struct i2c_client *client)
249 cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6); 270 cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6);
250 } 271 }
251 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);
252 } 281 }
253 282
254 if (cx25840_read(client, 0x803) & 0x10) { 283 if (cx25840_read(client, 0x803) & 0x10) {
@@ -319,8 +348,10 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
319 348
320 state->vid_input = vid_input; 349 state->vid_input = vid_input;
321 state->aud_input = aud_input; 350 state->aud_input = aud_input;
322 cx25840_audio_set_path(client); 351 if (!state->is_cx25836) {
323 input_change(client); 352 cx25840_audio_set_path(client);
353 input_change(client);
354 }
324 return 0; 355 return 0;
325} 356}
326 357
@@ -354,6 +385,8 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std)
354 } 385 }
355 } 386 }
356 387
388 v4l_dbg(1, cx25840_debug, client, "changing video std to fmt %i\n",fmt);
389
357 /* Follow step 9 of section 3.16 in the cx25840 datasheet. 390 /* Follow step 9 of section 3.16 in the cx25840 datasheet.
358 Without this PAL may display a vertical ghosting effect. 391 Without this PAL may display a vertical ghosting effect.
359 This happens for example with the Yuan MPC622. */ 392 This happens for example with the Yuan MPC622. */
@@ -370,6 +403,7 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std)
370 403
371v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client) 404v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client)
372{ 405{
406 struct cx25840_state *state = i2c_get_clientdata(client);
373 /* check VID_FMT_SEL first */ 407 /* check VID_FMT_SEL first */
374 u8 fmt = cx25840_read(client, 0x400) & 0xf; 408 u8 fmt = cx25840_read(client, 0x400) & 0xf;
375 409
@@ -383,7 +417,7 @@ v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client)
383 { 417 {
384 /* if the audio std is A2-M, then this is the South Korean 418 /* if the audio std is A2-M, then this is the South Korean
385 NTSC standard */ 419 NTSC standard */
386 if (cx25840_read(client, 0x805) == 2) 420 if (!state->is_cx25836 && cx25840_read(client, 0x805) == 2)
387 return V4L2_STD_NTSC_M_KR; 421 return V4L2_STD_NTSC_M_KR;
388 return V4L2_STD_NTSC_M; 422 return V4L2_STD_NTSC_M;
389 } 423 }
@@ -456,6 +490,8 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
456 case V4L2_CID_AUDIO_TREBLE: 490 case V4L2_CID_AUDIO_TREBLE:
457 case V4L2_CID_AUDIO_BALANCE: 491 case V4L2_CID_AUDIO_BALANCE:
458 case V4L2_CID_AUDIO_MUTE: 492 case V4L2_CID_AUDIO_MUTE:
493 if (state->is_cx25836)
494 return -EINVAL;
459 return cx25840_audio(client, VIDIOC_S_CTRL, ctrl); 495 return cx25840_audio(client, VIDIOC_S_CTRL, ctrl);
460 496
461 default: 497 default:
@@ -490,6 +526,8 @@ static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
490 case V4L2_CID_AUDIO_TREBLE: 526 case V4L2_CID_AUDIO_TREBLE:
491 case V4L2_CID_AUDIO_BALANCE: 527 case V4L2_CID_AUDIO_BALANCE:
492 case V4L2_CID_AUDIO_MUTE: 528 case V4L2_CID_AUDIO_MUTE:
529 if (state->is_cx25836)
530 return -EINVAL;
493 return cx25840_audio(client, VIDIOC_G_CTRL, ctrl); 531 return cx25840_audio(client, VIDIOC_G_CTRL, ctrl);
494 default: 532 default:
495 return -EINVAL; 533 return -EINVAL;
@@ -579,91 +617,6 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
579 617
580/* ----------------------------------------------------------------------- */ 618/* ----------------------------------------------------------------------- */
581 619
582static struct v4l2_queryctrl cx25840_qctrl[] = {
583 {
584 .id = V4L2_CID_BRIGHTNESS,
585 .type = V4L2_CTRL_TYPE_INTEGER,
586 .name = "Brightness",
587 .minimum = 0,
588 .maximum = 255,
589 .step = 1,
590 .default_value = 128,
591 .flags = 0,
592 }, {
593 .id = V4L2_CID_CONTRAST,
594 .type = V4L2_CTRL_TYPE_INTEGER,
595 .name = "Contrast",
596 .minimum = 0,
597 .maximum = 127,
598 .step = 1,
599 .default_value = 64,
600 .flags = 0,
601 }, {
602 .id = V4L2_CID_SATURATION,
603 .type = V4L2_CTRL_TYPE_INTEGER,
604 .name = "Saturation",
605 .minimum = 0,
606 .maximum = 127,
607 .step = 1,
608 .default_value = 64,
609 .flags = 0,
610 }, {
611 .id = V4L2_CID_HUE,
612 .type = V4L2_CTRL_TYPE_INTEGER,
613 .name = "Hue",
614 .minimum = -128,
615 .maximum = 127,
616 .step = 1,
617 .default_value = 0,
618 .flags = 0,
619 }, {
620 .id = V4L2_CID_AUDIO_VOLUME,
621 .type = V4L2_CTRL_TYPE_INTEGER,
622 .name = "Volume",
623 .minimum = 0,
624 .maximum = 65535,
625 .step = 65535/100,
626 .default_value = 58880,
627 .flags = 0,
628 }, {
629 .id = V4L2_CID_AUDIO_BALANCE,
630 .type = V4L2_CTRL_TYPE_INTEGER,
631 .name = "Balance",
632 .minimum = 0,
633 .maximum = 65535,
634 .step = 65535/100,
635 .default_value = 32768,
636 .flags = 0,
637 }, {
638 .id = V4L2_CID_AUDIO_MUTE,
639 .type = V4L2_CTRL_TYPE_BOOLEAN,
640 .name = "Mute",
641 .minimum = 0,
642 .maximum = 1,
643 .step = 1,
644 .default_value = 1,
645 .flags = 0,
646 }, {
647 .id = V4L2_CID_AUDIO_BASS,
648 .type = V4L2_CTRL_TYPE_INTEGER,
649 .name = "Bass",
650 .minimum = 0,
651 .maximum = 65535,
652 .step = 65535/100,
653 .default_value = 32768,
654 }, {
655 .id = V4L2_CID_AUDIO_TREBLE,
656 .type = V4L2_CTRL_TYPE_INTEGER,
657 .name = "Treble",
658 .minimum = 0,
659 .maximum = 65535,
660 .step = 65535/100,
661 .default_value = 32768,
662 },
663};
664
665/* ----------------------------------------------------------------------- */
666
667static int cx25840_command(struct i2c_client *client, unsigned int cmd, 620static int cx25840_command(struct i2c_client *client, unsigned int cmd,
668 void *arg) 621 void *arg)
669{ 622{
@@ -706,8 +659,8 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
706 659
707 case VIDIOC_STREAMON: 660 case VIDIOC_STREAMON:
708 v4l_dbg(1, cx25840_debug, client, "enable output\n"); 661 v4l_dbg(1, cx25840_debug, client, "enable output\n");
709 cx25840_write(client, 0x115, 0x8c); 662 cx25840_write(client, 0x115, state->is_cx25836 ? 0x0c : 0x8c);
710 cx25840_write(client, 0x116, 0x07); 663 cx25840_write(client, 0x116, state->is_cx25836 ? 0x04 : 0x07);
711 break; 664 break;
712 665
713 case VIDIOC_STREAMOFF: 666 case VIDIOC_STREAMOFF:
@@ -717,7 +670,9 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
717 break; 670 break;
718 671
719 case VIDIOC_LOG_STATUS: 672 case VIDIOC_LOG_STATUS:
720 log_status(client); 673 log_video_status(client);
674 if (!state->is_cx25836)
675 log_audio_status(client);
721 break; 676 break;
722 677
723 case VIDIOC_G_CTRL: 678 case VIDIOC_G_CTRL:
@@ -729,13 +684,29 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
729 case VIDIOC_QUERYCTRL: 684 case VIDIOC_QUERYCTRL:
730 { 685 {
731 struct v4l2_queryctrl *qc = arg; 686 struct v4l2_queryctrl *qc = arg;
732 int i;
733 687
734 for (i = 0; i < ARRAY_SIZE(cx25840_qctrl); i++) 688 switch (qc->id) {
735 if (qc->id && qc->id == cx25840_qctrl[i].id) { 689 case V4L2_CID_BRIGHTNESS:
736 memcpy(qc, &cx25840_qctrl[i], sizeof(*qc)); 690 case V4L2_CID_CONTRAST:
737 return 0; 691 case V4L2_CID_SATURATION:
738 } 692 case V4L2_CID_HUE:
693 return v4l2_ctrl_query_fill_std(qc);
694 default:
695 break;
696 }
697 if (state->is_cx25836)
698 return -EINVAL;
699
700 switch (qc->id) {
701 case V4L2_CID_AUDIO_VOLUME:
702 case V4L2_CID_AUDIO_MUTE:
703 case V4L2_CID_AUDIO_BALANCE:
704 case V4L2_CID_AUDIO_BASS:
705 case V4L2_CID_AUDIO_TREBLE:
706 return v4l2_ctrl_query_fill_std(qc);
707 default:
708 return -EINVAL;
709 }
739 return -EINVAL; 710 return -EINVAL;
740 } 711 }
741 712
@@ -760,31 +731,41 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
760 return set_input(client, route->input, state->aud_input); 731 return set_input(client, route->input, state->aud_input);
761 732
762 case VIDIOC_INT_G_AUDIO_ROUTING: 733 case VIDIOC_INT_G_AUDIO_ROUTING:
734 if (state->is_cx25836)
735 return -EINVAL;
763 route->input = state->aud_input; 736 route->input = state->aud_input;
764 route->output = 0; 737 route->output = 0;
765 break; 738 break;
766 739
767 case VIDIOC_INT_S_AUDIO_ROUTING: 740 case VIDIOC_INT_S_AUDIO_ROUTING:
741 if (state->is_cx25836)
742 return -EINVAL;
768 return set_input(client, state->vid_input, route->input); 743 return set_input(client, state->vid_input, route->input);
769 744
770 case VIDIOC_S_FREQUENCY: 745 case VIDIOC_S_FREQUENCY:
771 input_change(client); 746 if (!state->is_cx25836) {
747 input_change(client);
748 }
772 break; 749 break;
773 750
774 case VIDIOC_G_TUNER: 751 case VIDIOC_G_TUNER:
775 { 752 {
776 u8 mode = cx25840_read(client, 0x804); 753 u8 vpres = cx25840_read(client, 0x40e) & 0x20;
777 u8 vpres = cx25840_read(client, 0x80a) & 0x10; 754 u8 mode;
778 int val = 0; 755 int val = 0;
779 756
780 if (state->radio) 757 if (state->radio)
781 break; 758 break;
782 759
760 vt->signal = vpres ? 0xffff : 0x0;
761 if (state->is_cx25836)
762 break;
763
783 vt->capability |= 764 vt->capability |=
784 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | 765 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
785 V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; 766 V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
786 767
787 vt->signal = vpres ? 0xffff : 0x0; 768 mode = cx25840_read(client, 0x804);
788 769
789 /* get rxsubchans and audmode */ 770 /* get rxsubchans and audmode */
790 if ((mode & 0xf) == 1) 771 if ((mode & 0xf) == 1)
@@ -804,7 +785,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
804 } 785 }
805 786
806 case VIDIOC_S_TUNER: 787 case VIDIOC_S_TUNER:
807 if (state->radio) 788 if (state->radio || state->is_cx25836)
808 break; 789 break;
809 790
810 switch (vt->audmode) { 791 switch (vt->audmode) {
@@ -846,12 +827,14 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
846 return set_v4lfmt(client, (struct v4l2_format *)arg); 827 return set_v4lfmt(client, (struct v4l2_format *)arg);
847 828
848 case VIDIOC_INT_RESET: 829 case VIDIOC_INT_RESET:
849 cx25840_initialize(client, 0); 830 if (state->is_cx25836)
831 cx25836_initialize(client);
832 else
833 cx25840_initialize(client, 0);
850 break; 834 break;
851 835
852 case VIDIOC_INT_G_CHIP_IDENT: 836 case VIDIOC_INT_G_CHIP_IDENT:
853 *(enum v4l2_chip_ident *)arg = 837 *(enum v4l2_chip_ident *)arg = state->id;
854 V4L2_IDENT_CX25840 + ((cx25840_read(client, 0x100) >> 4) & 0xf);
855 break; 838 break;
856 839
857 default: 840 default:
@@ -870,6 +853,7 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
870{ 853{
871 struct i2c_client *client; 854 struct i2c_client *client;
872 struct cx25840_state *state; 855 struct cx25840_state *state;
856 enum v4l2_chip_ident id;
873 u16 device_id; 857 u16 device_id;
874 858
875 /* Check if the adapter supports the needed features 859 /* Check if the adapter supports the needed features
@@ -878,10 +862,11 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
878 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) 862 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
879 return 0; 863 return 0;
880 864
881 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); 865 state = kzalloc(sizeof(struct cx25840_state), GFP_KERNEL);
882 if (client == 0) 866 if (state == 0)
883 return -ENOMEM; 867 return -ENOMEM;
884 868
869 client = &state->c;
885 client->addr = address; 870 client->addr = address;
886 client->adapter = adapter; 871 client->adapter = adapter;
887 client->driver = &i2c_driver_cx25840; 872 client->driver = &i2c_driver_cx25840;
@@ -893,10 +878,18 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
893 device_id |= cx25840_read(client, 0x100); 878 device_id |= cx25840_read(client, 0x100);
894 879
895 /* The high byte of the device ID should be 880 /* The high byte of the device ID should be
896 * 0x84 if chip is present */ 881 * 0x83 for the cx2583x and 0x84 for the cx2584x */
897 if ((device_id & 0xff00) != 0x8400) { 882 if ((device_id & 0xff00) == 0x8300) {
883 id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
884 state->is_cx25836 = 1;
885 }
886 else if ((device_id & 0xff00) == 0x8400) {
887 id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
888 state->is_cx25836 = 0;
889 }
890 else {
898 v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n"); 891 v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n");
899 kfree(client); 892 kfree(state);
900 return 0; 893 return 0;
901 } 894 }
902 895
@@ -905,21 +898,19 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
905 (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3, 898 (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3,
906 address << 1, adapter->name); 899 address << 1, adapter->name);
907 900
908 state = kmalloc(sizeof(struct cx25840_state), GFP_KERNEL);
909 if (state == NULL) {
910 kfree(client);
911 return -ENOMEM;
912 }
913
914 i2c_set_clientdata(client, state); 901 i2c_set_clientdata(client, state);
915 memset(state, 0, sizeof(struct cx25840_state));
916 state->vid_input = CX25840_COMPOSITE7; 902 state->vid_input = CX25840_COMPOSITE7;
917 state->aud_input = CX25840_AUDIO8; 903 state->aud_input = CX25840_AUDIO8;
918 state->audclk_freq = 48000; 904 state->audclk_freq = 48000;
919 state->pvr150_workaround = 0; 905 state->pvr150_workaround = 0;
920 state->audmode = V4L2_TUNER_MODE_LANG1; 906 state->audmode = V4L2_TUNER_MODE_LANG1;
907 state->vbi_line_offset = 8;
908 state->id = id;
921 909
922 cx25840_initialize(client, 1); 910 if (state->is_cx25836)
911 cx25836_initialize(client);
912 else
913 cx25840_initialize(client, 1);
923 914
924 i2c_attach_client(client); 915 i2c_attach_client(client);
925 916
@@ -944,7 +935,6 @@ static int cx25840_detach_client(struct i2c_client *client)
944 } 935 }
945 936
946 kfree(state); 937 kfree(state);
947 kfree(client);
948 938
949 return 0; 939 return 0;
950} 940}
@@ -977,7 +967,7 @@ module_exit(m__exit);
977 967
978/* ----------------------------------------------------------------------- */ 968/* ----------------------------------------------------------------------- */
979 969
980static void log_status(struct i2c_client *client) 970static void log_video_status(struct i2c_client *client)
981{ 971{
982 static const char *const fmt_strs[] = { 972 static const char *const fmt_strs[] = {
983 "0x0", 973 "0x0",
@@ -989,9 +979,36 @@ static void log_status(struct i2c_client *client)
989 }; 979 };
990 980
991 struct cx25840_state *state = i2c_get_clientdata(client); 981 struct cx25840_state *state = i2c_get_clientdata(client);
992 u8 microctrl_vidfmt = cx25840_read(client, 0x80a);
993 u8 vidfmt_sel = cx25840_read(client, 0x400) & 0xf; 982 u8 vidfmt_sel = cx25840_read(client, 0x400) & 0xf;
994 u8 gen_stat1 = cx25840_read(client, 0x40d); 983 u8 gen_stat1 = cx25840_read(client, 0x40d);
984 u8 gen_stat2 = cx25840_read(client, 0x40e);
985 int vid_input = state->vid_input;
986
987 v4l_info(client, "Video signal: %spresent\n",
988 (gen_stat2 & 0x20) ? "" : "not ");
989 v4l_info(client, "Detected format: %s\n",
990 fmt_strs[gen_stat1 & 0xf]);
991
992 v4l_info(client, "Specified standard: %s\n",
993 vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
994
995 if (vid_input >= CX25840_COMPOSITE1 &&
996 vid_input <= CX25840_COMPOSITE8) {
997 v4l_info(client, "Specified video input: Composite %d\n",
998 vid_input - CX25840_COMPOSITE1 + 1);
999 } else {
1000 v4l_info(client, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
1001 (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
1002 }
1003
1004 v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq);
1005}
1006
1007/* ----------------------------------------------------------------------- */
1008
1009static void log_audio_status(struct i2c_client *client)
1010{
1011 struct cx25840_state *state = i2c_get_clientdata(client);
995 u8 download_ctl = cx25840_read(client, 0x803); 1012 u8 download_ctl = cx25840_read(client, 0x803);
996 u8 mod_det_stat0 = cx25840_read(client, 0x804); 1013 u8 mod_det_stat0 = cx25840_read(client, 0x804);
997 u8 mod_det_stat1 = cx25840_read(client, 0x805); 1014 u8 mod_det_stat1 = cx25840_read(client, 0x805);
@@ -999,15 +1016,9 @@ static void log_status(struct i2c_client *client)
999 u8 pref_mode = cx25840_read(client, 0x809); 1016 u8 pref_mode = cx25840_read(client, 0x809);
1000 u8 afc0 = cx25840_read(client, 0x80b); 1017 u8 afc0 = cx25840_read(client, 0x80b);
1001 u8 mute_ctl = cx25840_read(client, 0x8d3); 1018 u8 mute_ctl = cx25840_read(client, 0x8d3);
1002 int vid_input = state->vid_input;
1003 int aud_input = state->aud_input; 1019 int aud_input = state->aud_input;
1004 char *p; 1020 char *p;
1005 1021
1006 v4l_info(client, "Video signal: %spresent\n",
1007 (microctrl_vidfmt & 0x10) ? "" : "not ");
1008 v4l_info(client, "Detected format: %s\n",
1009 fmt_strs[gen_stat1 & 0xf]);
1010
1011 switch (mod_det_stat0) { 1022 switch (mod_det_stat0) {
1012 case 0x00: p = "mono"; break; 1023 case 0x00: p = "mono"; break;
1013 case 0x01: p = "stereo"; break; 1024 case 0x01: p = "stereo"; break;
@@ -1107,25 +1118,12 @@ static void log_status(struct i2c_client *client)
1107 v4l_info(client, "Configured audio system: %s\n", p); 1118 v4l_info(client, "Configured audio system: %s\n", p);
1108 } 1119 }
1109 1120
1110 v4l_info(client, "Specified standard: %s\n",
1111 vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
1112
1113 if (vid_input >= CX25840_COMPOSITE1 &&
1114 vid_input <= CX25840_COMPOSITE8) {
1115 v4l_info(client, "Specified video input: Composite %d\n",
1116 vid_input - CX25840_COMPOSITE1 + 1);
1117 } else {
1118 v4l_info(client, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
1119 (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
1120 }
1121 if (aud_input) { 1121 if (aud_input) {
1122 v4l_info(client, "Specified audio input: Tuner (In%d)\n", aud_input); 1122 v4l_info(client, "Specified audio input: Tuner (In%d)\n", aud_input);
1123 } else { 1123 } else {
1124 v4l_info(client, "Specified audio input: External\n"); 1124 v4l_info(client, "Specified audio input: External\n");
1125 } 1125 }
1126 1126
1127 v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq);
1128
1129 switch (pref_mode & 0xf) { 1127 switch (pref_mode & 0xf) {
1130 case 0: p = "mono/language A"; break; 1128 case 0: p = "mono/language A"; break;
1131 case 1: p = "language B"; break; 1129 case 1: p = "language B"; break;