aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx18')
-rw-r--r--drivers/media/video/cx18/Kconfig5
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c81
-rw-r--r--drivers/media/video/cx18/cx18-cards.c27
-rw-r--r--drivers/media/video/cx18/cx18-cards.h5
-rw-r--r--drivers/media/video/cx18/cx18-controls.c6
-rw-r--r--drivers/media/video/cx18/cx18-driver.c55
-rw-r--r--drivers/media/video/cx18/cx18-driver.h12
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c40
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c19
-rw-r--r--drivers/media/video/cx18/cx18-fileops.h9
-rw-r--r--drivers/media/video/cx18/cx18-gpio.c48
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c10
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c12
-rw-r--r--drivers/media/video/cx18/cx18-irq.c12
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c8
-rw-r--r--drivers/media/video/cx18/cx18-queue.c22
-rw-r--r--drivers/media/video/cx18/cx18-queue.h4
-rw-r--r--drivers/media/video/cx18/cx18-streams.c50
-rw-r--r--drivers/media/video/cx18/cx18-streams.h2
19 files changed, 225 insertions, 202 deletions
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig
index acc4b47f1d1d..5f942690570c 100644
--- a/drivers/media/video/cx18/Kconfig
+++ b/drivers/media/video/cx18/Kconfig
@@ -1,14 +1,17 @@
1config VIDEO_CX18 1config VIDEO_CX18
2 tristate "Conexant cx23418 MPEG encoder support" 2 tristate "Conexant cx23418 MPEG encoder support"
3 depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL 3 depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
4 depends on INPUT # due to VIDEO_IR
5 depends on HOTPLUG # due to FW_LOADER
4 select I2C_ALGOBIT 6 select I2C_ALGOBIT
5 select FW_LOADER 7 select FW_LOADER
6 select VIDEO_IR 8 select VIDEO_IR
7 select MEDIA_TUNER 9 select VIDEO_TUNER
8 select VIDEO_TVEEPROM 10 select VIDEO_TVEEPROM
9 select VIDEO_CX2341X 11 select VIDEO_CX2341X
10 select VIDEO_CS5345 12 select VIDEO_CS5345
11 select DVB_S5H1409 13 select DVB_S5H1409
14 select MEDIA_TUNER_MXL5005S
12 ---help--- 15 ---help---
13 This is a video4linux driver for Conexant cx23418 based 16 This is a video4linux driver for Conexant cx23418 based
14 PCI combo video recorder devices. 17 PCI combo video recorder devices.
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index 66864904c99b..9a26751615c6 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -182,14 +182,16 @@ static void input_change(struct cx18 *cx)
182 if (std == V4L2_STD_NTSC_M_JP) { 182 if (std == V4L2_STD_NTSC_M_JP) {
183 /* Japan uses EIAJ audio standard */ 183 /* Japan uses EIAJ audio standard */
184 cx18_av_write(cx, 0x808, 0xf7); 184 cx18_av_write(cx, 0x808, 0xf7);
185 cx18_av_write(cx, 0x80b, 0x02);
185 } else if (std == V4L2_STD_NTSC_M_KR) { 186 } else if (std == V4L2_STD_NTSC_M_KR) {
186 /* South Korea uses A2 audio standard */ 187 /* South Korea uses A2 audio standard */
187 cx18_av_write(cx, 0x808, 0xf8); 188 cx18_av_write(cx, 0x808, 0xf8);
189 cx18_av_write(cx, 0x80b, 0x03);
188 } else { 190 } else {
189 /* Others use the BTSC audio standard */ 191 /* Others use the BTSC audio standard */
190 cx18_av_write(cx, 0x808, 0xf6); 192 cx18_av_write(cx, 0x808, 0xf6);
193 cx18_av_write(cx, 0x80b, 0x01);
191 } 194 }
192 cx18_av_write(cx, 0x80b, 0x00);
193 } else if (std & V4L2_STD_PAL) { 195 } else if (std & V4L2_STD_PAL) {
194 /* Follow tuner change procedure for PAL */ 196 /* Follow tuner change procedure for PAL */
195 cx18_av_write(cx, 0x808, 0xff); 197 cx18_av_write(cx, 0x808, 0xff);
@@ -741,8 +743,8 @@ static void log_audio_status(struct cx18 *cx)
741{ 743{
742 struct cx18_av_state *state = &cx->av_state; 744 struct cx18_av_state *state = &cx->av_state;
743 u8 download_ctl = cx18_av_read(cx, 0x803); 745 u8 download_ctl = cx18_av_read(cx, 0x803);
744 u8 mod_det_stat0 = cx18_av_read(cx, 0x805); 746 u8 mod_det_stat0 = cx18_av_read(cx, 0x804);
745 u8 mod_det_stat1 = cx18_av_read(cx, 0x804); 747 u8 mod_det_stat1 = cx18_av_read(cx, 0x805);
746 u8 audio_config = cx18_av_read(cx, 0x808); 748 u8 audio_config = cx18_av_read(cx, 0x808);
747 u8 pref_mode = cx18_av_read(cx, 0x809); 749 u8 pref_mode = cx18_av_read(cx, 0x809);
748 u8 afc0 = cx18_av_read(cx, 0x80b); 750 u8 afc0 = cx18_av_read(cx, 0x80b);
@@ -760,12 +762,12 @@ static void log_audio_status(struct cx18 *cx)
760 case 0x12: p = "dual with SAP"; break; 762 case 0x12: p = "dual with SAP"; break;
761 case 0x14: p = "tri with SAP"; break; 763 case 0x14: p = "tri with SAP"; break;
762 case 0xfe: p = "forced mode"; break; 764 case 0xfe: p = "forced mode"; break;
763 default: p = "not defined"; 765 default: p = "not defined"; break;
764 } 766 }
765 CX18_INFO("Detected audio mode: %s\n", p); 767 CX18_INFO("Detected audio mode: %s\n", p);
766 768
767 switch (mod_det_stat1) { 769 switch (mod_det_stat1) {
768 case 0x00: p = "BTSC"; break; 770 case 0x00: p = "not defined"; break;
769 case 0x01: p = "EIAJ"; break; 771 case 0x01: p = "EIAJ"; break;
770 case 0x02: p = "A2-M"; break; 772 case 0x02: p = "A2-M"; break;
771 case 0x03: p = "A2-BG"; break; 773 case 0x03: p = "A2-BG"; break;
@@ -779,8 +781,13 @@ static void log_audio_status(struct cx18 *cx)
779 case 0x0b: p = "NICAM-I"; break; 781 case 0x0b: p = "NICAM-I"; break;
780 case 0x0c: p = "NICAM-L"; break; 782 case 0x0c: p = "NICAM-L"; break;
781 case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break; 783 case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break;
784 case 0x0e: p = "IF FM Radio"; break;
785 case 0x0f: p = "BTSC"; break;
786 case 0x10: p = "detected chrominance"; break;
787 case 0xfd: p = "unknown audio standard"; break;
788 case 0xfe: p = "forced audio standard"; break;
782 case 0xff: p = "no detected audio standard"; break; 789 case 0xff: p = "no detected audio standard"; break;
783 default: p = "not defined"; 790 default: p = "not defined"; break;
784 } 791 }
785 CX18_INFO("Detected audio standard: %s\n", p); 792 CX18_INFO("Detected audio standard: %s\n", p);
786 CX18_INFO("Audio muted: %s\n", 793 CX18_INFO("Audio muted: %s\n",
@@ -789,22 +796,23 @@ static void log_audio_status(struct cx18 *cx)
789 (download_ctl & 0x10) ? "running" : "stopped"); 796 (download_ctl & 0x10) ? "running" : "stopped");
790 797
791 switch (audio_config >> 4) { 798 switch (audio_config >> 4) {
792 case 0x00: p = "BTSC"; break; 799 case 0x00: p = "undefined"; break;
793 case 0x01: p = "EIAJ"; break; 800 case 0x01: p = "BTSC"; break;
794 case 0x02: p = "A2-M"; break; 801 case 0x02: p = "EIAJ"; break;
795 case 0x03: p = "A2-BG"; break; 802 case 0x03: p = "A2-M"; break;
796 case 0x04: p = "A2-DK1"; break; 803 case 0x04: p = "A2-BG"; break;
797 case 0x05: p = "A2-DK2"; break; 804 case 0x05: p = "A2-DK1"; break;
798 case 0x06: p = "A2-DK3"; break; 805 case 0x06: p = "A2-DK2"; break;
799 case 0x07: p = "A1 (6.0 MHz FM Mono)"; break; 806 case 0x07: p = "A2-DK3"; break;
800 case 0x08: p = "AM-L"; break; 807 case 0x08: p = "A1 (6.0 MHz FM Mono)"; break;
801 case 0x09: p = "NICAM-BG"; break; 808 case 0x09: p = "AM-L"; break;
802 case 0x0a: p = "NICAM-DK"; break; 809 case 0x0a: p = "NICAM-BG"; break;
803 case 0x0b: p = "NICAM-I"; break; 810 case 0x0b: p = "NICAM-DK"; break;
804 case 0x0c: p = "NICAM-L"; break; 811 case 0x0c: p = "NICAM-I"; break;
805 case 0x0d: p = "FM radio"; break; 812 case 0x0d: p = "NICAM-L"; break;
813 case 0x0e: p = "FM radio"; break;
806 case 0x0f: p = "automatic detection"; break; 814 case 0x0f: p = "automatic detection"; break;
807 default: p = "undefined"; 815 default: p = "undefined"; break;
808 } 816 }
809 CX18_INFO("Configured audio standard: %s\n", p); 817 CX18_INFO("Configured audio standard: %s\n", p);
810 818
@@ -815,12 +823,9 @@ static void log_audio_status(struct cx18 *cx)
815 case 0x02: p = "MONO3 (STEREO forced MONO)"; break; 823 case 0x02: p = "MONO3 (STEREO forced MONO)"; break;
816 case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break; 824 case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break;
817 case 0x04: p = "STEREO"; break; 825 case 0x04: p = "STEREO"; break;
818 case 0x05: p = "DUAL1 (AB)"; break; 826 case 0x05: p = "DUAL1 (AC)"; break;
819 case 0x06: p = "DUAL2 (AC) (FM)"; break; 827 case 0x06: p = "DUAL2 (BC)"; break;
820 case 0x07: p = "DUAL3 (BC) (FM)"; break; 828 case 0x07: p = "DUAL3 (AB)"; break;
821 case 0x08: p = "DUAL4 (AC) (AM)"; break;
822 case 0x09: p = "DUAL5 (BC) (AM)"; break;
823 case 0x0a: p = "SAP"; break;
824 default: p = "undefined"; 829 default: p = "undefined";
825 } 830 }
826 CX18_INFO("Configured audio mode: %s\n", p); 831 CX18_INFO("Configured audio mode: %s\n", p);
@@ -835,9 +840,11 @@ static void log_audio_status(struct cx18 *cx)
835 case 0x06: p = "BTSC"; break; 840 case 0x06: p = "BTSC"; break;
836 case 0x07: p = "EIAJ"; break; 841 case 0x07: p = "EIAJ"; break;
837 case 0x08: p = "A2-M"; break; 842 case 0x08: p = "A2-M"; break;
838 case 0x09: p = "FM Radio"; break; 843 case 0x09: p = "FM Radio (4.5 MHz)"; break;
844 case 0x0a: p = "FM Radio (5.5 MHz)"; break;
845 case 0x0b: p = "S-Video"; break;
839 case 0x0f: p = "automatic standard and mode detection"; break; 846 case 0x0f: p = "automatic standard and mode detection"; break;
840 default: p = "undefined"; 847 default: p = "undefined"; break;
841 } 848 }
842 CX18_INFO("Configured audio system: %s\n", p); 849 CX18_INFO("Configured audio system: %s\n", p);
843 } 850 }
@@ -857,22 +864,24 @@ static void log_audio_status(struct cx18 *cx)
857 case 5: p = "language AC"; break; 864 case 5: p = "language AC"; break;
858 case 6: p = "language BC"; break; 865 case 6: p = "language BC"; break;
859 case 7: p = "language AB"; break; 866 case 7: p = "language AB"; break;
860 default: p = "undefined"; 867 default: p = "undefined"; break;
861 } 868 }
862 CX18_INFO("Preferred audio mode: %s\n", p); 869 CX18_INFO("Preferred audio mode: %s\n", p);
863 870
864 if ((audio_config & 0xf) == 0xf) { 871 if ((audio_config & 0xf) == 0xf) {
865 switch ((afc0 >> 2) & 0x1) { 872 switch ((afc0 >> 3) & 0x1) {
866 case 0: p = "system DK"; break; 873 case 0: p = "system DK"; break;
867 case 1: p = "system L"; break; 874 case 1: p = "system L"; break;
868 } 875 }
869 CX18_INFO("Selected 65 MHz format: %s\n", p); 876 CX18_INFO("Selected 65 MHz format: %s\n", p);
870 877
871 switch (afc0 & 0x3) { 878 switch (afc0 & 0x7) {
872 case 0: p = "BTSC"; break; 879 case 0: p = "Chroma"; break;
873 case 1: p = "EIAJ"; break; 880 case 1: p = "BTSC"; break;
874 case 2: p = "A2-M"; break; 881 case 2: p = "EIAJ"; break;
875 default: p = "undefined"; 882 case 3: p = "A2-M"; break;
883 case 4: p = "autodetect"; break;
884 default: p = "undefined"; break;
876 } 885 }
877 CX18_INFO("Selected 45 MHz format: %s\n", p); 886 CX18_INFO("Selected 45 MHz format: %s\n", p);
878 } 887 }
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index f5e3ba1f5354..baccd079243d 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -47,11 +47,12 @@ static struct cx18_card_tuner_i2c cx18_i2c_std = {
47static const struct cx18_card cx18_card_hvr1600_esmt = { 47static const struct cx18_card cx18_card_hvr1600_esmt = {
48 .type = CX18_CARD_HVR_1600_ESMT, 48 .type = CX18_CARD_HVR_1600_ESMT,
49 .name = "Hauppauge HVR-1600", 49 .name = "Hauppauge HVR-1600",
50 .comment = "DVB & VBI are not yet supported\n", 50 .comment = "VBI is not yet supported\n",
51 .v4l2_capabilities = CX18_CAP_ENCODER, 51 .v4l2_capabilities = CX18_CAP_ENCODER,
52 .hw_audio_ctrl = CX18_HW_CX23418, 52 .hw_audio_ctrl = CX18_HW_CX23418,
53 .hw_muxer = CX18_HW_CS5345, 53 .hw_muxer = CX18_HW_CS5345,
54 .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345, 54 .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
55 CX18_HW_CS5345 | CX18_HW_DVB,
55 .video_inputs = { 56 .video_inputs = {
56 { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 }, 57 { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 },
57 { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 }, 58 { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 },
@@ -86,11 +87,12 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
86static const struct cx18_card cx18_card_hvr1600_samsung = { 87static const struct cx18_card cx18_card_hvr1600_samsung = {
87 .type = CX18_CARD_HVR_1600_SAMSUNG, 88 .type = CX18_CARD_HVR_1600_SAMSUNG,
88 .name = "Hauppauge HVR-1600 (Preproduction)", 89 .name = "Hauppauge HVR-1600 (Preproduction)",
89 .comment = "DVB & VBI are not yet supported\n", 90 .comment = "VBI is not yet supported\n",
90 .v4l2_capabilities = CX18_CAP_ENCODER, 91 .v4l2_capabilities = CX18_CAP_ENCODER,
91 .hw_audio_ctrl = CX18_HW_CX23418, 92 .hw_audio_ctrl = CX18_HW_CX23418,
92 .hw_muxer = CX18_HW_CS5345, 93 .hw_muxer = CX18_HW_CS5345,
93 .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345, 94 .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
95 CX18_HW_CS5345 | CX18_HW_DVB,
94 .video_inputs = { 96 .video_inputs = {
95 { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 }, 97 { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 },
96 { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 }, 98 { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 },
@@ -124,7 +126,7 @@ static const struct cx18_card cx18_card_hvr1600_samsung = {
124 126
125/* ------------------------------------------------------------------------- */ 127/* ------------------------------------------------------------------------- */
126 128
127/* Compro VideoMate H900: not working at the moment! */ 129/* Compro VideoMate H900: note that this card is analog only! */
128 130
129static const struct cx18_card_pci_info cx18_pci_h900[] = { 131static const struct cx18_card_pci_info cx18_pci_h900[] = {
130 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_COMPRO, 0xe100 }, 132 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_COMPRO, 0xe100 },
@@ -134,14 +136,15 @@ static const struct cx18_card_pci_info cx18_pci_h900[] = {
134static const struct cx18_card cx18_card_h900 = { 136static const struct cx18_card cx18_card_h900 = {
135 .type = CX18_CARD_COMPRO_H900, 137 .type = CX18_CARD_COMPRO_H900,
136 .name = "Compro VideoMate H900", 138 .name = "Compro VideoMate H900",
137 .comment = "Not yet supported!\n", 139 .comment = "VBI is not yet supported\n",
138 .v4l2_capabilities = 0, 140 .v4l2_capabilities = CX18_CAP_ENCODER,
139 .hw_audio_ctrl = CX18_HW_CX23418, 141 .hw_audio_ctrl = CX18_HW_CX23418,
140 .hw_all = CX18_HW_TUNER, 142 .hw_all = CX18_HW_TUNER,
141 .video_inputs = { 143 .video_inputs = {
142 { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 }, 144 { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE2 },
143 { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 }, 145 { CX18_CARD_INPUT_SVIDEO1, 1,
144 { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 }, 146 CX23418_SVIDEO_LUMA3 | CX23418_SVIDEO_CHROMA4 },
147 { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE1 },
145 }, 148 },
146 .audio_inputs = { 149 .audio_inputs = {
147 { CX18_CARD_INPUT_AUD_TUNER, 150 { CX18_CARD_INPUT_AUD_TUNER,
@@ -163,6 +166,7 @@ static const struct cx18_card cx18_card_h900 = {
163 .tune_lane = 0, 166 .tune_lane = 0,
164 .initial_emrs = 0, 167 .initial_emrs = 0,
165 }, 168 },
169 .xceive_pin = 15,
166 .pci_list = cx18_pci_h900, 170 .pci_list = cx18_pci_h900,
167 .i2c = &cx18_i2c_std, 171 .i2c = &cx18_i2c_std,
168}; 172};
@@ -200,8 +204,6 @@ static const struct cx18_card cx18_card_mpc718 = {
200 /* XC3028 tuner */ 204 /* XC3028 tuner */
201 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, 205 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
202 }, 206 },
203 /* tuner reset */
204 .gpio_init = { .direction = 0x1000, .initial_value = 0x1000 },
205 .ddr = { 207 .ddr = {
206 /* Probably Samsung K4D263238G-VC33 memory */ 208 /* Probably Samsung K4D263238G-VC33 memory */
207 .chip_config = 0x003, 209 .chip_config = 0x003,
@@ -211,6 +213,7 @@ static const struct cx18_card cx18_card_mpc718 = {
211 .tune_lane = 0, 213 .tune_lane = 0,
212 .initial_emrs = 2, 214 .initial_emrs = 2,
213 }, 215 },
216 .xceive_pin = 15,
214 .pci_list = cx18_pci_mpc718, 217 .pci_list = cx18_pci_mpc718,
215 .i2c = &cx18_i2c_std, 218 .i2c = &cx18_i2c_std,
216}; 219};
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
index bca249bdd337..bccb67f0db16 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -114,8 +114,8 @@ struct cx18_card_pci_info {
114/* The mask is the set of bits used by the operation */ 114/* The mask is the set of bits used by the operation */
115 115
116struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */ 116struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */
117 u16 direction; /* DIR setting. Leave to 0 if no init is needed */ 117 u32 direction; /* DIR setting. Leave to 0 if no init is needed */
118 u16 initial_value; 118 u32 initial_value;
119}; 119};
120 120
121struct cx18_card_tuner { 121struct cx18_card_tuner {
@@ -153,6 +153,7 @@ struct cx18_card {
153 struct cx18_card_audio_input radio_input; 153 struct cx18_card_audio_input radio_input;
154 154
155 /* GPIO card-specific settings */ 155 /* GPIO card-specific settings */
156 u8 xceive_pin; /* XCeive tuner GPIO reset pin */
156 struct cx18_gpio_init gpio_init; 157 struct cx18_gpio_init gpio_init;
157 158
158 struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS]; 159 struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS];
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
index 2bdac5ebbb0d..87cf41021665 100644
--- a/drivers/media/video/cx18/cx18-controls.c
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -159,7 +159,7 @@ static int cx18_setup_vbi_fmt(struct cx18 *cx, enum v4l2_mpeg_stream_vbi_fmt fmt
159{ 159{
160 if (!(cx->v4l2_cap & V4L2_CAP_SLICED_VBI_CAPTURE)) 160 if (!(cx->v4l2_cap & V4L2_CAP_SLICED_VBI_CAPTURE))
161 return -EINVAL; 161 return -EINVAL;
162 if (atomic_read(&cx->capturing) > 0) 162 if (atomic_read(&cx->ana_capturing) > 0)
163 return -EBUSY; 163 return -EBUSY;
164 164
165 /* First try to allocate sliced VBI buffers if needed. */ 165 /* First try to allocate sliced VBI buffers if needed. */
@@ -235,7 +235,7 @@ int cx18_control_ioctls(struct cx18 *cx, unsigned int cmd, void *arg)
235 CX18_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n"); 235 CX18_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n");
236 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) { 236 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
237 struct cx2341x_mpeg_params p = cx->params; 237 struct cx2341x_mpeg_params p = cx->params;
238 int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->capturing), arg, cmd); 238 int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->ana_capturing), arg, cmd);
239 239
240 if (err) 240 if (err)
241 return err; 241 return err;
@@ -295,7 +295,7 @@ int cx18_control_ioctls(struct cx18 *cx, unsigned int cmd, void *arg)
295 CX18_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n"); 295 CX18_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n");
296 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) 296 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
297 return cx2341x_ext_ctrls(&cx->params, 297 return cx2341x_ext_ctrls(&cx->params,
298 atomic_read(&cx->capturing), arg, cmd); 298 atomic_read(&cx->ana_capturing), arg, cmd);
299 return -EINVAL; 299 return -EINVAL;
300 } 300 }
301 301
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 3f55d47bc4b9..2b810bb2a4c7 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -164,16 +164,6 @@ MODULE_LICENSE("GPL");
164 164
165MODULE_VERSION(CX18_VERSION); 165MODULE_VERSION(CX18_VERSION);
166 166
167int cx18_waitq(wait_queue_head_t *waitq)
168{
169 DEFINE_WAIT(wait);
170
171 prepare_to_wait(waitq, &wait, TASK_INTERRUPTIBLE);
172 schedule();
173 finish_wait(waitq, &wait);
174 return signal_pending(current) ? -EINTR : 0;
175}
176
177/* Generic utility functions */ 167/* Generic utility functions */
178int cx18_msleep_timeout(unsigned int msecs, int intr) 168int cx18_msleep_timeout(unsigned int msecs, int intr)
179{ 169{
@@ -220,13 +210,13 @@ static void cx18_process_eeprom(struct cx18 *cx)
220 210
221 /* Many thanks to Steven Toth from Hauppauge for providing the 211 /* Many thanks to Steven Toth from Hauppauge for providing the
222 model numbers */ 212 model numbers */
213 /* Note: the Samsung memory models cannot be reliably determined
214 from the model number. Use the cardtype module option if you
215 have one of these preproduction models. */
223 switch (tv.model) { 216 switch (tv.model) {
224 case 74000 ... 74099: 217 case 74000 ... 74999:
225 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); 218 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
226 break; 219 break;
227 case 74700 ... 74799:
228 cx->card = cx18_get_card(CX18_CARD_HVR_1600_SAMSUNG);
229 break;
230 case 0: 220 case 0:
231 CX18_ERR("Invalid EEPROM\n"); 221 CX18_ERR("Invalid EEPROM\n");
232 return; 222 return;
@@ -548,6 +538,7 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev,
548 return 0; 538 return 0;
549} 539}
550 540
541#ifdef MODULE
551static u32 cx18_request_module(struct cx18 *cx, u32 hw, 542static u32 cx18_request_module(struct cx18 *cx, u32 hw,
552 const char *name, u32 id) 543 const char *name, u32 id)
553{ 544{
@@ -560,12 +551,14 @@ static u32 cx18_request_module(struct cx18 *cx, u32 hw,
560 CX18_DEBUG_INFO("Loaded module %s\n", name); 551 CX18_DEBUG_INFO("Loaded module %s\n", name);
561 return hw; 552 return hw;
562} 553}
554#endif
563 555
564static void cx18_load_and_init_modules(struct cx18 *cx) 556static void cx18_load_and_init_modules(struct cx18 *cx)
565{ 557{
566 u32 hw = cx->card->hw_all; 558 u32 hw = cx->card->hw_all;
567 int i; 559 int i;
568 560
561#ifdef MODULE
569 /* load modules */ 562 /* load modules */
570#ifndef CONFIG_MEDIA_TUNER 563#ifndef CONFIG_MEDIA_TUNER
571 hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER); 564 hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER);
@@ -573,6 +566,7 @@ static void cx18_load_and_init_modules(struct cx18 *cx)
573#ifndef CONFIG_VIDEO_CS5345 566#ifndef CONFIG_VIDEO_CS5345
574 hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345); 567 hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345);
575#endif 568#endif
569#endif
576 570
577 /* check which i2c devices are actually found */ 571 /* check which i2c devices are actually found */
578 for (i = 0; i < 32; i++) { 572 for (i = 0; i < 32; i++) {
@@ -676,7 +670,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
676 cx18_init_power(cx, 1); 670 cx18_init_power(cx, 1);
677 cx18_init_memory(cx); 671 cx18_init_memory(cx);
678 672
679 cx->scb = (struct cx18_scb *)(cx->enc_mem + SCB_OFFSET); 673 cx->scb = (struct cx18_scb __iomem *)(cx->enc_mem + SCB_OFFSET);
680 cx18_init_scb(cx); 674 cx18_init_scb(cx);
681 675
682 cx18_gpio_init(cx); 676 cx18_gpio_init(cx);
@@ -757,17 +751,6 @@ static int __devinit cx18_probe(struct pci_dev *dev,
757 if (cx->options.radio > 0) 751 if (cx->options.radio > 0)
758 cx->v4l2_cap |= V4L2_CAP_RADIO; 752 cx->v4l2_cap |= V4L2_CAP_RADIO;
759 753
760 retval = cx18_streams_setup(cx);
761 if (retval) {
762 CX18_ERR("Error %d setting up streams\n", retval);
763 goto free_irq;
764 }
765 retval = cx18_streams_register(cx);
766 if (retval) {
767 CX18_ERR("Error %d registering devices\n", retval);
768 goto free_streams;
769 }
770
771 if (cx->options.tuner > -1) { 754 if (cx->options.tuner > -1) {
772 struct tuner_setup setup; 755 struct tuner_setup setup;
773 756
@@ -794,14 +777,23 @@ static int __devinit cx18_probe(struct pci_dev *dev,
794 are not. */ 777 are not. */
795 cx->tuner_std = cx->std; 778 cx->tuner_std = cx->std;
796 779
797 cx18_init_on_first_open(cx); 780 retval = cx18_streams_setup(cx);
781 if (retval) {
782 CX18_ERR("Error %d setting up streams\n", retval);
783 goto free_irq;
784 }
785 retval = cx18_streams_register(cx);
786 if (retval) {
787 CX18_ERR("Error %d registering devices\n", retval);
788 goto free_streams;
789 }
798 790
799 CX18_INFO("Initialized card #%d: %s\n", cx->num, cx->card_name); 791 CX18_INFO("Initialized card #%d: %s\n", cx->num, cx->card_name);
800 792
801 return 0; 793 return 0;
802 794
803free_streams: 795free_streams:
804 cx18_streams_cleanup(cx); 796 cx18_streams_cleanup(cx, 1);
805free_irq: 797free_irq:
806 free_irq(cx->dev->irq, (void *)cx); 798 free_irq(cx->dev->irq, (void *)cx);
807free_i2c: 799free_i2c:
@@ -895,7 +887,7 @@ static void cx18_remove(struct pci_dev *pci_dev)
895 887
896 /* Stop all captures */ 888 /* Stop all captures */
897 CX18_DEBUG_INFO("Stopping all streams\n"); 889 CX18_DEBUG_INFO("Stopping all streams\n");
898 if (atomic_read(&cx->capturing) > 0) 890 if (atomic_read(&cx->tot_capturing) > 0)
899 cx18_stop_all_captures(cx); 891 cx18_stop_all_captures(cx);
900 892
901 /* Interrupts */ 893 /* Interrupts */
@@ -904,14 +896,13 @@ static void cx18_remove(struct pci_dev *pci_dev)
904 896
905 cx18_halt_firmware(cx); 897 cx18_halt_firmware(cx);
906 898
907 cx18_streams_cleanup(cx); 899 cx18_streams_cleanup(cx, 1);
908 900
909 exit_cx18_i2c(cx); 901 exit_cx18_i2c(cx);
910 902
911 free_irq(cx->dev->irq, (void *)cx); 903 free_irq(cx->dev->irq, (void *)cx);
912 904
913 if (cx->dev) 905 cx18_iounmap(cx);
914 cx18_iounmap(cx);
915 906
916 release_mem_region(cx->base_addr, CX18_MEM_SIZE); 907 release_mem_region(cx->base_addr, CX18_MEM_SIZE);
917 908
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index 2ee939193bb7..de14ab59a206 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -358,7 +358,7 @@ struct cx18 {
358 u32 v4l2_cap; /* V4L2 capabilities of card */ 358 u32 v4l2_cap; /* V4L2 capabilities of card */
359 u32 hw_flags; /* Hardware description of the board */ 359 u32 hw_flags; /* Hardware description of the board */
360 unsigned mdl_offset; 360 unsigned mdl_offset;
361 struct cx18_scb *scb; /* pointer to SCB */ 361 struct cx18_scb __iomem *scb; /* pointer to SCB */
362 362
363 struct cx18_av_state av_state; 363 struct cx18_av_state av_state;
364 364
@@ -380,7 +380,8 @@ struct cx18 {
380 int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */ 380 int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */
381 struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */ 381 struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */
382 unsigned long i_flags; /* global cx18 flags */ 382 unsigned long i_flags; /* global cx18 flags */
383 atomic_t capturing; /* count number of active capture streams */ 383 atomic_t ana_capturing; /* count number of active analog capture streams */
384 atomic_t tot_capturing; /* total count number of active capture streams */
384 spinlock_t lock; /* lock access to this struct */ 385 spinlock_t lock; /* lock access to this struct */
385 int search_pack_header; 386 int search_pack_header;
386 387
@@ -423,6 +424,10 @@ struct cx18 {
423 struct mutex i2c_bus_lock[2]; 424 struct mutex i2c_bus_lock[2];
424 struct i2c_client *i2c_clients[I2C_CLIENTS_MAX]; 425 struct i2c_client *i2c_clients[I2C_CLIENTS_MAX];
425 426
427 /* gpio */
428 u32 gpio_dir;
429 u32 gpio_val;
430
426 /* v4l2 and User settings */ 431 /* v4l2 and User settings */
427 432
428 /* codec settings */ 433 /* codec settings */
@@ -444,9 +449,6 @@ extern spinlock_t cx18_cards_lock;
444/* Return non-zero if a signal is pending */ 449/* Return non-zero if a signal is pending */
445int cx18_msleep_timeout(unsigned int msecs, int intr); 450int cx18_msleep_timeout(unsigned int msecs, int intr);
446 451
447/* Wait on queue, returns -EINTR if interrupted */
448int cx18_waitq(wait_queue_head_t *waitq);
449
450/* Read Hauppauge eeprom */ 452/* Read Hauppauge eeprom */
451struct tveeprom; /* forward reference */ 453struct tveeprom; /* forward reference */
452void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv); 454void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv);
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 65efe69d939a..c9744173f969 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -24,25 +24,27 @@
24#include "cx18-streams.h" 24#include "cx18-streams.h"
25#include "cx18-cards.h" 25#include "cx18-cards.h"
26#include "s5h1409.h" 26#include "s5h1409.h"
27 27#include "mxl5005s.h"
28/* Wait until the MXL500X driver is merged */
29#ifdef HAVE_MXL500X
30#include "mxl500x.h"
31#endif
32 28
33DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 29DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
34 30
35#define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000 31#define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000
36 32
37#ifdef HAVE_MXL500X 33static struct mxl5005s_config hauppauge_hvr1600_tuner = {
38static struct mxl500x_config hauppauge_hvr1600_tuner = { 34 .i2c_address = 0xC6 >> 1,
39 .delsys = MXL500x_MODE_ATSC, 35 .if_freq = IF_FREQ_5380000HZ,
40 .octf = MXL500x_OCTF_CH, 36 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
41 .xtal_freq = 16000000, 37 .agc_mode = MXL_SINGLE_AGC,
42 .iflo_freq = 5380000, 38 .tracking_filter = MXL_TF_C_H,
43 .ref_freq = 322800000, 39 .rssi_enable = MXL_RSSI_ENABLE,
44 .rssi_ena = MXL_RSSI_ENABLE, 40 .cap_select = MXL_CAP_SEL_ENABLE,
45 .addr = 0xC6 >> 1, 41 .div_out = MXL_DIV_OUT_4,
42 .clock_out = MXL_CLOCK_OUT_DISABLE,
43 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
44 .top = MXL5005S_TOP_25P2,
45 .mod_mode = MXL_DIGITAL_MODE,
46 .if_mode = MXL_ZERO_IF,
47 .AgcMasterByte = 0x00,
46}; 48};
47 49
48static struct s5h1409_config hauppauge_hvr1600_config = { 50static struct s5h1409_config hauppauge_hvr1600_config = {
@@ -55,7 +57,6 @@ static struct s5h1409_config hauppauge_hvr1600_config = {
55 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 57 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
56 58
57}; 59};
58#endif
59 60
60static int dvb_register(struct cx18_stream *stream); 61static int dvb_register(struct cx18_stream *stream);
61 62
@@ -252,21 +253,18 @@ static int dvb_register(struct cx18_stream *stream)
252 int ret = 0; 253 int ret = 0;
253 254
254 switch (cx->card->type) { 255 switch (cx->card->type) {
255/* Wait until the MXL500X driver is merged */
256#ifdef HAVE_MXL500X
257 case CX18_CARD_HVR_1600_ESMT: 256 case CX18_CARD_HVR_1600_ESMT:
258 case CX18_CARD_HVR_1600_SAMSUNG: 257 case CX18_CARD_HVR_1600_SAMSUNG:
259 dvb->fe = dvb_attach(s5h1409_attach, 258 dvb->fe = dvb_attach(s5h1409_attach,
260 &hauppauge_hvr1600_config, 259 &hauppauge_hvr1600_config,
261 &cx->i2c_adap[0]); 260 &cx->i2c_adap[0]);
262 if (dvb->fe != NULL) { 261 if (dvb->fe != NULL) {
263 dvb_attach(mxl500x_attach, dvb->fe, 262 dvb_attach(mxl5005s_attach, dvb->fe,
264 &hauppauge_hvr1600_tuner, 263 &cx->i2c_adap[0],
265 &cx->i2c_adap[0]); 264 &hauppauge_hvr1600_tuner);
266 ret = 0; 265 ret = 0;
267 } 266 }
268 break; 267 break;
269#endif
270 default: 268 default:
271 /* No Digital Tv Support */ 269 /* No Digital Tv Support */
272 break; 270 break;
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index 69303065a294..1e537fe04a23 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -39,7 +39,7 @@
39 associated VBI streams are also automatically claimed. 39 associated VBI streams are also automatically claimed.
40 Possible error returns: -EBUSY if someone else has claimed 40 Possible error returns: -EBUSY if someone else has claimed
41 the stream or 0 on success. */ 41 the stream or 0 on success. */
42int cx18_claim_stream(struct cx18_open_id *id, int type) 42static int cx18_claim_stream(struct cx18_open_id *id, int type)
43{ 43{
44 struct cx18 *cx = id->cx; 44 struct cx18 *cx = id->cx;
45 struct cx18_stream *s = &cx->streams[type]; 45 struct cx18_stream *s = &cx->streams[type];
@@ -87,7 +87,7 @@ int cx18_claim_stream(struct cx18_open_id *id, int type)
87 87
88/* This function releases a previously claimed stream. It will take into 88/* This function releases a previously claimed stream. It will take into
89 account associated VBI streams. */ 89 account associated VBI streams. */
90void cx18_release_stream(struct cx18_stream *s) 90static void cx18_release_stream(struct cx18_stream *s)
91{ 91{
92 struct cx18 *cx = s->cx; 92 struct cx18 *cx = s->cx;
93 struct cx18_stream *s_vbi; 93 struct cx18_stream *s_vbi;
@@ -318,7 +318,7 @@ static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
318 size_t tot_written = 0; 318 size_t tot_written = 0;
319 int single_frame = 0; 319 int single_frame = 0;
320 320
321 if (atomic_read(&cx->capturing) == 0 && s->id == -1) { 321 if (atomic_read(&cx->ana_capturing) == 0 && s->id == -1) {
322 /* shouldn't happen */ 322 /* shouldn't happen */
323 CX18_DEBUG_WARN("Stream %s not initialized before read\n", 323 CX18_DEBUG_WARN("Stream %s not initialized before read\n",
324 s->name); 324 s->name);
@@ -361,7 +361,8 @@ static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
361 cx18_enqueue(s, buf, &s->q_free); 361 cx18_enqueue(s, buf, &s->q_free);
362 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, 362 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5,
363 s->handle, 363 s->handle,
364 (void *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, 364 (void __iomem *)&cx->scb->cpu_mdl[buf->id] -
365 cx->enc_mem,
365 1, buf->id, s->buf_size); 366 1, buf->id, s->buf_size);
366 } else 367 } else
367 cx18_enqueue(s, buf, &s->q_io); 368 cx18_enqueue(s, buf, &s->q_io);
@@ -581,7 +582,7 @@ int cx18_v4l2_close(struct inode *inode, struct file *filp)
581 cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std); 582 cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std);
582 /* Select correct audio input (i.e. TV tuner or Line in) */ 583 /* Select correct audio input (i.e. TV tuner or Line in) */
583 cx18_audio_set_io(cx); 584 cx18_audio_set_io(cx);
584 if (atomic_read(&cx->capturing) > 0) { 585 if (atomic_read(&cx->ana_capturing) > 0) {
585 /* Undo video mute */ 586 /* Undo video mute */
586 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle, 587 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
587 cx->params.video_mute | 588 cx->params.video_mute |
@@ -627,7 +628,7 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
627 } 628 }
628 629
629 if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { 630 if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
630 if (atomic_read(&cx->capturing) > 0) { 631 if (atomic_read(&cx->ana_capturing) > 0) {
631 /* switching to radio while capture is 632 /* switching to radio while capture is
632 in progress is not polite */ 633 in progress is not polite */
633 cx18_release_stream(s); 634 cx18_release_stream(s);
@@ -662,6 +663,8 @@ int cx18_v4l2_open(struct inode *inode, struct file *filp)
662 for (x = 0; cx == NULL && x < cx18_cards_active; x++) { 663 for (x = 0; cx == NULL && x < cx18_cards_active; x++) {
663 /* find out which stream this open was on */ 664 /* find out which stream this open was on */
664 for (y = 0; y < CX18_MAX_STREAMS; y++) { 665 for (y = 0; y < CX18_MAX_STREAMS; y++) {
666 if (cx18_cards[x] == NULL)
667 continue;
665 s = &cx18_cards[x]->streams[y]; 668 s = &cx18_cards[x]->streams[y];
666 if (s->v4l2dev && s->v4l2dev->minor == minor) { 669 if (s->v4l2dev && s->v4l2dev->minor == minor) {
667 cx = cx18_cards[x]; 670 cx = cx18_cards[x];
@@ -692,7 +695,7 @@ int cx18_v4l2_open(struct inode *inode, struct file *filp)
692 695
693void cx18_mute(struct cx18 *cx) 696void cx18_mute(struct cx18 *cx)
694{ 697{
695 if (atomic_read(&cx->capturing)) 698 if (atomic_read(&cx->ana_capturing))
696 cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, 699 cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2,
697 cx18_find_handle(cx), 1); 700 cx18_find_handle(cx), 1);
698 CX18_DEBUG_INFO("Mute\n"); 701 CX18_DEBUG_INFO("Mute\n");
@@ -700,7 +703,7 @@ void cx18_mute(struct cx18 *cx)
700 703
701void cx18_unmute(struct cx18 *cx) 704void cx18_unmute(struct cx18 *cx)
702{ 705{
703 if (atomic_read(&cx->capturing)) { 706 if (atomic_read(&cx->ana_capturing)) {
704 cx18_msleep_timeout(100, 0); 707 cx18_msleep_timeout(100, 0);
705 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, 708 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2,
706 cx18_find_handle(cx), 12); 709 cx18_find_handle(cx), 12);
diff --git a/drivers/media/video/cx18/cx18-fileops.h b/drivers/media/video/cx18/cx18-fileops.h
index 16cdafbd24c5..46da0282fc7d 100644
--- a/drivers/media/video/cx18/cx18-fileops.h
+++ b/drivers/media/video/cx18/cx18-fileops.h
@@ -34,12 +34,3 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end);
34void cx18_mute(struct cx18 *cx); 34void cx18_mute(struct cx18 *cx);
35void cx18_unmute(struct cx18 *cx); 35void cx18_unmute(struct cx18 *cx);
36 36
37/* Utilities */
38
39/* Try to claim a stream for the filehandle. Return 0 on success,
40 -EBUSY if stream already claimed. Once a stream is claimed, it
41 remains claimed until the associated filehandle is closed. */
42int cx18_claim_stream(struct cx18_open_id *id, int type);
43
44/* Release a previously claimed stream. */
45void cx18_release_stream(struct cx18_stream *s);
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c
index 19253e6b8673..ceb63653c926 100644
--- a/drivers/media/video/cx18/cx18-gpio.c
+++ b/drivers/media/video/cx18/cx18-gpio.c
@@ -44,31 +44,57 @@
44 * gpio13: cs5345 reset pin 44 * gpio13: cs5345 reset pin
45*/ 45*/
46 46
47static void gpio_write(struct cx18 *cx)
48{
49 u32 dir = cx->gpio_dir;
50 u32 val = cx->gpio_val;
51
52 write_reg((dir & 0xffff) << 16, CX18_REG_GPIO_DIR1);
53 write_reg(((dir & 0xffff) << 16) | (val & 0xffff),
54 CX18_REG_GPIO_OUT1);
55 write_reg(dir & 0xffff0000, CX18_REG_GPIO_DIR2);
56 write_reg((dir & 0xffff0000) | ((val & 0xffff0000) >> 16),
57 CX18_REG_GPIO_OUT2);
58}
59
47void cx18_gpio_init(struct cx18 *cx) 60void cx18_gpio_init(struct cx18 *cx)
48{ 61{
49 if (cx->card->gpio_init.direction == 0) 62 cx->gpio_dir = cx->card->gpio_init.direction;
63 cx->gpio_val = cx->card->gpio_init.initial_value;
64
65 if (cx->card->tuners[0].tuner == TUNER_XC2028) {
66 cx->gpio_dir |= 1 << cx->card->xceive_pin;
67 cx->gpio_val |= 1 << cx->card->xceive_pin;
68 }
69
70 if (cx->gpio_dir == 0)
50 return; 71 return;
51 72
52 CX18_DEBUG_INFO("GPIO initial dir: %08x out: %08x\n", 73 CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n",
53 read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_OUT1)); 74 read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2),
75 read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2));
54 76
55 /* init output data then direction */ 77 gpio_write(cx);
56 write_reg(cx->card->gpio_init.direction << 16, CX18_REG_GPIO_DIR1);
57 write_reg(0, CX18_REG_GPIO_DIR2);
58 write_reg((cx->card->gpio_init.direction << 16) |
59 cx->card->gpio_init.initial_value, CX18_REG_GPIO_OUT1);
60 write_reg(0, CX18_REG_GPIO_OUT2);
61} 78}
62 79
63/* Xceive tuner reset function */ 80/* Xceive tuner reset function */
64int cx18_reset_tuner_gpio(void *dev, int cmd, int value) 81int cx18_reset_tuner_gpio(void *dev, int cmd, int value)
65{ 82{
66 struct i2c_algo_bit_data *algo = dev; 83 struct i2c_algo_bit_data *algo = dev;
67 struct cx18 *cx = algo->data; 84 struct cx18_i2c_algo_callback_data *cb_data = algo->data;
68/* int curdir, curout;*/ 85 struct cx18 *cx = cb_data->cx;
69 86
70 if (cmd != XC2028_TUNER_RESET) 87 if (cmd != XC2028_TUNER_RESET)
71 return 0; 88 return 0;
72 CX18_DEBUG_INFO("Resetting tuner\n"); 89 CX18_DEBUG_INFO("Resetting tuner\n");
90
91 cx->gpio_val &= ~(1 << cx->card->xceive_pin);
92
93 gpio_write(cx);
94 schedule_timeout_interruptible(msecs_to_jiffies(1));
95
96 cx->gpio_val |= 1 << cx->card->xceive_pin;
97 gpio_write(cx);
98 schedule_timeout_interruptible(msecs_to_jiffies(1));
73 return 0; 99 return 0;
74} 100}
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index 18c88d1e4833..1d6c51a75313 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -25,6 +25,7 @@
25#include "cx18-cards.h" 25#include "cx18-cards.h"
26#include "cx18-gpio.h" 26#include "cx18-gpio.h"
27#include "cx18-av-core.h" 27#include "cx18-av-core.h"
28#include "cx18-i2c.h"
28 29
29#include <media/ir-kbd-i2c.h> 30#include <media/ir-kbd-i2c.h>
30 31
@@ -73,7 +74,7 @@ static const u8 hw_bus[] = {
73}; 74};
74 75
75/* This array should match the CX18_HW_ defines */ 76/* This array should match the CX18_HW_ defines */
76static const char * const hw_drivernames[] = { 77static const char * const hw_devicenames[] = {
77 "tuner", 78 "tuner",
78 "tveeprom", 79 "tveeprom",
79 "cs5345", 80 "cs5345",
@@ -94,8 +95,7 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
94 id = hw_driverids[idx]; 95 id = hw_driverids[idx];
95 bus = hw_bus[idx]; 96 bus = hw_bus[idx];
96 memset(&info, 0, sizeof(info)); 97 memset(&info, 0, sizeof(info));
97 strlcpy(info.driver_name, hw_drivernames[idx], 98 strlcpy(info.type, hw_devicenames[idx], sizeof(info.type));
98 sizeof(info.driver_name));
99 info.addr = hw_addrs[idx]; 99 info.addr = hw_addrs[idx];
100 for (i = 0; i < I2C_CLIENTS_MAX; i++) 100 for (i = 0; i < I2C_CLIENTS_MAX; i++)
101 if (cx->i2c_clients[i] == NULL) 101 if (cx->i2c_clients[i] == NULL)
@@ -278,7 +278,7 @@ static const char *cx18_i2c_id_name(u32 id)
278 278
279 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++) 279 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
280 if (hw_driverids[i] == id) 280 if (hw_driverids[i] == id)
281 return hw_drivernames[i]; 281 return hw_devicenames[i];
282 return "unknown device"; 282 return "unknown device";
283} 283}
284 284
@@ -289,7 +289,7 @@ static const char *cx18_i2c_hw_name(u32 hw)
289 289
290 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++) 290 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
291 if (1 << i == hw) 291 if (1 << i == hw)
292 return hw_drivernames[i]; 292 return hw_devicenames[i];
293 return "unknown device"; 293 return "unknown device";
294} 294}
295 295
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index dbdcb86ec5aa..4151f1e5493f 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -247,7 +247,7 @@ static int cx18_try_or_set_fmt(struct cx18 *cx, int streamtype,
247 247
248 if (!set_fmt || (cx->params.width == w && cx->params.height == h)) 248 if (!set_fmt || (cx->params.width == w && cx->params.height == h))
249 return 0; 249 return 0;
250 if (atomic_read(&cx->capturing) > 0) 250 if (atomic_read(&cx->ana_capturing) > 0)
251 return -EBUSY; 251 return -EBUSY;
252 252
253 cx->params.width = w; 253 cx->params.width = w;
@@ -264,7 +264,7 @@ static int cx18_try_or_set_fmt(struct cx18 *cx, int streamtype,
264 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { 264 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
265 if (set_fmt && streamtype == CX18_ENC_STREAM_TYPE_VBI && 265 if (set_fmt && streamtype == CX18_ENC_STREAM_TYPE_VBI &&
266 cx->vbi.sliced_in->service_set && 266 cx->vbi.sliced_in->service_set &&
267 atomic_read(&cx->capturing) > 0) 267 atomic_read(&cx->ana_capturing) > 0)
268 return -EBUSY; 268 return -EBUSY;
269 if (set_fmt) { 269 if (set_fmt) {
270 cx->vbi.sliced_in->service_set = 0; 270 cx->vbi.sliced_in->service_set = 0;
@@ -293,7 +293,7 @@ static int cx18_try_or_set_fmt(struct cx18 *cx, int streamtype,
293 return 0; 293 return 0;
294 if (set == 0) 294 if (set == 0)
295 return -EINVAL; 295 return -EINVAL;
296 if (atomic_read(&cx->capturing) > 0 && cx->vbi.sliced_in->service_set == 0) 296 if (atomic_read(&cx->ana_capturing) > 0 && cx->vbi.sliced_in->service_set == 0)
297 return -EBUSY; 297 return -EBUSY;
298 cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); 298 cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
299 memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in)); 299 memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in));
@@ -581,7 +581,7 @@ int cx18_v4l2_ioctls(struct cx18 *cx, struct file *filp, unsigned cmd, void *arg
581 break; 581 break;
582 582
583 if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) || 583 if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ||
584 atomic_read(&cx->capturing) > 0) { 584 atomic_read(&cx->ana_capturing) > 0) {
585 /* Switching standard would turn off the radio or mess 585 /* Switching standard would turn off the radio or mess
586 with already running streams, prevent that by 586 with already running streams, prevent that by
587 returning EBUSY. */ 587 returning EBUSY. */
@@ -677,7 +677,7 @@ int cx18_v4l2_ioctls(struct cx18 *cx, struct file *filp, unsigned cmd, void *arg
677 enc->flags = 0; 677 enc->flags = 0;
678 if (try) 678 if (try)
679 return 0; 679 return 0;
680 if (!atomic_read(&cx->capturing)) 680 if (!atomic_read(&cx->ana_capturing))
681 return -EPERM; 681 return -EPERM;
682 if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) 682 if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
683 return 0; 683 return 0;
@@ -689,7 +689,7 @@ int cx18_v4l2_ioctls(struct cx18 *cx, struct file *filp, unsigned cmd, void *arg
689 enc->flags = 0; 689 enc->flags = 0;
690 if (try) 690 if (try)
691 return 0; 691 return 0;
692 if (!atomic_read(&cx->capturing)) 692 if (!atomic_read(&cx->ana_capturing))
693 return -EPERM; 693 return -EPERM;
694 if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) 694 if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
695 return 0; 695 return 0;
diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c
index 6e14f8bda559..25114a5cbd57 100644
--- a/drivers/media/video/cx18/cx18-irq.c
+++ b/drivers/media/video/cx18/cx18-irq.c
@@ -75,7 +75,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb)
75 75
76 cx18_buf_sync_for_device(s, buf); 76 cx18_buf_sync_for_device(s, buf);
77 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, 77 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
78 (void *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, 78 (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem,
79 1, buf->id, s->buf_size); 79 1, buf->id, s->buf_size);
80 } else 80 } else
81 set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags); 81 set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags);
@@ -161,13 +161,15 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id)
161 */ 161 */
162 162
163 if (sw2) { 163 if (sw2) {
164 if (sw2 & (cx->scb->cpu2hpu_irq_ack | cx->scb->cpu2epu_irq_ack)) 164 if (sw2 & (readl(&cx->scb->cpu2hpu_irq_ack) |
165 readl(&cx->scb->cpu2epu_irq_ack)))
165 wake_up(&cx->mb_cpu_waitq); 166 wake_up(&cx->mb_cpu_waitq);
166 if (sw2 & (cx->scb->apu2hpu_irq_ack | cx->scb->apu2epu_irq_ack)) 167 if (sw2 & (readl(&cx->scb->apu2hpu_irq_ack) |
168 readl(&cx->scb->apu2epu_irq_ack)))
167 wake_up(&cx->mb_apu_waitq); 169 wake_up(&cx->mb_apu_waitq);
168 if (sw2 & cx->scb->epu2hpu_irq_ack) 170 if (sw2 & readl(&cx->scb->epu2hpu_irq_ack))
169 wake_up(&cx->mb_epu_waitq); 171 wake_up(&cx->mb_epu_waitq);
170 if (sw2 & cx->scb->hpu2epu_irq_ack) 172 if (sw2 & readl(&cx->scb->hpu2epu_irq_ack))
171 wake_up(&cx->mb_hpu_waitq); 173 wake_up(&cx->mb_hpu_waitq);
172 } 174 }
173 175
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index 0c5f328bca54..2a5ccef9185b 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -94,10 +94,10 @@ static const struct cx18_api_info *find_api_info(u32 cmd)
94 return NULL; 94 return NULL;
95} 95}
96 96
97static struct cx18_mailbox *cx18_mb_is_complete(struct cx18 *cx, int rpu, 97static struct cx18_mailbox __iomem *cx18_mb_is_complete(struct cx18 *cx, int rpu,
98 u32 *state, u32 *irq, u32 *req) 98 u32 *state, u32 *irq, u32 *req)
99{ 99{
100 struct cx18_mailbox *mb = NULL; 100 struct cx18_mailbox __iomem *mb = NULL;
101 int wait_count = 0; 101 int wait_count = 0;
102 u32 ack; 102 u32 ack;
103 103
@@ -142,7 +142,7 @@ static struct cx18_mailbox *cx18_mb_is_complete(struct cx18 *cx, int rpu,
142long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb) 142long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb)
143{ 143{
144 const struct cx18_api_info *info = find_api_info(mb->cmd); 144 const struct cx18_api_info *info = find_api_info(mb->cmd);
145 struct cx18_mailbox *ack_mb; 145 struct cx18_mailbox __iomem *ack_mb;
146 u32 ack_irq; 146 u32 ack_irq;
147 u8 rpu = CPU; 147 u8 rpu = CPU;
148 148
@@ -182,7 +182,7 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
182{ 182{
183 const struct cx18_api_info *info = find_api_info(cmd); 183 const struct cx18_api_info *info = find_api_info(cmd);
184 u32 state = 0, irq = 0, req, oldreq, err; 184 u32 state = 0, irq = 0, req, oldreq, err;
185 struct cx18_mailbox *mb; 185 struct cx18_mailbox __iomem *mb;
186 wait_queue_head_t *waitq; 186 wait_queue_head_t *waitq;
187 int timeout = 100; 187 int timeout = 100;
188 int cnt = 0; 188 int cnt = 0;
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index 65af1bb507ca..6990b77c6200 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -26,17 +26,6 @@
26#include "cx18-queue.h" 26#include "cx18-queue.h"
27#include "cx18-scb.h" 27#include "cx18-scb.h"
28 28
29int cx18_buf_copy_from_user(struct cx18_stream *s, struct cx18_buffer *buf,
30 const char __user *src, int copybytes)
31{
32 if (s->buf_size - buf->bytesused < copybytes)
33 copybytes = s->buf_size - buf->bytesused;
34 if (copy_from_user(buf->buf + buf->bytesused, src, copybytes))
35 return -EFAULT;
36 buf->bytesused += copybytes;
37 return copybytes;
38}
39
40void cx18_buf_swap(struct cx18_buffer *buf) 29void cx18_buf_swap(struct cx18_buffer *buf)
41{ 30{
42 int i; 31 int i;
@@ -159,8 +148,9 @@ static void cx18_queue_move_buf(struct cx18_stream *s, struct cx18_queue *from,
159 -ENOMEM is returned if the buffers could not be obtained, 0 if all 148 -ENOMEM is returned if the buffers could not be obtained, 0 if all
160 buffers where obtained from the 'from' list and if non-zero then 149 buffers where obtained from the 'from' list and if non-zero then
161 the number of stolen buffers is returned. */ 150 the number of stolen buffers is returned. */
162int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from, 151static int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
163 struct cx18_queue *steal, struct cx18_queue *to, int needed_bytes) 152 struct cx18_queue *steal, struct cx18_queue *to,
153 int needed_bytes)
164{ 154{
165 unsigned long flags; 155 unsigned long flags;
166 int rc = 0; 156 int rc = 0;
@@ -239,12 +229,12 @@ int cx18_stream_alloc(struct cx18_stream *s)
239 229
240 /* allocate stream buffers. Initially all buffers are in q_free. */ 230 /* allocate stream buffers. Initially all buffers are in q_free. */
241 for (i = 0; i < s->buffers; i++) { 231 for (i = 0; i < s->buffers; i++) {
242 struct cx18_buffer *buf = 232 struct cx18_buffer *buf = kzalloc(sizeof(struct cx18_buffer),
243 kzalloc(sizeof(struct cx18_buffer), GFP_KERNEL); 233 GFP_KERNEL|__GFP_NOWARN);
244 234
245 if (buf == NULL) 235 if (buf == NULL)
246 break; 236 break;
247 buf->buf = kmalloc(s->buf_size, GFP_KERNEL); 237 buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN);
248 if (buf->buf == NULL) { 238 if (buf->buf == NULL) {
249 kfree(buf); 239 kfree(buf);
250 break; 240 break;
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h
index f86c8a6fa6e7..91423b9863a4 100644
--- a/drivers/media/video/cx18/cx18-queue.h
+++ b/drivers/media/video/cx18/cx18-queue.h
@@ -39,8 +39,6 @@ static inline void cx18_buf_sync_for_device(struct cx18_stream *s,
39 s->buf_size, s->dma); 39 s->buf_size, s->dma);
40} 40}
41 41
42int cx18_buf_copy_from_user(struct cx18_stream *s, struct cx18_buffer *buf,
43 const char __user *src, int copybytes);
44void cx18_buf_swap(struct cx18_buffer *buf); 42void cx18_buf_swap(struct cx18_buffer *buf);
45 43
46/* cx18_queue utility functions */ 44/* cx18_queue utility functions */
@@ -48,8 +46,6 @@ void cx18_queue_init(struct cx18_queue *q);
48void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, 46void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
49 struct cx18_queue *q); 47 struct cx18_queue *q);
50struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q); 48struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
51int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
52 struct cx18_queue *steal, struct cx18_queue *to, int needed_bytes);
53struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, 49struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id,
54 u32 bytesused); 50 u32 bytesused);
55void cx18_flush_queues(struct cx18_stream *s); 51void cx18_flush_queues(struct cx18_stream *s);
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index afb141b2027a..1b921a336092 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -36,12 +36,13 @@
36#define CX18_DSP0_INTERRUPT_MASK 0xd0004C 36#define CX18_DSP0_INTERRUPT_MASK 0xd0004C
37 37
38static struct file_operations cx18_v4l2_enc_fops = { 38static struct file_operations cx18_v4l2_enc_fops = {
39 .owner = THIS_MODULE, 39 .owner = THIS_MODULE,
40 .read = cx18_v4l2_read, 40 .read = cx18_v4l2_read,
41 .open = cx18_v4l2_open, 41 .open = cx18_v4l2_open,
42 .ioctl = cx18_v4l2_ioctl, 42 .ioctl = cx18_v4l2_ioctl,
43 .release = cx18_v4l2_close, 43 .compat_ioctl = v4l_compat_ioctl32,
44 .poll = cx18_v4l2_enc_poll, 44 .release = cx18_v4l2_close,
45 .poll = cx18_v4l2_enc_poll,
45}; 46};
46 47
47/* offset from 0 to register ts v4l2 minors on */ 48/* offset from 0 to register ts v4l2 minors on */
@@ -218,7 +219,7 @@ int cx18_streams_setup(struct cx18 *cx)
218 return 0; 219 return 0;
219 220
220 /* One or more streams could not be initialized. Clean 'em all up. */ 221 /* One or more streams could not be initialized. Clean 'em all up. */
221 cx18_streams_cleanup(cx); 222 cx18_streams_cleanup(cx, 0);
222 return -ENOMEM; 223 return -ENOMEM;
223} 224}
224 225
@@ -296,12 +297,12 @@ int cx18_streams_register(struct cx18 *cx)
296 return 0; 297 return 0;
297 298
298 /* One or more streams could not be initialized. Clean 'em all up. */ 299 /* One or more streams could not be initialized. Clean 'em all up. */
299 cx18_streams_cleanup(cx); 300 cx18_streams_cleanup(cx, 1);
300 return -ENOMEM; 301 return -ENOMEM;
301} 302}
302 303
303/* Unregister v4l2 devices */ 304/* Unregister v4l2 devices */
304void cx18_streams_cleanup(struct cx18 *cx) 305void cx18_streams_cleanup(struct cx18 *cx, int unregister)
305{ 306{
306 struct video_device *vdev; 307 struct video_device *vdev;
307 int type; 308 int type;
@@ -319,8 +320,11 @@ void cx18_streams_cleanup(struct cx18 *cx)
319 320
320 cx18_stream_free(&cx->streams[type]); 321 cx18_stream_free(&cx->streams[type]);
321 322
322 /* Unregister device */ 323 /* Unregister or release device */
323 video_unregister_device(vdev); 324 if (unregister)
325 video_unregister_device(vdev);
326 else
327 video_device_release(vdev);
324 } 328 }
325} 329}
326 330
@@ -440,7 +444,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
440 s->handle = data[0]; 444 s->handle = data[0];
441 cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype); 445 cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype);
442 446
443 if (atomic_read(&cx->capturing) == 0 && !ts) { 447 if (atomic_read(&cx->ana_capturing) == 0 && !ts) {
444 /* Stuff from Windows, we don't know what it is */ 448 /* Stuff from Windows, we don't know what it is */
445 cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0); 449 cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0);
446 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1); 450 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1);
@@ -463,14 +467,14 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
463 cx2341x_update(cx, cx18_api_func, NULL, &cx->params); 467 cx2341x_update(cx, cx18_api_func, NULL, &cx->params);
464 } 468 }
465 469
466 if (atomic_read(&cx->capturing) == 0) { 470 if (atomic_read(&cx->tot_capturing) == 0) {
467 clear_bit(CX18_F_I_EOS, &cx->i_flags); 471 clear_bit(CX18_F_I_EOS, &cx->i_flags);
468 write_reg(7, CX18_DSP0_INTERRUPT_MASK); 472 write_reg(7, CX18_DSP0_INTERRUPT_MASK);
469 } 473 }
470 474
471 cx18_vapi(cx, CX18_CPU_DE_SET_MDL_ACK, 3, s->handle, 475 cx18_vapi(cx, CX18_CPU_DE_SET_MDL_ACK, 3, s->handle,
472 (void *)&cx->scb->cpu_mdl_ack[s->type][0] - cx->enc_mem, 476 (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][0] - cx->enc_mem,
473 (void *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem); 477 (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem);
474 478
475 list_for_each(p, &s->q_free.list) { 479 list_for_each(p, &s->q_free.list) {
476 struct cx18_buffer *buf = list_entry(p, struct cx18_buffer, list); 480 struct cx18_buffer *buf = list_entry(p, struct cx18_buffer, list);
@@ -478,8 +482,8 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
478 writel(buf->dma_handle, &cx->scb->cpu_mdl[buf->id].paddr); 482 writel(buf->dma_handle, &cx->scb->cpu_mdl[buf->id].paddr);
479 writel(s->buf_size, &cx->scb->cpu_mdl[buf->id].length); 483 writel(s->buf_size, &cx->scb->cpu_mdl[buf->id].length);
480 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, 484 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
481 (void *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, 1, 485 (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem,
482 buf->id, s->buf_size); 486 1, buf->id, s->buf_size);
483 } 487 }
484 /* begin_capture */ 488 /* begin_capture */
485 if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) { 489 if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) {
@@ -489,7 +493,9 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
489 } 493 }
490 494
491 /* you're live! sit back and await interrupts :) */ 495 /* you're live! sit back and await interrupts :) */
492 atomic_inc(&cx->capturing); 496 if (!ts)
497 atomic_inc(&cx->ana_capturing);
498 atomic_inc(&cx->tot_capturing);
493 return 0; 499 return 0;
494} 500}
495 501
@@ -520,7 +526,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
520 526
521 CX18_DEBUG_INFO("Stop Capture\n"); 527 CX18_DEBUG_INFO("Stop Capture\n");
522 528
523 if (atomic_read(&cx->capturing) == 0) 529 if (atomic_read(&cx->tot_capturing) == 0)
524 return 0; 530 return 0;
525 531
526 if (s->type == CX18_ENC_STREAM_TYPE_MPG) 532 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
@@ -534,7 +540,9 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
534 CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n"); 540 CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n");
535 } 541 }
536 542
537 atomic_dec(&cx->capturing); 543 if (s->type != CX18_ENC_STREAM_TYPE_TS)
544 atomic_dec(&cx->ana_capturing);
545 atomic_dec(&cx->tot_capturing);
538 546
539 /* Clear capture and no-read bits */ 547 /* Clear capture and no-read bits */
540 clear_bit(CX18_F_S_STREAMING, &s->s_flags); 548 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
@@ -542,7 +550,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
542 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); 550 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
543 s->handle = 0xffffffff; 551 s->handle = 0xffffffff;
544 552
545 if (atomic_read(&cx->capturing) > 0) 553 if (atomic_read(&cx->tot_capturing) > 0)
546 return 0; 554 return 0;
547 555
548 write_reg(5, CX18_DSP0_INTERRUPT_MASK); 556 write_reg(5, CX18_DSP0_INTERRUPT_MASK);
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
index 8c7ba7d2fa79..f327e947b24f 100644
--- a/drivers/media/video/cx18/cx18-streams.h
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -24,7 +24,7 @@
24u32 cx18_find_handle(struct cx18 *cx); 24u32 cx18_find_handle(struct cx18 *cx);
25int cx18_streams_setup(struct cx18 *cx); 25int cx18_streams_setup(struct cx18 *cx);
26int cx18_streams_register(struct cx18 *cx); 26int cx18_streams_register(struct cx18 *cx);
27void cx18_streams_cleanup(struct cx18 *cx); 27void cx18_streams_cleanup(struct cx18 *cx, int unregister);
28 28
29/* Capture related */ 29/* Capture related */
30int cx18_start_v4l2_encode_stream(struct cx18_stream *s); 30int cx18_start_v4l2_encode_stream(struct cx18_stream *s);