diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
commit | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch) | |
tree | a57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/media/video/ivtv | |
parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) |
Diffstat (limited to 'drivers/media/video/ivtv')
36 files changed, 15491 insertions, 0 deletions
diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig new file mode 100644 index 00000000000..89f65914cc8 --- /dev/null +++ b/drivers/media/video/ivtv/Kconfig | |||
@@ -0,0 +1,45 @@ | |||
1 | config VIDEO_IVTV | ||
2 | tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support" | ||
3 | depends on VIDEO_V4L2 && PCI && I2C | ||
4 | select I2C_ALGOBIT | ||
5 | depends on RC_CORE | ||
6 | select VIDEO_TUNER | ||
7 | select VIDEO_TVEEPROM | ||
8 | select VIDEO_CX2341X | ||
9 | select VIDEO_CX25840 | ||
10 | select VIDEO_MSP3400 | ||
11 | select VIDEO_SAA711X | ||
12 | select VIDEO_SAA717X | ||
13 | select VIDEO_SAA7127 | ||
14 | select VIDEO_CS53L32A | ||
15 | select VIDEO_M52790 | ||
16 | select VIDEO_WM8775 | ||
17 | select VIDEO_WM8739 | ||
18 | select VIDEO_VP27SMPX | ||
19 | select VIDEO_UPD64031A | ||
20 | select VIDEO_UPD64083 | ||
21 | ---help--- | ||
22 | This is a video4linux driver for Conexant cx23416 or cx23415 based | ||
23 | PCI personal video recorder devices. | ||
24 | |||
25 | This is used in devices such as the Hauppauge PVR-150/250/350/500 | ||
26 | cards. There is a driver homepage at <http://www.ivtvdriver.org>. | ||
27 | |||
28 | To compile this driver as a module, choose M here: the | ||
29 | module will be called ivtv. | ||
30 | |||
31 | config VIDEO_FB_IVTV | ||
32 | tristate "Conexant cx23415 framebuffer support" | ||
33 | depends on VIDEO_IVTV && FB | ||
34 | select FB_CFB_FILLRECT | ||
35 | select FB_CFB_COPYAREA | ||
36 | select FB_CFB_IMAGEBLIT | ||
37 | ---help--- | ||
38 | This is a framebuffer driver for the Conexant cx23415 MPEG | ||
39 | encoder/decoder. | ||
40 | |||
41 | This is used in the Hauppauge PVR-350 card. There is a driver | ||
42 | homepage at <http://www.ivtvdriver.org>. | ||
43 | |||
44 | To compile this driver as a module, choose M here: the | ||
45 | module will be called ivtvfb. | ||
diff --git a/drivers/media/video/ivtv/Makefile b/drivers/media/video/ivtv/Makefile new file mode 100644 index 00000000000..26ce0d6eaee --- /dev/null +++ b/drivers/media/video/ivtv/Makefile | |||
@@ -0,0 +1,14 @@ | |||
1 | ivtv-objs := ivtv-routing.o ivtv-cards.o ivtv-controls.o \ | ||
2 | ivtv-driver.o ivtv-fileops.o ivtv-firmware.o \ | ||
3 | ivtv-gpio.o ivtv-i2c.o ivtv-ioctl.o ivtv-irq.o \ | ||
4 | ivtv-mailbox.o ivtv-queue.o ivtv-streams.o ivtv-udma.o \ | ||
5 | ivtv-vbi.o ivtv-yuv.o | ||
6 | |||
7 | obj-$(CONFIG_VIDEO_IVTV) += ivtv.o | ||
8 | obj-$(CONFIG_VIDEO_FB_IVTV) += ivtvfb.o | ||
9 | |||
10 | EXTRA_CFLAGS += -Idrivers/media/video | ||
11 | EXTRA_CFLAGS += -Idrivers/media/common/tuners | ||
12 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core | ||
13 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends | ||
14 | |||
diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c new file mode 100644 index 00000000000..145e4749a69 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-cards.c | |||
@@ -0,0 +1,1370 @@ | |||
1 | /* | ||
2 | Functions to query card hardware | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include "ivtv-driver.h" | ||
22 | #include "ivtv-cards.h" | ||
23 | #include "ivtv-i2c.h" | ||
24 | |||
25 | #include <media/msp3400.h> | ||
26 | #include <media/m52790.h> | ||
27 | #include <media/wm8775.h> | ||
28 | #include <media/cs53l32a.h> | ||
29 | #include <media/cx25840.h> | ||
30 | #include <media/upd64031a.h> | ||
31 | |||
32 | #define MSP_TUNER MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, \ | ||
33 | MSP_DSP_IN_TUNER, MSP_DSP_IN_TUNER) | ||
34 | #define MSP_SCART1 MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, \ | ||
35 | MSP_DSP_IN_SCART, MSP_DSP_IN_SCART) | ||
36 | #define MSP_SCART2 MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1, \ | ||
37 | MSP_DSP_IN_SCART, MSP_DSP_IN_SCART) | ||
38 | #define MSP_SCART3 MSP_INPUT(MSP_IN_SCART3, MSP_IN_TUNER1, \ | ||
39 | MSP_DSP_IN_SCART, MSP_DSP_IN_SCART) | ||
40 | #define MSP_MONO MSP_INPUT(MSP_IN_MONO, MSP_IN_TUNER1, \ | ||
41 | MSP_DSP_IN_SCART, MSP_DSP_IN_SCART) | ||
42 | |||
43 | #define V4L2_STD_PAL_SECAM (V4L2_STD_PAL|V4L2_STD_SECAM) | ||
44 | |||
45 | /* usual i2c tuner addresses to probe */ | ||
46 | static struct ivtv_card_tuner_i2c ivtv_i2c_std = { | ||
47 | .radio = { I2C_CLIENT_END }, | ||
48 | .demod = { 0x43, I2C_CLIENT_END }, | ||
49 | .tv = { 0x61, 0x60, I2C_CLIENT_END }, | ||
50 | }; | ||
51 | |||
52 | /* as above, but with possible radio tuner */ | ||
53 | static struct ivtv_card_tuner_i2c ivtv_i2c_radio = { | ||
54 | .radio = { 0x60, I2C_CLIENT_END }, | ||
55 | .demod = { 0x43, I2C_CLIENT_END }, | ||
56 | .tv = { 0x61, I2C_CLIENT_END }, | ||
57 | }; | ||
58 | |||
59 | /* using the tda8290+75a combo */ | ||
60 | static struct ivtv_card_tuner_i2c ivtv_i2c_tda8290 = { | ||
61 | .radio = { I2C_CLIENT_END }, | ||
62 | .demod = { I2C_CLIENT_END }, | ||
63 | .tv = { 0x4b, I2C_CLIENT_END }, | ||
64 | }; | ||
65 | |||
66 | /********************** card configuration *******************************/ | ||
67 | |||
68 | /* Please add new PCI IDs to: http://pci-ids.ucw.cz/ | ||
69 | This keeps the PCI ID database up to date. Note that the entries | ||
70 | must be added under vendor 0x4444 (Conexant) as subsystem IDs. | ||
71 | New vendor IDs should still be added to the vendor ID list. */ | ||
72 | |||
73 | /* Hauppauge PVR-250 cards */ | ||
74 | |||
75 | /* Note: for Hauppauge cards the tveeprom information is used instead of PCI IDs */ | ||
76 | static const struct ivtv_card ivtv_card_pvr250 = { | ||
77 | .type = IVTV_CARD_PVR_250, | ||
78 | .name = "Hauppauge WinTV PVR-250", | ||
79 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
80 | .hw_video = IVTV_HW_SAA7115, | ||
81 | .hw_audio = IVTV_HW_MSP34XX, | ||
82 | .hw_audio_ctrl = IVTV_HW_MSP34XX, | ||
83 | .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7115 | | ||
84 | IVTV_HW_TVEEPROM | IVTV_HW_TUNER, | ||
85 | .video_inputs = { | ||
86 | { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 }, | ||
87 | { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 }, | ||
88 | { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE0 }, | ||
89 | { IVTV_CARD_INPUT_SVIDEO2, 2, IVTV_SAA71XX_SVIDEO1 }, | ||
90 | { IVTV_CARD_INPUT_COMPOSITE2, 2, IVTV_SAA71XX_COMPOSITE1 }, | ||
91 | { IVTV_CARD_INPUT_COMPOSITE3, 1, IVTV_SAA71XX_COMPOSITE5 }, | ||
92 | }, | ||
93 | .audio_inputs = { | ||
94 | { IVTV_CARD_INPUT_AUD_TUNER, MSP_TUNER }, | ||
95 | { IVTV_CARD_INPUT_LINE_IN1, MSP_SCART1 }, | ||
96 | { IVTV_CARD_INPUT_LINE_IN2, MSP_SCART3 }, | ||
97 | }, | ||
98 | .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, MSP_SCART2 }, | ||
99 | .i2c = &ivtv_i2c_std, | ||
100 | }; | ||
101 | |||
102 | /* ------------------------------------------------------------------------- */ | ||
103 | |||
104 | /* Hauppauge PVR-350 cards */ | ||
105 | |||
106 | /* Outputs for Hauppauge PVR350 cards */ | ||
107 | static struct ivtv_card_output ivtv_pvr350_outputs[] = { | ||
108 | { | ||
109 | .name = "S-Video + Composite", | ||
110 | .video_output = 0, | ||
111 | }, { | ||
112 | .name = "Composite", | ||
113 | .video_output = 1, | ||
114 | }, { | ||
115 | .name = "S-Video", | ||
116 | .video_output = 2, | ||
117 | }, { | ||
118 | .name = "RGB", | ||
119 | .video_output = 3, | ||
120 | }, { | ||
121 | .name = "YUV C", | ||
122 | .video_output = 4, | ||
123 | }, { | ||
124 | .name = "YUV V", | ||
125 | .video_output = 5, | ||
126 | } | ||
127 | }; | ||
128 | |||
129 | static const struct ivtv_card ivtv_card_pvr350 = { | ||
130 | .type = IVTV_CARD_PVR_350, | ||
131 | .name = "Hauppauge WinTV PVR-350", | ||
132 | .v4l2_capabilities = IVTV_CAP_ENCODER | IVTV_CAP_DECODER, | ||
133 | .video_outputs = ivtv_pvr350_outputs, | ||
134 | .nof_outputs = ARRAY_SIZE(ivtv_pvr350_outputs), | ||
135 | .hw_video = IVTV_HW_SAA7115, | ||
136 | .hw_audio = IVTV_HW_MSP34XX, | ||
137 | .hw_audio_ctrl = IVTV_HW_MSP34XX, | ||
138 | .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7115 | | ||
139 | IVTV_HW_SAA7127 | IVTV_HW_TVEEPROM | IVTV_HW_TUNER | | ||
140 | IVTV_HW_I2C_IR_RX_HAUP_EXT | IVTV_HW_I2C_IR_RX_HAUP_INT, | ||
141 | .video_inputs = { | ||
142 | { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 }, | ||
143 | { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 }, | ||
144 | { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE0 }, | ||
145 | { IVTV_CARD_INPUT_SVIDEO2, 2, IVTV_SAA71XX_SVIDEO1 }, | ||
146 | { IVTV_CARD_INPUT_COMPOSITE2, 2, IVTV_SAA71XX_COMPOSITE1 }, | ||
147 | { IVTV_CARD_INPUT_COMPOSITE3, 1, IVTV_SAA71XX_COMPOSITE5 }, | ||
148 | }, | ||
149 | .audio_inputs = { | ||
150 | { IVTV_CARD_INPUT_AUD_TUNER, MSP_TUNER }, | ||
151 | { IVTV_CARD_INPUT_LINE_IN1, MSP_SCART1 }, | ||
152 | { IVTV_CARD_INPUT_LINE_IN2, MSP_SCART3 }, | ||
153 | }, | ||
154 | .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, MSP_SCART2 }, | ||
155 | .i2c = &ivtv_i2c_std, | ||
156 | }; | ||
157 | |||
158 | /* PVR-350 V1 boards have a different audio tuner input and use a | ||
159 | saa7114 instead of a saa7115. | ||
160 | Note that the info below comes from a pre-production model so it may | ||
161 | not be correct. Especially the audio behaves strangely (mono only it seems) */ | ||
162 | static const struct ivtv_card ivtv_card_pvr350_v1 = { | ||
163 | .type = IVTV_CARD_PVR_350_V1, | ||
164 | .name = "Hauppauge WinTV PVR-350 (V1)", | ||
165 | .v4l2_capabilities = IVTV_CAP_ENCODER | IVTV_CAP_DECODER, | ||
166 | .video_outputs = ivtv_pvr350_outputs, | ||
167 | .nof_outputs = ARRAY_SIZE(ivtv_pvr350_outputs), | ||
168 | .hw_video = IVTV_HW_SAA7114, | ||
169 | .hw_audio = IVTV_HW_MSP34XX, | ||
170 | .hw_audio_ctrl = IVTV_HW_MSP34XX, | ||
171 | .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7114 | | ||
172 | IVTV_HW_SAA7127 | IVTV_HW_TVEEPROM | IVTV_HW_TUNER, | ||
173 | .video_inputs = { | ||
174 | { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 }, | ||
175 | { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 }, | ||
176 | { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE0 }, | ||
177 | { IVTV_CARD_INPUT_SVIDEO2, 2, IVTV_SAA71XX_SVIDEO1 }, | ||
178 | { IVTV_CARD_INPUT_COMPOSITE2, 2, IVTV_SAA71XX_COMPOSITE1 }, | ||
179 | { IVTV_CARD_INPUT_COMPOSITE3, 1, IVTV_SAA71XX_COMPOSITE5 }, | ||
180 | }, | ||
181 | .audio_inputs = { | ||
182 | { IVTV_CARD_INPUT_AUD_TUNER, MSP_MONO }, | ||
183 | { IVTV_CARD_INPUT_LINE_IN1, MSP_SCART1 }, | ||
184 | { IVTV_CARD_INPUT_LINE_IN2, MSP_SCART3 }, | ||
185 | }, | ||
186 | .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, MSP_SCART2 }, | ||
187 | .i2c = &ivtv_i2c_std, | ||
188 | }; | ||
189 | |||
190 | /* ------------------------------------------------------------------------- */ | ||
191 | |||
192 | /* Hauppauge PVR-150/PVR-500 cards */ | ||
193 | |||
194 | static const struct ivtv_card ivtv_card_pvr150 = { | ||
195 | .type = IVTV_CARD_PVR_150, | ||
196 | .name = "Hauppauge WinTV PVR-150", | ||
197 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
198 | .hw_video = IVTV_HW_CX25840, | ||
199 | .hw_audio = IVTV_HW_CX25840, | ||
200 | .hw_audio_ctrl = IVTV_HW_CX25840, | ||
201 | .hw_muxer = IVTV_HW_WM8775, | ||
202 | .hw_all = IVTV_HW_WM8775 | IVTV_HW_CX25840 | | ||
203 | IVTV_HW_TVEEPROM | IVTV_HW_TUNER | | ||
204 | IVTV_HW_I2C_IR_RX_HAUP_EXT | IVTV_HW_I2C_IR_RX_HAUP_INT | | ||
205 | IVTV_HW_Z8F0811_IR_HAUP, | ||
206 | .video_inputs = { | ||
207 | { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE7 }, | ||
208 | { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO1 }, | ||
209 | { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE3 }, | ||
210 | { IVTV_CARD_INPUT_SVIDEO2, 2, CX25840_SVIDEO2 }, | ||
211 | { IVTV_CARD_INPUT_COMPOSITE2, 2, CX25840_COMPOSITE4 }, | ||
212 | }, | ||
213 | .audio_inputs = { | ||
214 | { IVTV_CARD_INPUT_AUD_TUNER, | ||
215 | CX25840_AUDIO8, WM8775_AIN2 }, | ||
216 | { IVTV_CARD_INPUT_LINE_IN1, | ||
217 | CX25840_AUDIO_SERIAL, WM8775_AIN2 }, | ||
218 | { IVTV_CARD_INPUT_LINE_IN2, | ||
219 | CX25840_AUDIO_SERIAL, WM8775_AIN3 }, | ||
220 | }, | ||
221 | .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, | ||
222 | CX25840_AUDIO_SERIAL, WM8775_AIN4 }, | ||
223 | /* apparently needed for the IR blaster */ | ||
224 | .gpio_init = { .direction = 0x1f01, .initial_value = 0x26f3 }, | ||
225 | .i2c = &ivtv_i2c_std, | ||
226 | }; | ||
227 | |||
228 | /* ------------------------------------------------------------------------- */ | ||
229 | |||
230 | /* AVerMedia M179 cards */ | ||
231 | |||
232 | static const struct ivtv_card_pci_info ivtv_pci_m179[] = { | ||
233 | { PCI_DEVICE_ID_IVTV15, IVTV_PCI_ID_AVERMEDIA, 0xa3cf }, | ||
234 | { PCI_DEVICE_ID_IVTV15, IVTV_PCI_ID_AVERMEDIA, 0xa3ce }, | ||
235 | { 0, 0, 0 } | ||
236 | }; | ||
237 | |||
238 | static const struct ivtv_card ivtv_card_m179 = { | ||
239 | .type = IVTV_CARD_M179, | ||
240 | .name = "AVerMedia M179", | ||
241 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
242 | .hw_video = IVTV_HW_SAA7114, | ||
243 | .hw_audio = IVTV_HW_GPIO, | ||
244 | .hw_audio_ctrl = IVTV_HW_GPIO, | ||
245 | .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7114 | IVTV_HW_TUNER, | ||
246 | .video_inputs = { | ||
247 | { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 }, | ||
248 | { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 }, | ||
249 | { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 }, | ||
250 | }, | ||
251 | .audio_inputs = { | ||
252 | { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER }, | ||
253 | { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN }, | ||
254 | }, | ||
255 | .gpio_init = { .direction = 0xe380, .initial_value = 0x8290 }, | ||
256 | .gpio_audio_input = { .mask = 0x8040, .tuner = 0x8000, .linein = 0x0000 }, | ||
257 | .gpio_audio_mute = { .mask = 0x2000, .mute = 0x2000 }, | ||
258 | .gpio_audio_mode = { .mask = 0x4300, .mono = 0x4000, .stereo = 0x0200, | ||
259 | .lang1 = 0x0200, .lang2 = 0x0100, .both = 0x0000 }, | ||
260 | .gpio_audio_freq = { .mask = 0x0018, .f32000 = 0x0000, | ||
261 | .f44100 = 0x0008, .f48000 = 0x0010 }, | ||
262 | .gpio_audio_detect = { .mask = 0x4000, .stereo = 0x0000 }, | ||
263 | .tuners = { | ||
264 | /* As far as we know all M179 cards use this tuner */ | ||
265 | { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_NTSC }, | ||
266 | }, | ||
267 | .pci_list = ivtv_pci_m179, | ||
268 | .i2c = &ivtv_i2c_std, | ||
269 | }; | ||
270 | |||
271 | /* ------------------------------------------------------------------------- */ | ||
272 | |||
273 | /* Yuan MPG600/Kuroutoshikou ITVC16-STVLP cards */ | ||
274 | |||
275 | static const struct ivtv_card_pci_info ivtv_pci_mpg600[] = { | ||
276 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN1, 0xfff3 }, | ||
277 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN1, 0xffff }, | ||
278 | { 0, 0, 0 } | ||
279 | }; | ||
280 | |||
281 | static const struct ivtv_card ivtv_card_mpg600 = { | ||
282 | .type = IVTV_CARD_MPG600, | ||
283 | .name = "Yuan MPG600, Kuroutoshikou ITVC16-STVLP", | ||
284 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
285 | .hw_video = IVTV_HW_SAA7115, | ||
286 | .hw_audio = IVTV_HW_GPIO, | ||
287 | .hw_audio_ctrl = IVTV_HW_GPIO, | ||
288 | .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TUNER, | ||
289 | .video_inputs = { | ||
290 | { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 }, | ||
291 | { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 }, | ||
292 | { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 }, | ||
293 | }, | ||
294 | .audio_inputs = { | ||
295 | { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER }, | ||
296 | { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN }, | ||
297 | }, | ||
298 | .gpio_init = { .direction = 0x3080, .initial_value = 0x0004 }, | ||
299 | .gpio_audio_input = { .mask = 0x3000, .tuner = 0x0000, .linein = 0x2000 }, | ||
300 | .gpio_audio_mute = { .mask = 0x0001, .mute = 0x0001 }, | ||
301 | .gpio_audio_mode = { .mask = 0x000e, .mono = 0x0006, .stereo = 0x0004, | ||
302 | .lang1 = 0x0004, .lang2 = 0x0000, .both = 0x0008 }, | ||
303 | .gpio_audio_detect = { .mask = 0x0900, .stereo = 0x0100 }, | ||
304 | .tuners = { | ||
305 | /* The PAL tuner is confirmed */ | ||
306 | { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FQ1216ME }, | ||
307 | { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 }, | ||
308 | }, | ||
309 | .pci_list = ivtv_pci_mpg600, | ||
310 | .i2c = &ivtv_i2c_std, | ||
311 | }; | ||
312 | |||
313 | /* ------------------------------------------------------------------------- */ | ||
314 | |||
315 | /* Yuan MPG160/Kuroutoshikou ITVC15-STVLP cards */ | ||
316 | |||
317 | static const struct ivtv_card_pci_info ivtv_pci_mpg160[] = { | ||
318 | { PCI_DEVICE_ID_IVTV15, IVTV_PCI_ID_YUAN1, 0 }, | ||
319 | { PCI_DEVICE_ID_IVTV15, IVTV_PCI_ID_IODATA, 0x40a0 }, | ||
320 | { 0, 0, 0 } | ||
321 | }; | ||
322 | |||
323 | static const struct ivtv_card ivtv_card_mpg160 = { | ||
324 | .type = IVTV_CARD_MPG160, | ||
325 | .name = "YUAN MPG160, Kuroutoshikou ITVC15-STVLP, I/O Data GV-M2TV/PCI", | ||
326 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
327 | .hw_video = IVTV_HW_SAA7114, | ||
328 | .hw_audio = IVTV_HW_GPIO, | ||
329 | .hw_audio_ctrl = IVTV_HW_GPIO, | ||
330 | .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7114 | IVTV_HW_TUNER, | ||
331 | .video_inputs = { | ||
332 | { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 }, | ||
333 | { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 }, | ||
334 | { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 }, | ||
335 | }, | ||
336 | .audio_inputs = { | ||
337 | { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER }, | ||
338 | { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN }, | ||
339 | }, | ||
340 | .gpio_init = { .direction = 0x7080, .initial_value = 0x400c }, | ||
341 | .gpio_audio_input = { .mask = 0x3000, .tuner = 0x0000, .linein = 0x2000 }, | ||
342 | .gpio_audio_mute = { .mask = 0x0001, .mute = 0x0001 }, | ||
343 | .gpio_audio_mode = { .mask = 0x000e, .mono = 0x0006, .stereo = 0x0004, | ||
344 | .lang1 = 0x0004, .lang2 = 0x0000, .both = 0x0008 }, | ||
345 | .gpio_audio_detect = { .mask = 0x0900, .stereo = 0x0100 }, | ||
346 | .tuners = { | ||
347 | { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FQ1216ME }, | ||
348 | { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 }, | ||
349 | }, | ||
350 | .pci_list = ivtv_pci_mpg160, | ||
351 | .i2c = &ivtv_i2c_std, | ||
352 | }; | ||
353 | |||
354 | /* ------------------------------------------------------------------------- */ | ||
355 | |||
356 | /* Yuan PG600/Diamond PVR-550 cards */ | ||
357 | |||
358 | static const struct ivtv_card_pci_info ivtv_pci_pg600[] = { | ||
359 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_DIAMONDMM, 0x0070 }, | ||
360 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN3, 0x0600 }, | ||
361 | { 0, 0, 0 } | ||
362 | }; | ||
363 | |||
364 | static const struct ivtv_card ivtv_card_pg600 = { | ||
365 | .type = IVTV_CARD_PG600, | ||
366 | .name = "Yuan PG600, Diamond PVR-550", | ||
367 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
368 | .hw_video = IVTV_HW_CX25840, | ||
369 | .hw_audio = IVTV_HW_CX25840, | ||
370 | .hw_audio_ctrl = IVTV_HW_CX25840, | ||
371 | .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER, | ||
372 | .video_inputs = { | ||
373 | { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 }, | ||
374 | { IVTV_CARD_INPUT_SVIDEO1, 1, | ||
375 | CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 }, | ||
376 | { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 }, | ||
377 | }, | ||
378 | .audio_inputs = { | ||
379 | { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 }, | ||
380 | { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL }, | ||
381 | }, | ||
382 | .tuners = { | ||
383 | { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FQ1216ME }, | ||
384 | { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 }, | ||
385 | }, | ||
386 | .pci_list = ivtv_pci_pg600, | ||
387 | .i2c = &ivtv_i2c_std, | ||
388 | }; | ||
389 | |||
390 | /* ------------------------------------------------------------------------- */ | ||
391 | |||
392 | /* Adaptec VideOh! AVC-2410 card */ | ||
393 | |||
394 | static const struct ivtv_card_pci_info ivtv_pci_avc2410[] = { | ||
395 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_ADAPTEC, 0x0093 }, | ||
396 | { 0, 0, 0 } | ||
397 | }; | ||
398 | |||
399 | static const struct ivtv_card ivtv_card_avc2410 = { | ||
400 | .type = IVTV_CARD_AVC2410, | ||
401 | .name = "Adaptec VideOh! AVC-2410", | ||
402 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
403 | .hw_video = IVTV_HW_SAA7115, | ||
404 | .hw_audio = IVTV_HW_MSP34XX, | ||
405 | .hw_audio_ctrl = IVTV_HW_MSP34XX, | ||
406 | .hw_muxer = IVTV_HW_CS53L32A, | ||
407 | .hw_all = IVTV_HW_MSP34XX | IVTV_HW_CS53L32A | | ||
408 | IVTV_HW_SAA7115 | IVTV_HW_TUNER | | ||
409 | IVTV_HW_I2C_IR_RX_ADAPTEC, | ||
410 | .video_inputs = { | ||
411 | { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 }, | ||
412 | { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 }, | ||
413 | { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 }, | ||
414 | }, | ||
415 | .audio_inputs = { | ||
416 | { IVTV_CARD_INPUT_AUD_TUNER, | ||
417 | MSP_TUNER, CS53L32A_IN0 }, | ||
418 | { IVTV_CARD_INPUT_LINE_IN1, | ||
419 | MSP_SCART1, CS53L32A_IN2 }, | ||
420 | }, | ||
421 | /* This card has no eeprom and in fact the Windows driver relies | ||
422 | on the country/region setting of the user to decide which tuner | ||
423 | is available. */ | ||
424 | .tuners = { | ||
425 | { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, | ||
426 | { .std = V4L2_STD_ALL - V4L2_STD_NTSC_M_JP, | ||
427 | .tuner = TUNER_PHILIPS_FM1236_MK3 }, | ||
428 | { .std = V4L2_STD_NTSC_M_JP, .tuner = TUNER_PHILIPS_FQ1286 }, | ||
429 | }, | ||
430 | .pci_list = ivtv_pci_avc2410, | ||
431 | .i2c = &ivtv_i2c_std, | ||
432 | }; | ||
433 | |||
434 | /* ------------------------------------------------------------------------- */ | ||
435 | |||
436 | /* Adaptec VideOh! AVC-2010 card */ | ||
437 | |||
438 | static const struct ivtv_card_pci_info ivtv_pci_avc2010[] = { | ||
439 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_ADAPTEC, 0x0092 }, | ||
440 | { 0, 0, 0 } | ||
441 | }; | ||
442 | |||
443 | static const struct ivtv_card ivtv_card_avc2010 = { | ||
444 | .type = IVTV_CARD_AVC2010, | ||
445 | .name = "Adaptec VideOh! AVC-2010", | ||
446 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
447 | .hw_video = IVTV_HW_SAA7115, | ||
448 | .hw_audio = IVTV_HW_CS53L32A, | ||
449 | .hw_audio_ctrl = IVTV_HW_CS53L32A, | ||
450 | .hw_all = IVTV_HW_CS53L32A | IVTV_HW_SAA7115, | ||
451 | .video_inputs = { | ||
452 | { IVTV_CARD_INPUT_SVIDEO1, 0, IVTV_SAA71XX_SVIDEO0 }, | ||
453 | { IVTV_CARD_INPUT_COMPOSITE1, 0, IVTV_SAA71XX_COMPOSITE3 }, | ||
454 | }, | ||
455 | .audio_inputs = { | ||
456 | { IVTV_CARD_INPUT_LINE_IN1, CS53L32A_IN2 }, | ||
457 | }, | ||
458 | /* Does not have a tuner */ | ||
459 | .pci_list = ivtv_pci_avc2010, | ||
460 | }; | ||
461 | |||
462 | /* ------------------------------------------------------------------------- */ | ||
463 | |||
464 | /* Nagase Transgear 5000TV card */ | ||
465 | |||
466 | static const struct ivtv_card_pci_info ivtv_pci_tg5000tv[] = { | ||
467 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xbfff }, | ||
468 | { 0, 0, 0 } | ||
469 | }; | ||
470 | |||
471 | static const struct ivtv_card ivtv_card_tg5000tv = { | ||
472 | .type = IVTV_CARD_TG5000TV, | ||
473 | .name = "Nagase Transgear 5000TV", | ||
474 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
475 | .hw_video = IVTV_HW_SAA7114 | IVTV_HW_UPD64031A | IVTV_HW_UPD6408X | | ||
476 | IVTV_HW_GPIO, | ||
477 | .hw_audio = IVTV_HW_GPIO, | ||
478 | .hw_audio_ctrl = IVTV_HW_GPIO, | ||
479 | .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7114 | IVTV_HW_TUNER | | ||
480 | IVTV_HW_UPD64031A | IVTV_HW_UPD6408X, | ||
481 | .video_inputs = { | ||
482 | { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_SVIDEO0 }, | ||
483 | { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO2 }, | ||
484 | { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_SVIDEO2 }, | ||
485 | }, | ||
486 | .audio_inputs = { | ||
487 | { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER }, | ||
488 | { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN }, | ||
489 | }, | ||
490 | .gr_config = UPD64031A_VERTICAL_EXTERNAL, | ||
491 | .gpio_init = { .direction = 0xe080, .initial_value = 0x8000 }, | ||
492 | .gpio_audio_input = { .mask = 0x8080, .tuner = 0x8000, .linein = 0x0080 }, | ||
493 | .gpio_audio_mute = { .mask = 0x6000, .mute = 0x6000 }, | ||
494 | .gpio_audio_mode = { .mask = 0x4300, .mono = 0x4000, .stereo = 0x0200, | ||
495 | .lang1 = 0x0300, .lang2 = 0x0000, .both = 0x0200 }, | ||
496 | .gpio_video_input = { .mask = 0x0030, .tuner = 0x0000, | ||
497 | .composite = 0x0010, .svideo = 0x0020 }, | ||
498 | .tuners = { | ||
499 | { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 }, | ||
500 | }, | ||
501 | .pci_list = ivtv_pci_tg5000tv, | ||
502 | .i2c = &ivtv_i2c_std, | ||
503 | }; | ||
504 | |||
505 | /* ------------------------------------------------------------------------- */ | ||
506 | |||
507 | /* AOpen VA2000MAX-SNT6 card */ | ||
508 | |||
509 | static const struct ivtv_card_pci_info ivtv_pci_va2000[] = { | ||
510 | { PCI_DEVICE_ID_IVTV16, 0, 0xff5f }, | ||
511 | { 0, 0, 0 } | ||
512 | }; | ||
513 | |||
514 | static const struct ivtv_card ivtv_card_va2000 = { | ||
515 | .type = IVTV_CARD_VA2000MAX_SNT6, | ||
516 | .name = "AOpen VA2000MAX-SNT6", | ||
517 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
518 | .hw_video = IVTV_HW_SAA7115 | IVTV_HW_UPD6408X, | ||
519 | .hw_audio = IVTV_HW_MSP34XX, | ||
520 | .hw_audio_ctrl = IVTV_HW_MSP34XX, | ||
521 | .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7115 | | ||
522 | IVTV_HW_UPD6408X | IVTV_HW_TUNER, | ||
523 | .video_inputs = { | ||
524 | { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_SVIDEO0 }, | ||
525 | }, | ||
526 | .audio_inputs = { | ||
527 | { IVTV_CARD_INPUT_AUD_TUNER, MSP_TUNER }, | ||
528 | }, | ||
529 | .tuners = { | ||
530 | { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 }, | ||
531 | }, | ||
532 | .pci_list = ivtv_pci_va2000, | ||
533 | .i2c = &ivtv_i2c_std, | ||
534 | }; | ||
535 | |||
536 | /* ------------------------------------------------------------------------- */ | ||
537 | |||
538 | /* Yuan MPG600GR/Kuroutoshikou CX23416GYC-STVLP cards */ | ||
539 | |||
540 | static const struct ivtv_card_pci_info ivtv_pci_cx23416gyc[] = { | ||
541 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN1, 0x0600 }, | ||
542 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN4, 0x0600 }, | ||
543 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_MELCO, 0x0523 }, | ||
544 | { 0, 0, 0 } | ||
545 | }; | ||
546 | |||
547 | static const struct ivtv_card ivtv_card_cx23416gyc = { | ||
548 | .type = IVTV_CARD_CX23416GYC, | ||
549 | .name = "Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP", | ||
550 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
551 | .hw_video = IVTV_HW_SAA717X | IVTV_HW_GPIO | | ||
552 | IVTV_HW_UPD64031A | IVTV_HW_UPD6408X, | ||
553 | .hw_audio = IVTV_HW_SAA717X, | ||
554 | .hw_audio_ctrl = IVTV_HW_SAA717X, | ||
555 | .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA717X | IVTV_HW_TUNER | | ||
556 | IVTV_HW_UPD64031A | IVTV_HW_UPD6408X, | ||
557 | .video_inputs = { | ||
558 | { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_SVIDEO3 | | ||
559 | IVTV_SAA717X_TUNER_FLAG }, | ||
560 | { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 }, | ||
561 | { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_SVIDEO3 }, | ||
562 | }, | ||
563 | .audio_inputs = { | ||
564 | { IVTV_CARD_INPUT_AUD_TUNER, IVTV_SAA717X_IN2 }, | ||
565 | { IVTV_CARD_INPUT_LINE_IN1, IVTV_SAA717X_IN0 }, | ||
566 | }, | ||
567 | .gr_config = UPD64031A_VERTICAL_EXTERNAL, | ||
568 | .gpio_init = { .direction = 0xf880, .initial_value = 0x8800 }, | ||
569 | .gpio_video_input = { .mask = 0x0020, .tuner = 0x0000, | ||
570 | .composite = 0x0020, .svideo = 0x0020 }, | ||
571 | .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000, | ||
572 | .f44100 = 0x4000, .f48000 = 0x8000 }, | ||
573 | .tuners = { | ||
574 | { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, | ||
575 | { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 }, | ||
576 | }, | ||
577 | .pci_list = ivtv_pci_cx23416gyc, | ||
578 | .i2c = &ivtv_i2c_std, | ||
579 | }; | ||
580 | |||
581 | static const struct ivtv_card ivtv_card_cx23416gyc_nogr = { | ||
582 | .type = IVTV_CARD_CX23416GYC_NOGR, | ||
583 | .name = "Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR)", | ||
584 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
585 | .hw_video = IVTV_HW_SAA717X | IVTV_HW_GPIO | IVTV_HW_UPD6408X, | ||
586 | .hw_audio = IVTV_HW_SAA717X, | ||
587 | .hw_audio_ctrl = IVTV_HW_SAA717X, | ||
588 | .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA717X | IVTV_HW_TUNER | | ||
589 | IVTV_HW_UPD6408X, | ||
590 | .video_inputs = { | ||
591 | { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 | | ||
592 | IVTV_SAA717X_TUNER_FLAG }, | ||
593 | { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 }, | ||
594 | { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE0 }, | ||
595 | }, | ||
596 | .audio_inputs = { | ||
597 | { IVTV_CARD_INPUT_AUD_TUNER, IVTV_SAA717X_IN2 }, | ||
598 | { IVTV_CARD_INPUT_LINE_IN1, IVTV_SAA717X_IN0 }, | ||
599 | }, | ||
600 | .gpio_init = { .direction = 0xf880, .initial_value = 0x8800 }, | ||
601 | .gpio_video_input = { .mask = 0x0020, .tuner = 0x0000, | ||
602 | .composite = 0x0020, .svideo = 0x0020 }, | ||
603 | .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000, | ||
604 | .f44100 = 0x4000, .f48000 = 0x8000 }, | ||
605 | .tuners = { | ||
606 | { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, | ||
607 | { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 }, | ||
608 | }, | ||
609 | .i2c = &ivtv_i2c_std, | ||
610 | }; | ||
611 | |||
612 | static const struct ivtv_card ivtv_card_cx23416gyc_nogrycs = { | ||
613 | .type = IVTV_CARD_CX23416GYC_NOGRYCS, | ||
614 | .name = "Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR/YCS)", | ||
615 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
616 | .hw_video = IVTV_HW_SAA717X | IVTV_HW_GPIO, | ||
617 | .hw_audio = IVTV_HW_SAA717X, | ||
618 | .hw_audio_ctrl = IVTV_HW_SAA717X, | ||
619 | .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA717X | IVTV_HW_TUNER, | ||
620 | .video_inputs = { | ||
621 | { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 | | ||
622 | IVTV_SAA717X_TUNER_FLAG }, | ||
623 | { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 }, | ||
624 | { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE0 }, | ||
625 | }, | ||
626 | .audio_inputs = { | ||
627 | { IVTV_CARD_INPUT_AUD_TUNER, IVTV_SAA717X_IN2 }, | ||
628 | { IVTV_CARD_INPUT_LINE_IN1, IVTV_SAA717X_IN0 }, | ||
629 | }, | ||
630 | .gpio_init = { .direction = 0xf880, .initial_value = 0x8800 }, | ||
631 | .gpio_video_input = { .mask = 0x0020, .tuner = 0x0000, | ||
632 | .composite = 0x0020, .svideo = 0x0020 }, | ||
633 | .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000, | ||
634 | .f44100 = 0x4000, .f48000 = 0x8000 }, | ||
635 | .tuners = { | ||
636 | { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, | ||
637 | { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 }, | ||
638 | }, | ||
639 | .i2c = &ivtv_i2c_std, | ||
640 | }; | ||
641 | |||
642 | /* ------------------------------------------------------------------------- */ | ||
643 | |||
644 | /* I/O Data GV-MVP/RX & GV-MVP/RX2W (dual tuner) cards */ | ||
645 | |||
646 | static const struct ivtv_card_pci_info ivtv_pci_gv_mvprx[] = { | ||
647 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_IODATA, 0xd01e }, | ||
648 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_IODATA, 0xd038 }, /* 2W unit #1 */ | ||
649 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_IODATA, 0xd039 }, /* 2W unit #2 */ | ||
650 | { 0, 0, 0 } | ||
651 | }; | ||
652 | |||
653 | static const struct ivtv_card ivtv_card_gv_mvprx = { | ||
654 | .type = IVTV_CARD_GV_MVPRX, | ||
655 | .name = "I/O Data GV-MVP/RX, GV-MVP/RX2W (dual tuner)", | ||
656 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
657 | .hw_video = IVTV_HW_SAA7115 | IVTV_HW_UPD64031A | IVTV_HW_UPD6408X, | ||
658 | .hw_audio = IVTV_HW_GPIO, | ||
659 | .hw_audio_ctrl = IVTV_HW_WM8739, | ||
660 | .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_VP27SMPX | | ||
661 | IVTV_HW_TUNER | IVTV_HW_WM8739 | | ||
662 | IVTV_HW_UPD64031A | IVTV_HW_UPD6408X, | ||
663 | .video_inputs = { | ||
664 | { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_SVIDEO0 }, | ||
665 | { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO1 }, | ||
666 | { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_SVIDEO2 }, | ||
667 | }, | ||
668 | .audio_inputs = { | ||
669 | { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER }, | ||
670 | { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN }, | ||
671 | }, | ||
672 | .gpio_init = { .direction = 0xc301, .initial_value = 0x0200 }, | ||
673 | .gpio_audio_input = { .mask = 0xffff, .tuner = 0x0200, .linein = 0x0300 }, | ||
674 | .tuners = { | ||
675 | /* This card has the Panasonic VP27 tuner */ | ||
676 | { .std = V4L2_STD_MN, .tuner = TUNER_PANASONIC_VP27 }, | ||
677 | }, | ||
678 | .pci_list = ivtv_pci_gv_mvprx, | ||
679 | .i2c = &ivtv_i2c_std, | ||
680 | }; | ||
681 | |||
682 | /* ------------------------------------------------------------------------- */ | ||
683 | |||
684 | /* I/O Data GV-MVP/RX2E card */ | ||
685 | |||
686 | static const struct ivtv_card_pci_info ivtv_pci_gv_mvprx2e[] = { | ||
687 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_IODATA, 0xd025 }, | ||
688 | {0, 0, 0} | ||
689 | }; | ||
690 | |||
691 | static const struct ivtv_card ivtv_card_gv_mvprx2e = { | ||
692 | .type = IVTV_CARD_GV_MVPRX2E, | ||
693 | .name = "I/O Data GV-MVP/RX2E", | ||
694 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
695 | .hw_video = IVTV_HW_SAA7115, | ||
696 | .hw_audio = IVTV_HW_GPIO, | ||
697 | .hw_audio_ctrl = IVTV_HW_WM8739, | ||
698 | .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TUNER | | ||
699 | IVTV_HW_VP27SMPX | IVTV_HW_WM8739, | ||
700 | .video_inputs = { | ||
701 | { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 }, | ||
702 | { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 }, | ||
703 | { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 }, | ||
704 | }, | ||
705 | .audio_inputs = { | ||
706 | { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER }, | ||
707 | { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN }, | ||
708 | }, | ||
709 | .gpio_init = { .direction = 0xc301, .initial_value = 0x0200 }, | ||
710 | .gpio_audio_input = { .mask = 0xffff, .tuner = 0x0200, .linein = 0x0300 }, | ||
711 | .tuners = { | ||
712 | /* This card has the Panasonic VP27 tuner */ | ||
713 | { .std = V4L2_STD_MN, .tuner = TUNER_PANASONIC_VP27 }, | ||
714 | }, | ||
715 | .pci_list = ivtv_pci_gv_mvprx2e, | ||
716 | .i2c = &ivtv_i2c_std, | ||
717 | }; | ||
718 | |||
719 | /* ------------------------------------------------------------------------- */ | ||
720 | |||
721 | /* GotVIEW PCI DVD card */ | ||
722 | |||
723 | static const struct ivtv_card_pci_info ivtv_pci_gotview_pci_dvd[] = { | ||
724 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN1, 0x0600 }, | ||
725 | { 0, 0, 0 } | ||
726 | }; | ||
727 | |||
728 | static const struct ivtv_card ivtv_card_gotview_pci_dvd = { | ||
729 | .type = IVTV_CARD_GOTVIEW_PCI_DVD, | ||
730 | .name = "GotView PCI DVD", | ||
731 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
732 | .hw_video = IVTV_HW_SAA717X, | ||
733 | .hw_audio = IVTV_HW_SAA717X, | ||
734 | .hw_audio_ctrl = IVTV_HW_SAA717X, | ||
735 | .hw_all = IVTV_HW_SAA717X | IVTV_HW_TUNER, | ||
736 | .video_inputs = { | ||
737 | { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE1 }, /* pin 116 */ | ||
738 | { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 }, /* pin 114/109 */ | ||
739 | { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 }, /* pin 118 */ | ||
740 | }, | ||
741 | .audio_inputs = { | ||
742 | { IVTV_CARD_INPUT_AUD_TUNER, IVTV_SAA717X_IN0 }, | ||
743 | { IVTV_CARD_INPUT_LINE_IN1, IVTV_SAA717X_IN2 }, | ||
744 | }, | ||
745 | .gpio_init = { .direction = 0xf000, .initial_value = 0xA000 }, | ||
746 | .tuners = { | ||
747 | /* This card has a Philips FQ1216ME MK3 tuner */ | ||
748 | { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, | ||
749 | }, | ||
750 | .pci_list = ivtv_pci_gotview_pci_dvd, | ||
751 | .i2c = &ivtv_i2c_std, | ||
752 | }; | ||
753 | |||
754 | /* ------------------------------------------------------------------------- */ | ||
755 | |||
756 | /* GotVIEW PCI DVD2 Deluxe card */ | ||
757 | |||
758 | static const struct ivtv_card_pci_info ivtv_pci_gotview_pci_dvd2[] = { | ||
759 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_GOTVIEW1, 0x0600 }, | ||
760 | { 0, 0, 0 } | ||
761 | }; | ||
762 | |||
763 | static const struct ivtv_card ivtv_card_gotview_pci_dvd2 = { | ||
764 | .type = IVTV_CARD_GOTVIEW_PCI_DVD2, | ||
765 | .name = "GotView PCI DVD2 Deluxe", | ||
766 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
767 | .hw_video = IVTV_HW_CX25840, | ||
768 | .hw_audio = IVTV_HW_CX25840, | ||
769 | .hw_audio_ctrl = IVTV_HW_CX25840, | ||
770 | .hw_muxer = IVTV_HW_GPIO, | ||
771 | .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER, | ||
772 | .video_inputs = { | ||
773 | { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 }, | ||
774 | { IVTV_CARD_INPUT_SVIDEO1, 1, | ||
775 | CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 }, | ||
776 | { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 }, | ||
777 | }, | ||
778 | .audio_inputs = { | ||
779 | { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5, 0 }, | ||
780 | { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 }, | ||
781 | }, | ||
782 | .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 }, | ||
783 | .gpio_init = { .direction = 0x0800, .initial_value = 0 }, | ||
784 | .gpio_audio_input = { .mask = 0x0800, .tuner = 0, .linein = 0, .radio = 0x0800 }, | ||
785 | .tuners = { | ||
786 | /* This card has a Philips FQ1216ME MK5 tuner */ | ||
787 | { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, | ||
788 | }, | ||
789 | .pci_list = ivtv_pci_gotview_pci_dvd2, | ||
790 | .i2c = &ivtv_i2c_std, | ||
791 | }; | ||
792 | |||
793 | /* ------------------------------------------------------------------------- */ | ||
794 | |||
795 | /* Yuan MPC622 miniPCI card */ | ||
796 | |||
797 | static const struct ivtv_card_pci_info ivtv_pci_yuan_mpc622[] = { | ||
798 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN2, 0xd998 }, | ||
799 | { 0, 0, 0 } | ||
800 | }; | ||
801 | |||
802 | static const struct ivtv_card ivtv_card_yuan_mpc622 = { | ||
803 | .type = IVTV_CARD_YUAN_MPC622, | ||
804 | .name = "Yuan MPC622", | ||
805 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
806 | .hw_video = IVTV_HW_CX25840, | ||
807 | .hw_audio = IVTV_HW_CX25840, | ||
808 | .hw_audio_ctrl = IVTV_HW_CX25840, | ||
809 | .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER, | ||
810 | .video_inputs = { | ||
811 | { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 }, | ||
812 | { IVTV_CARD_INPUT_SVIDEO1, 1, | ||
813 | CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 }, | ||
814 | { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 }, | ||
815 | }, | ||
816 | .audio_inputs = { | ||
817 | { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 }, | ||
818 | { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL }, | ||
819 | }, | ||
820 | .gpio_init = { .direction = 0x00ff, .initial_value = 0x0002 }, | ||
821 | .tuners = { | ||
822 | /* This card has the TDA8290/TDA8275 tuner chips */ | ||
823 | { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_TDA8290 }, | ||
824 | }, | ||
825 | .pci_list = ivtv_pci_yuan_mpc622, | ||
826 | .i2c = &ivtv_i2c_tda8290, | ||
827 | }; | ||
828 | |||
829 | /* ------------------------------------------------------------------------- */ | ||
830 | |||
831 | /* DIGITAL COWBOY DCT-MTVP1 card */ | ||
832 | |||
833 | static const struct ivtv_card_pci_info ivtv_pci_dctmvtvp1[] = { | ||
834 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xbfff }, | ||
835 | { 0, 0, 0 } | ||
836 | }; | ||
837 | |||
838 | static const struct ivtv_card ivtv_card_dctmvtvp1 = { | ||
839 | .type = IVTV_CARD_DCTMTVP1, | ||
840 | .name = "Digital Cowboy DCT-MTVP1", | ||
841 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
842 | .hw_video = IVTV_HW_SAA7115 | IVTV_HW_UPD64031A | IVTV_HW_UPD6408X | | ||
843 | IVTV_HW_GPIO, | ||
844 | .hw_audio = IVTV_HW_GPIO, | ||
845 | .hw_audio_ctrl = IVTV_HW_GPIO, | ||
846 | .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TUNER | | ||
847 | IVTV_HW_UPD64031A | IVTV_HW_UPD6408X, | ||
848 | .video_inputs = { | ||
849 | { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_SVIDEO0 }, | ||
850 | { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO2 }, | ||
851 | { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_SVIDEO2 }, | ||
852 | }, | ||
853 | .audio_inputs = { | ||
854 | { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER }, | ||
855 | { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN }, | ||
856 | }, | ||
857 | .gpio_init = { .direction = 0xe080, .initial_value = 0x8000 }, | ||
858 | .gpio_audio_input = { .mask = 0x8080, .tuner = 0x8000, .linein = 0x0080 }, | ||
859 | .gpio_audio_mute = { .mask = 0x6000, .mute = 0x6000 }, | ||
860 | .gpio_audio_mode = { .mask = 0x4300, .mono = 0x4000, .stereo = 0x0200, | ||
861 | .lang1 = 0x0300, .lang2 = 0x0000, .both = 0x0200 }, | ||
862 | .gpio_video_input = { .mask = 0x0030, .tuner = 0x0000, | ||
863 | .composite = 0x0010, .svideo = 0x0020}, | ||
864 | .tuners = { | ||
865 | { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 }, | ||
866 | }, | ||
867 | .pci_list = ivtv_pci_dctmvtvp1, | ||
868 | .i2c = &ivtv_i2c_std, | ||
869 | }; | ||
870 | |||
871 | /* ------------------------------------------------------------------------- */ | ||
872 | |||
873 | /* Yuan PG600-2/GotView PCI DVD Lite cards */ | ||
874 | |||
875 | static const struct ivtv_card_pci_info ivtv_pci_pg600v2[] = { | ||
876 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN3, 0x0600 }, | ||
877 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_GOTVIEW2, 0x0600 }, | ||
878 | { 0, 0, 0 } | ||
879 | }; | ||
880 | |||
881 | static const struct ivtv_card ivtv_card_pg600v2 = { | ||
882 | .type = IVTV_CARD_PG600V2, | ||
883 | .name = "Yuan PG600-2, GotView PCI DVD Lite", | ||
884 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
885 | .hw_video = IVTV_HW_CX25840, | ||
886 | .hw_audio = IVTV_HW_CX25840, | ||
887 | .hw_audio_ctrl = IVTV_HW_CX25840, | ||
888 | .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER, | ||
889 | /* XC2028 support apparently works for the Yuan, it's still | ||
890 | uncertain whether it also works with the GotView. */ | ||
891 | .video_inputs = { | ||
892 | { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 }, | ||
893 | { IVTV_CARD_INPUT_SVIDEO1, 1, | ||
894 | CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 }, | ||
895 | { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 }, | ||
896 | }, | ||
897 | .audio_inputs = { | ||
898 | { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 }, | ||
899 | { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL }, | ||
900 | }, | ||
901 | .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 }, | ||
902 | .xceive_pin = 12, | ||
903 | .tuners = { | ||
904 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, | ||
905 | }, | ||
906 | .pci_list = ivtv_pci_pg600v2, | ||
907 | .i2c = &ivtv_i2c_std, | ||
908 | }; | ||
909 | |||
910 | /* ------------------------------------------------------------------------- */ | ||
911 | |||
912 | /* Club3D ZAP-TV1x01 cards */ | ||
913 | |||
914 | static const struct ivtv_card_pci_info ivtv_pci_club3d[] = { | ||
915 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN3, 0x0600 }, | ||
916 | { 0, 0, 0 } | ||
917 | }; | ||
918 | |||
919 | static const struct ivtv_card ivtv_card_club3d = { | ||
920 | .type = IVTV_CARD_CLUB3D, | ||
921 | .name = "Club3D ZAP-TV1x01", | ||
922 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
923 | .hw_video = IVTV_HW_CX25840, | ||
924 | .hw_audio = IVTV_HW_CX25840, | ||
925 | .hw_audio_ctrl = IVTV_HW_CX25840, | ||
926 | .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER, | ||
927 | .video_inputs = { | ||
928 | { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 }, | ||
929 | { IVTV_CARD_INPUT_SVIDEO1, 1, | ||
930 | CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 }, | ||
931 | { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE3 }, | ||
932 | }, | ||
933 | .audio_inputs = { | ||
934 | { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 }, | ||
935 | { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL }, | ||
936 | }, | ||
937 | .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 }, | ||
938 | .xceive_pin = 12, | ||
939 | .tuners = { | ||
940 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, | ||
941 | }, | ||
942 | .pci_list = ivtv_pci_club3d, | ||
943 | .i2c = &ivtv_i2c_std, | ||
944 | }; | ||
945 | |||
946 | /* ------------------------------------------------------------------------- */ | ||
947 | |||
948 | /* AVerTV MCE 116 Plus (M116) card */ | ||
949 | |||
950 | static const struct ivtv_card_pci_info ivtv_pci_avertv_mce116[] = { | ||
951 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc439 }, | ||
952 | { 0, 0, 0 } | ||
953 | }; | ||
954 | |||
955 | static const struct ivtv_card ivtv_card_avertv_mce116 = { | ||
956 | .type = IVTV_CARD_AVERTV_MCE116, | ||
957 | .name = "AVerTV MCE 116 Plus", | ||
958 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
959 | .hw_video = IVTV_HW_CX25840, | ||
960 | .hw_audio = IVTV_HW_CX25840, | ||
961 | .hw_audio_ctrl = IVTV_HW_CX25840, | ||
962 | .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739 | | ||
963 | IVTV_HW_I2C_IR_RX_AVER, | ||
964 | .video_inputs = { | ||
965 | { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 }, | ||
966 | { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 }, | ||
967 | { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 }, | ||
968 | }, | ||
969 | .audio_inputs = { | ||
970 | { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 }, | ||
971 | { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 }, | ||
972 | }, | ||
973 | .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 }, | ||
974 | /* enable line-in */ | ||
975 | .gpio_init = { .direction = 0xe000, .initial_value = 0x4000 }, | ||
976 | .xceive_pin = 10, | ||
977 | .tuners = { | ||
978 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, | ||
979 | }, | ||
980 | .pci_list = ivtv_pci_avertv_mce116, | ||
981 | .i2c = &ivtv_i2c_std, | ||
982 | }; | ||
983 | |||
984 | /* ------------------------------------------------------------------------- */ | ||
985 | |||
986 | /* AVerMedia PVR-150 Plus / AVerTV M113 cards with a Daewoo/Partsnic Tuner */ | ||
987 | |||
988 | static const struct ivtv_card_pci_info ivtv_pci_aver_pvr150[] = { | ||
989 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc034 }, /* NTSC */ | ||
990 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc035 }, /* NTSC FM */ | ||
991 | { 0, 0, 0 } | ||
992 | }; | ||
993 | |||
994 | static const struct ivtv_card ivtv_card_aver_pvr150 = { | ||
995 | .type = IVTV_CARD_AVER_PVR150PLUS, | ||
996 | .name = "AVerMedia PVR-150 Plus / AVerTV M113 Partsnic (Daewoo) Tuner", | ||
997 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
998 | .hw_video = IVTV_HW_CX25840, | ||
999 | .hw_audio = IVTV_HW_CX25840, | ||
1000 | .hw_audio_ctrl = IVTV_HW_CX25840, | ||
1001 | .hw_muxer = IVTV_HW_GPIO, | ||
1002 | .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | | ||
1003 | IVTV_HW_WM8739 | IVTV_HW_GPIO, | ||
1004 | .video_inputs = { | ||
1005 | { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 }, | ||
1006 | { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 }, | ||
1007 | { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 }, | ||
1008 | }, | ||
1009 | .audio_inputs = { | ||
1010 | { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5, 0 }, | ||
1011 | { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 }, | ||
1012 | }, | ||
1013 | .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 }, | ||
1014 | /* The 74HC4052 Dual 4:1 multiplexer is controlled by 2 GPIO lines */ | ||
1015 | .gpio_init = { .direction = 0xc000, .initial_value = 0 }, | ||
1016 | .gpio_audio_input = { .mask = 0xc000, | ||
1017 | .tuner = 0x0000, | ||
1018 | .linein = 0x4000, | ||
1019 | .radio = 0x8000 }, | ||
1020 | .tuners = { | ||
1021 | /* Subsystem ID's 0xc03[45] have a Partsnic PTI-5NF05 tuner */ | ||
1022 | { .std = V4L2_STD_MN, .tuner = TUNER_PARTSNIC_PTI_5NF05 }, | ||
1023 | }, | ||
1024 | .pci_list = ivtv_pci_aver_pvr150, | ||
1025 | /* Subsystem ID 0xc035 has a TEA5767(?) FM tuner, 0xc034 does not */ | ||
1026 | .i2c = &ivtv_i2c_radio, | ||
1027 | }; | ||
1028 | |||
1029 | /* ------------------------------------------------------------------------- */ | ||
1030 | |||
1031 | /* AVerMedia UltraTV 1500 MCE (newer non-cx88 version, M113 variant) card */ | ||
1032 | |||
1033 | static const struct ivtv_card_pci_info ivtv_pci_aver_ultra1500mce[] = { | ||
1034 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc019 }, /* NTSC */ | ||
1035 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc01b }, /* PAL/SECAM */ | ||
1036 | { 0, 0, 0 } | ||
1037 | }; | ||
1038 | |||
1039 | static const struct ivtv_card ivtv_card_aver_ultra1500mce = { | ||
1040 | .type = IVTV_CARD_AVER_ULTRA1500MCE, | ||
1041 | .name = "AVerMedia UltraTV 1500 MCE / AVerTV M113 Philips Tuner", | ||
1042 | .comment = "For non-NTSC tuners, use the pal= or secam= module options", | ||
1043 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
1044 | .hw_video = IVTV_HW_CX25840, | ||
1045 | .hw_audio = IVTV_HW_CX25840, | ||
1046 | .hw_audio_ctrl = IVTV_HW_CX25840, | ||
1047 | .hw_muxer = IVTV_HW_GPIO, | ||
1048 | .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | | ||
1049 | IVTV_HW_WM8739 | IVTV_HW_GPIO, | ||
1050 | .video_inputs = { | ||
1051 | { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 }, | ||
1052 | { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 }, | ||
1053 | { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 }, | ||
1054 | }, | ||
1055 | .audio_inputs = { | ||
1056 | { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5, 0 }, | ||
1057 | { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 }, | ||
1058 | }, | ||
1059 | .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 }, | ||
1060 | /* The 74HC4052 Dual 4:1 multiplexer is controlled by 2 GPIO lines */ | ||
1061 | .gpio_init = { .direction = 0xc000, .initial_value = 0 }, | ||
1062 | .gpio_audio_input = { .mask = 0xc000, | ||
1063 | .tuner = 0x0000, | ||
1064 | .linein = 0x4000, | ||
1065 | .radio = 0x8000 }, | ||
1066 | .tuners = { | ||
1067 | /* The UltraTV 1500 MCE has a Philips FM1236 MK5 TV/FM tuner */ | ||
1068 | { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 }, | ||
1069 | { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216MK5 }, | ||
1070 | }, | ||
1071 | .pci_list = ivtv_pci_aver_ultra1500mce, | ||
1072 | .i2c = &ivtv_i2c_std, | ||
1073 | }; | ||
1074 | |||
1075 | /* ------------------------------------------------------------------------- */ | ||
1076 | |||
1077 | /* AVerMedia EZMaker PCI Deluxe card */ | ||
1078 | |||
1079 | static const struct ivtv_card_pci_info ivtv_pci_aver_ezmaker[] = { | ||
1080 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc03f }, | ||
1081 | { 0, 0, 0 } | ||
1082 | }; | ||
1083 | |||
1084 | static const struct ivtv_card ivtv_card_aver_ezmaker = { | ||
1085 | .type = IVTV_CARD_AVER_EZMAKER, | ||
1086 | .name = "AVerMedia EZMaker PCI Deluxe", | ||
1087 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
1088 | .hw_video = IVTV_HW_CX25840, | ||
1089 | .hw_audio = IVTV_HW_CX25840, | ||
1090 | .hw_audio_ctrl = IVTV_HW_CX25840, | ||
1091 | .hw_all = IVTV_HW_CX25840 | IVTV_HW_WM8739, | ||
1092 | .video_inputs = { | ||
1093 | { IVTV_CARD_INPUT_SVIDEO1, 0, CX25840_SVIDEO3 }, | ||
1094 | { IVTV_CARD_INPUT_COMPOSITE1, 0, CX25840_COMPOSITE1 }, | ||
1095 | }, | ||
1096 | .audio_inputs = { | ||
1097 | { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 0 }, | ||
1098 | }, | ||
1099 | .gpio_init = { .direction = 0x4000, .initial_value = 0x4000 }, | ||
1100 | /* Does not have a tuner */ | ||
1101 | .pci_list = ivtv_pci_aver_ezmaker, | ||
1102 | }; | ||
1103 | |||
1104 | /* ------------------------------------------------------------------------- */ | ||
1105 | |||
1106 | /* ASUS Falcon2 */ | ||
1107 | |||
1108 | static const struct ivtv_card_pci_info ivtv_pci_asus_falcon2[] = { | ||
1109 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_ASUSTEK, 0x4b66 }, | ||
1110 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_ASUSTEK, 0x462e }, | ||
1111 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_ASUSTEK, 0x4b2e }, | ||
1112 | { 0, 0, 0 } | ||
1113 | }; | ||
1114 | |||
1115 | static const struct ivtv_card ivtv_card_asus_falcon2 = { | ||
1116 | .type = IVTV_CARD_ASUS_FALCON2, | ||
1117 | .name = "ASUS Falcon2", | ||
1118 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
1119 | .hw_video = IVTV_HW_CX25840, | ||
1120 | .hw_audio = IVTV_HW_CX25840, | ||
1121 | .hw_audio_ctrl = IVTV_HW_CX25840, | ||
1122 | .hw_muxer = IVTV_HW_M52790, | ||
1123 | .hw_all = IVTV_HW_CX25840 | IVTV_HW_M52790 | IVTV_HW_TUNER, | ||
1124 | .video_inputs = { | ||
1125 | { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 }, | ||
1126 | { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 }, | ||
1127 | { IVTV_CARD_INPUT_COMPOSITE1, 2, CX25840_COMPOSITE2 }, | ||
1128 | }, | ||
1129 | .audio_inputs = { | ||
1130 | { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5, M52790_IN_TUNER }, | ||
1131 | { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, | ||
1132 | M52790_IN_V2 | M52790_SW1_YCMIX | M52790_SW2_YCMIX }, | ||
1133 | { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, M52790_IN_V2 }, | ||
1134 | }, | ||
1135 | .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, M52790_IN_TUNER }, | ||
1136 | .tuners = { | ||
1137 | { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 }, | ||
1138 | }, | ||
1139 | .pci_list = ivtv_pci_asus_falcon2, | ||
1140 | .i2c = &ivtv_i2c_std, | ||
1141 | }; | ||
1142 | |||
1143 | /* ------------------------------------------------------------------------- */ | ||
1144 | |||
1145 | /* AVerMedia M104 miniPCI card */ | ||
1146 | |||
1147 | static const struct ivtv_card_pci_info ivtv_pci_aver_m104[] = { | ||
1148 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc136 }, | ||
1149 | { 0, 0, 0 } | ||
1150 | }; | ||
1151 | |||
1152 | static const struct ivtv_card ivtv_card_aver_m104 = { | ||
1153 | .type = IVTV_CARD_AVER_M104, | ||
1154 | .name = "AVerMedia M104", | ||
1155 | .comment = "Not yet supported!\n", | ||
1156 | .v4l2_capabilities = 0, /*IVTV_CAP_ENCODER,*/ | ||
1157 | .hw_video = IVTV_HW_CX25840, | ||
1158 | .hw_audio = IVTV_HW_CX25840, | ||
1159 | .hw_audio_ctrl = IVTV_HW_CX25840, | ||
1160 | .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739, | ||
1161 | .video_inputs = { | ||
1162 | { IVTV_CARD_INPUT_SVIDEO1, 0, CX25840_SVIDEO3 }, | ||
1163 | { IVTV_CARD_INPUT_COMPOSITE1, 0, CX25840_COMPOSITE1 }, | ||
1164 | }, | ||
1165 | .audio_inputs = { | ||
1166 | { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 }, | ||
1167 | }, | ||
1168 | .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 }, | ||
1169 | /* enable line-in + reset tuner */ | ||
1170 | .gpio_init = { .direction = 0xe000, .initial_value = 0x4000 }, | ||
1171 | .xceive_pin = 10, | ||
1172 | .tuners = { | ||
1173 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, | ||
1174 | }, | ||
1175 | .pci_list = ivtv_pci_aver_m104, | ||
1176 | .i2c = &ivtv_i2c_std, | ||
1177 | }; | ||
1178 | |||
1179 | /* ------------------------------------------------------------------------- */ | ||
1180 | |||
1181 | /* Buffalo PC-MV5L/PCI cards */ | ||
1182 | |||
1183 | static const struct ivtv_card_pci_info ivtv_pci_buffalo[] = { | ||
1184 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_MELCO, 0x052b }, | ||
1185 | { 0, 0, 0 } | ||
1186 | }; | ||
1187 | |||
1188 | static const struct ivtv_card ivtv_card_buffalo = { | ||
1189 | .type = IVTV_CARD_BUFFALO_MV5L, | ||
1190 | .name = "Buffalo PC-MV5L/PCI", | ||
1191 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
1192 | .hw_video = IVTV_HW_CX25840, | ||
1193 | .hw_audio = IVTV_HW_CX25840, | ||
1194 | .hw_audio_ctrl = IVTV_HW_CX25840, | ||
1195 | .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER, | ||
1196 | .video_inputs = { | ||
1197 | { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 }, | ||
1198 | { IVTV_CARD_INPUT_SVIDEO1, 1, | ||
1199 | CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 }, | ||
1200 | { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 }, | ||
1201 | }, | ||
1202 | .audio_inputs = { | ||
1203 | { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 }, | ||
1204 | { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL }, | ||
1205 | }, | ||
1206 | .xceive_pin = 12, | ||
1207 | .tuners = { | ||
1208 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, | ||
1209 | }, | ||
1210 | .pci_list = ivtv_pci_buffalo, | ||
1211 | .i2c = &ivtv_i2c_std, | ||
1212 | }; | ||
1213 | |||
1214 | /* ------------------------------------------------------------------------- */ | ||
1215 | /* Sony Kikyou */ | ||
1216 | |||
1217 | static const struct ivtv_card_pci_info ivtv_pci_kikyou[] = { | ||
1218 | { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_SONY, 0x813d }, | ||
1219 | { 0, 0, 0 } | ||
1220 | }; | ||
1221 | |||
1222 | static const struct ivtv_card ivtv_card_kikyou = { | ||
1223 | .type = IVTV_CARD_KIKYOU, | ||
1224 | .name = "Sony VAIO Giga Pocket (ENX Kikyou)", | ||
1225 | .v4l2_capabilities = IVTV_CAP_ENCODER, | ||
1226 | .hw_video = IVTV_HW_SAA7115, | ||
1227 | .hw_audio = IVTV_HW_GPIO, | ||
1228 | .hw_audio_ctrl = IVTV_HW_GPIO, | ||
1229 | .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TUNER, | ||
1230 | .video_inputs = { | ||
1231 | { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE1 }, | ||
1232 | { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE1 }, | ||
1233 | { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO1 }, | ||
1234 | }, | ||
1235 | .audio_inputs = { | ||
1236 | { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER }, | ||
1237 | { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN }, | ||
1238 | { IVTV_CARD_INPUT_LINE_IN2, IVTV_GPIO_LINE_IN }, | ||
1239 | }, | ||
1240 | .gpio_init = { .direction = 0x03e1, .initial_value = 0x0320 }, | ||
1241 | .gpio_audio_input = { .mask = 0x0060, | ||
1242 | .tuner = 0x0020, | ||
1243 | .linein = 0x0000, | ||
1244 | .radio = 0x0060 }, | ||
1245 | .gpio_audio_mute = { .mask = 0x0000, | ||
1246 | .mute = 0x0000 }, /* 0x200? Disable for now. */ | ||
1247 | .gpio_audio_mode = { .mask = 0x0080, | ||
1248 | .mono = 0x0000, | ||
1249 | .stereo = 0x0000, /* SAP */ | ||
1250 | .lang1 = 0x0080, | ||
1251 | .lang2 = 0x0000, | ||
1252 | .both = 0x0080 }, | ||
1253 | .tuners = { | ||
1254 | { .std = V4L2_STD_ALL, .tuner = TUNER_SONY_BTF_PXN01Z }, | ||
1255 | }, | ||
1256 | .pci_list = ivtv_pci_kikyou, | ||
1257 | .i2c = &ivtv_i2c_std, | ||
1258 | }; | ||
1259 | |||
1260 | |||
1261 | static const struct ivtv_card *ivtv_card_list[] = { | ||
1262 | &ivtv_card_pvr250, | ||
1263 | &ivtv_card_pvr350, | ||
1264 | &ivtv_card_pvr150, | ||
1265 | &ivtv_card_m179, | ||
1266 | &ivtv_card_mpg600, | ||
1267 | &ivtv_card_mpg160, | ||
1268 | &ivtv_card_pg600, | ||
1269 | &ivtv_card_avc2410, | ||
1270 | &ivtv_card_avc2010, | ||
1271 | &ivtv_card_tg5000tv, | ||
1272 | &ivtv_card_va2000, | ||
1273 | &ivtv_card_cx23416gyc, | ||
1274 | &ivtv_card_gv_mvprx, | ||
1275 | &ivtv_card_gv_mvprx2e, | ||
1276 | &ivtv_card_gotview_pci_dvd, | ||
1277 | &ivtv_card_gotview_pci_dvd2, | ||
1278 | &ivtv_card_yuan_mpc622, | ||
1279 | &ivtv_card_dctmvtvp1, | ||
1280 | &ivtv_card_pg600v2, | ||
1281 | &ivtv_card_club3d, | ||
1282 | &ivtv_card_avertv_mce116, | ||
1283 | &ivtv_card_asus_falcon2, | ||
1284 | &ivtv_card_aver_pvr150, | ||
1285 | &ivtv_card_aver_ezmaker, | ||
1286 | &ivtv_card_aver_m104, | ||
1287 | &ivtv_card_buffalo, | ||
1288 | &ivtv_card_aver_ultra1500mce, | ||
1289 | &ivtv_card_kikyou, | ||
1290 | |||
1291 | /* Variations of standard cards but with the same PCI IDs. | ||
1292 | These cards must come last in this list. */ | ||
1293 | &ivtv_card_pvr350_v1, | ||
1294 | &ivtv_card_cx23416gyc_nogr, | ||
1295 | &ivtv_card_cx23416gyc_nogrycs, | ||
1296 | }; | ||
1297 | |||
1298 | const struct ivtv_card *ivtv_get_card(u16 index) | ||
1299 | { | ||
1300 | if (index >= ARRAY_SIZE(ivtv_card_list)) | ||
1301 | return NULL; | ||
1302 | return ivtv_card_list[index]; | ||
1303 | } | ||
1304 | |||
1305 | int ivtv_get_input(struct ivtv *itv, u16 index, struct v4l2_input *input) | ||
1306 | { | ||
1307 | const struct ivtv_card_video_input *card_input = itv->card->video_inputs + index; | ||
1308 | static const char * const input_strs[] = { | ||
1309 | "Tuner 1", | ||
1310 | "S-Video 1", | ||
1311 | "S-Video 2", | ||
1312 | "Composite 1", | ||
1313 | "Composite 2", | ||
1314 | "Composite 3" | ||
1315 | }; | ||
1316 | |||
1317 | if (index >= itv->nof_inputs) | ||
1318 | return -EINVAL; | ||
1319 | input->index = index; | ||
1320 | strlcpy(input->name, input_strs[card_input->video_type - 1], | ||
1321 | sizeof(input->name)); | ||
1322 | input->type = (card_input->video_type == IVTV_CARD_INPUT_VID_TUNER ? | ||
1323 | V4L2_INPUT_TYPE_TUNER : V4L2_INPUT_TYPE_CAMERA); | ||
1324 | input->audioset = (1 << itv->nof_audio_inputs) - 1; | ||
1325 | input->std = (input->type == V4L2_INPUT_TYPE_TUNER) ? | ||
1326 | itv->tuner_std : V4L2_STD_ALL; | ||
1327 | return 0; | ||
1328 | } | ||
1329 | |||
1330 | int ivtv_get_output(struct ivtv *itv, u16 index, struct v4l2_output *output) | ||
1331 | { | ||
1332 | const struct ivtv_card_output *card_output = itv->card->video_outputs + index; | ||
1333 | |||
1334 | if (index >= itv->card->nof_outputs) | ||
1335 | return -EINVAL; | ||
1336 | output->index = index; | ||
1337 | strlcpy(output->name, card_output->name, sizeof(output->name)); | ||
1338 | output->type = V4L2_OUTPUT_TYPE_ANALOG; | ||
1339 | output->audioset = 1; | ||
1340 | output->std = V4L2_STD_ALL; | ||
1341 | return 0; | ||
1342 | } | ||
1343 | |||
1344 | int ivtv_get_audio_input(struct ivtv *itv, u16 index, struct v4l2_audio *audio) | ||
1345 | { | ||
1346 | const struct ivtv_card_audio_input *aud_input = itv->card->audio_inputs + index; | ||
1347 | static const char * const input_strs[] = { | ||
1348 | "Tuner 1", | ||
1349 | "Line In 1", | ||
1350 | "Line In 2" | ||
1351 | }; | ||
1352 | |||
1353 | memset(audio, 0, sizeof(*audio)); | ||
1354 | if (index >= itv->nof_audio_inputs) | ||
1355 | return -EINVAL; | ||
1356 | strlcpy(audio->name, input_strs[aud_input->audio_type - 1], | ||
1357 | sizeof(audio->name)); | ||
1358 | audio->index = index; | ||
1359 | audio->capability = V4L2_AUDCAP_STEREO; | ||
1360 | return 0; | ||
1361 | } | ||
1362 | |||
1363 | int ivtv_get_audio_output(struct ivtv *itv, u16 index, struct v4l2_audioout *aud_output) | ||
1364 | { | ||
1365 | memset(aud_output, 0, sizeof(*aud_output)); | ||
1366 | if (itv->card->video_outputs == NULL || index != 0) | ||
1367 | return -EINVAL; | ||
1368 | strlcpy(aud_output->name, "A/V Audio Out", sizeof(aud_output->name)); | ||
1369 | return 0; | ||
1370 | } | ||
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h new file mode 100644 index 00000000000..e6f5c02981f --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-cards.h | |||
@@ -0,0 +1,309 @@ | |||
1 | /* | ||
2 | Functions to query card hardware | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #ifndef IVTV_CARDS_H | ||
22 | #define IVTV_CARDS_H | ||
23 | |||
24 | /* Supported cards */ | ||
25 | #define IVTV_CARD_PVR_250 0 /* WinTV PVR 250 */ | ||
26 | #define IVTV_CARD_PVR_350 1 /* encoder, decoder, tv-out */ | ||
27 | #define IVTV_CARD_PVR_150 2 /* WinTV PVR 150 and PVR 500 (really just two | ||
28 | PVR150s on one PCI board) */ | ||
29 | #define IVTV_CARD_M179 3 /* AVerMedia M179 (encoder only) */ | ||
30 | #define IVTV_CARD_MPG600 4 /* Kuroutoshikou ITVC16-STVLP/YUAN MPG600, encoder only */ | ||
31 | #define IVTV_CARD_MPG160 5 /* Kuroutoshikou ITVC15-STVLP/YUAN MPG160 | ||
32 | cx23415 based, but does not have tv-out */ | ||
33 | #define IVTV_CARD_PG600 6 /* YUAN PG600/DIAMONDMM PVR-550 based on the CX Falcon 2 */ | ||
34 | #define IVTV_CARD_AVC2410 7 /* Adaptec AVC-2410 */ | ||
35 | #define IVTV_CARD_AVC2010 8 /* Adaptec AVD-2010 (No Tuner) */ | ||
36 | #define IVTV_CARD_TG5000TV 9 /* NAGASE TRANSGEAR 5000TV, encoder only */ | ||
37 | #define IVTV_CARD_VA2000MAX_SNT6 10 /* VA2000MAX-STN6 */ | ||
38 | #define IVTV_CARD_CX23416GYC 11 /* Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */ | ||
39 | #define IVTV_CARD_GV_MVPRX 12 /* I/O Data GV-MVP/RX, RX2, RX2W */ | ||
40 | #define IVTV_CARD_GV_MVPRX2E 13 /* I/O Data GV-MVP/RX2E */ | ||
41 | #define IVTV_CARD_GOTVIEW_PCI_DVD 14 /* GotView PCI DVD */ | ||
42 | #define IVTV_CARD_GOTVIEW_PCI_DVD2 15 /* GotView PCI DVD2 */ | ||
43 | #define IVTV_CARD_YUAN_MPC622 16 /* Yuan MPC622 miniPCI */ | ||
44 | #define IVTV_CARD_DCTMTVP1 17 /* DIGITAL COWBOY DCT-MTVP1 */ | ||
45 | #define IVTV_CARD_PG600V2 18 /* Yuan PG600V2/GotView PCI DVD Lite */ | ||
46 | #define IVTV_CARD_CLUB3D 19 /* Club3D ZAP-TV1x01 */ | ||
47 | #define IVTV_CARD_AVERTV_MCE116 20 /* AVerTV MCE 116 Plus */ | ||
48 | #define IVTV_CARD_ASUS_FALCON2 21 /* ASUS Falcon2 */ | ||
49 | #define IVTV_CARD_AVER_PVR150PLUS 22 /* AVerMedia PVR-150 Plus */ | ||
50 | #define IVTV_CARD_AVER_EZMAKER 23 /* AVerMedia EZMaker PCI Deluxe */ | ||
51 | #define IVTV_CARD_AVER_M104 24 /* AverMedia M104 miniPCI card */ | ||
52 | #define IVTV_CARD_BUFFALO_MV5L 25 /* Buffalo PC-MV5L/PCI card */ | ||
53 | #define IVTV_CARD_AVER_ULTRA1500MCE 26 /* AVerMedia UltraTV 1500 MCE */ | ||
54 | #define IVTV_CARD_KIKYOU 27 /* Sony VAIO Giga Pocket (ENX Kikyou) */ | ||
55 | #define IVTV_CARD_LAST 27 | ||
56 | |||
57 | /* Variants of existing cards but with the same PCI IDs. The driver | ||
58 | detects these based on other device information. | ||
59 | These cards must always come last. | ||
60 | New cards must be inserted above, and the indices of the cards below | ||
61 | must be adjusted accordingly. */ | ||
62 | |||
63 | /* PVR-350 V1 (uses saa7114) */ | ||
64 | #define IVTV_CARD_PVR_350_V1 (IVTV_CARD_LAST+1) | ||
65 | /* 2 variants of Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */ | ||
66 | #define IVTV_CARD_CX23416GYC_NOGR (IVTV_CARD_LAST+2) | ||
67 | #define IVTV_CARD_CX23416GYC_NOGRYCS (IVTV_CARD_LAST+3) | ||
68 | |||
69 | /* system vendor and device IDs */ | ||
70 | #define PCI_VENDOR_ID_ICOMP 0x4444 | ||
71 | #define PCI_DEVICE_ID_IVTV15 0x0803 | ||
72 | #define PCI_DEVICE_ID_IVTV16 0x0016 | ||
73 | |||
74 | /* subsystem vendor ID */ | ||
75 | #define IVTV_PCI_ID_HAUPPAUGE 0x0070 | ||
76 | #define IVTV_PCI_ID_HAUPPAUGE_ALT1 0x0270 | ||
77 | #define IVTV_PCI_ID_HAUPPAUGE_ALT2 0x4070 | ||
78 | #define IVTV_PCI_ID_ADAPTEC 0x9005 | ||
79 | #define IVTV_PCI_ID_ASUSTEK 0x1043 | ||
80 | #define IVTV_PCI_ID_AVERMEDIA 0x1461 | ||
81 | #define IVTV_PCI_ID_YUAN1 0x12ab | ||
82 | #define IVTV_PCI_ID_YUAN2 0xff01 | ||
83 | #define IVTV_PCI_ID_YUAN3 0xffab | ||
84 | #define IVTV_PCI_ID_YUAN4 0xfbab | ||
85 | #define IVTV_PCI_ID_DIAMONDMM 0xff92 | ||
86 | #define IVTV_PCI_ID_IODATA 0x10fc | ||
87 | #define IVTV_PCI_ID_MELCO 0x1154 | ||
88 | #define IVTV_PCI_ID_GOTVIEW1 0xffac | ||
89 | #define IVTV_PCI_ID_GOTVIEW2 0xffad | ||
90 | #define IVTV_PCI_ID_SONY 0x104d | ||
91 | |||
92 | /* hardware flags, no gaps allowed */ | ||
93 | #define IVTV_HW_CX25840 (1 << 0) | ||
94 | #define IVTV_HW_SAA7115 (1 << 1) | ||
95 | #define IVTV_HW_SAA7127 (1 << 2) | ||
96 | #define IVTV_HW_MSP34XX (1 << 3) | ||
97 | #define IVTV_HW_TUNER (1 << 4) | ||
98 | #define IVTV_HW_WM8775 (1 << 5) | ||
99 | #define IVTV_HW_CS53L32A (1 << 6) | ||
100 | #define IVTV_HW_TVEEPROM (1 << 7) | ||
101 | #define IVTV_HW_SAA7114 (1 << 8) | ||
102 | #define IVTV_HW_UPD64031A (1 << 9) | ||
103 | #define IVTV_HW_UPD6408X (1 << 10) | ||
104 | #define IVTV_HW_SAA717X (1 << 11) | ||
105 | #define IVTV_HW_WM8739 (1 << 12) | ||
106 | #define IVTV_HW_VP27SMPX (1 << 13) | ||
107 | #define IVTV_HW_M52790 (1 << 14) | ||
108 | #define IVTV_HW_GPIO (1 << 15) | ||
109 | #define IVTV_HW_I2C_IR_RX_AVER (1 << 16) | ||
110 | #define IVTV_HW_I2C_IR_RX_HAUP_EXT (1 << 17) /* External before internal */ | ||
111 | #define IVTV_HW_I2C_IR_RX_HAUP_INT (1 << 18) | ||
112 | #define IVTV_HW_Z8F0811_IR_TX_HAUP (1 << 19) | ||
113 | #define IVTV_HW_Z8F0811_IR_RX_HAUP (1 << 20) | ||
114 | #define IVTV_HW_I2C_IR_RX_ADAPTEC (1 << 21) | ||
115 | |||
116 | #define IVTV_HW_Z8F0811_IR_HAUP (IVTV_HW_Z8F0811_IR_RX_HAUP | \ | ||
117 | IVTV_HW_Z8F0811_IR_TX_HAUP) | ||
118 | |||
119 | #define IVTV_HW_SAA711X (IVTV_HW_SAA7115 | IVTV_HW_SAA7114) | ||
120 | |||
121 | #define IVTV_HW_IR_RX_ANY (IVTV_HW_I2C_IR_RX_AVER | \ | ||
122 | IVTV_HW_I2C_IR_RX_HAUP_EXT | \ | ||
123 | IVTV_HW_I2C_IR_RX_HAUP_INT | \ | ||
124 | IVTV_HW_Z8F0811_IR_RX_HAUP | \ | ||
125 | IVTV_HW_I2C_IR_RX_ADAPTEC) | ||
126 | |||
127 | #define IVTV_HW_IR_TX_ANY (IVTV_HW_Z8F0811_IR_TX_HAUP) | ||
128 | |||
129 | #define IVTV_HW_IR_ANY (IVTV_HW_IR_RX_ANY | IVTV_HW_IR_TX_ANY) | ||
130 | |||
131 | /* video inputs */ | ||
132 | #define IVTV_CARD_INPUT_VID_TUNER 1 | ||
133 | #define IVTV_CARD_INPUT_SVIDEO1 2 | ||
134 | #define IVTV_CARD_INPUT_SVIDEO2 3 | ||
135 | #define IVTV_CARD_INPUT_COMPOSITE1 4 | ||
136 | #define IVTV_CARD_INPUT_COMPOSITE2 5 | ||
137 | #define IVTV_CARD_INPUT_COMPOSITE3 6 | ||
138 | |||
139 | /* audio inputs */ | ||
140 | #define IVTV_CARD_INPUT_AUD_TUNER 1 | ||
141 | #define IVTV_CARD_INPUT_LINE_IN1 2 | ||
142 | #define IVTV_CARD_INPUT_LINE_IN2 3 | ||
143 | |||
144 | #define IVTV_CARD_MAX_VIDEO_INPUTS 6 | ||
145 | #define IVTV_CARD_MAX_AUDIO_INPUTS 3 | ||
146 | #define IVTV_CARD_MAX_TUNERS 3 | ||
147 | |||
148 | /* SAA71XX HW inputs */ | ||
149 | #define IVTV_SAA71XX_COMPOSITE0 0 | ||
150 | #define IVTV_SAA71XX_COMPOSITE1 1 | ||
151 | #define IVTV_SAA71XX_COMPOSITE2 2 | ||
152 | #define IVTV_SAA71XX_COMPOSITE3 3 | ||
153 | #define IVTV_SAA71XX_COMPOSITE4 4 | ||
154 | #define IVTV_SAA71XX_COMPOSITE5 5 | ||
155 | #define IVTV_SAA71XX_SVIDEO0 6 | ||
156 | #define IVTV_SAA71XX_SVIDEO1 7 | ||
157 | #define IVTV_SAA71XX_SVIDEO2 8 | ||
158 | #define IVTV_SAA71XX_SVIDEO3 9 | ||
159 | |||
160 | /* SAA717X needs to mark the tuner input by ORing with this flag */ | ||
161 | #define IVTV_SAA717X_TUNER_FLAG 0x80 | ||
162 | |||
163 | /* Dummy HW input */ | ||
164 | #define IVTV_DUMMY_AUDIO 0 | ||
165 | |||
166 | /* GPIO HW inputs */ | ||
167 | #define IVTV_GPIO_TUNER 0 | ||
168 | #define IVTV_GPIO_LINE_IN 1 | ||
169 | |||
170 | /* SAA717X HW inputs */ | ||
171 | #define IVTV_SAA717X_IN0 0 | ||
172 | #define IVTV_SAA717X_IN1 1 | ||
173 | #define IVTV_SAA717X_IN2 2 | ||
174 | |||
175 | /* V4L2 capability aliases */ | ||
176 | #define IVTV_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \ | ||
177 | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE | \ | ||
178 | V4L2_CAP_SLICED_VBI_CAPTURE) | ||
179 | #define IVTV_CAP_DECODER (V4L2_CAP_VIDEO_OUTPUT | \ | ||
180 | V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY) | ||
181 | |||
182 | struct ivtv_card_video_input { | ||
183 | u8 video_type; /* video input type */ | ||
184 | u8 audio_index; /* index in ivtv_card_audio_input array */ | ||
185 | u16 video_input; /* hardware video input */ | ||
186 | }; | ||
187 | |||
188 | struct ivtv_card_audio_input { | ||
189 | u8 audio_type; /* audio input type */ | ||
190 | u32 audio_input; /* hardware audio input */ | ||
191 | u16 muxer_input; /* hardware muxer input for boards with a | ||
192 | multiplexer chip */ | ||
193 | }; | ||
194 | |||
195 | struct ivtv_card_output { | ||
196 | u8 name[32]; | ||
197 | u16 video_output; /* hardware video output */ | ||
198 | }; | ||
199 | |||
200 | struct ivtv_card_pci_info { | ||
201 | u16 device; | ||
202 | u16 subsystem_vendor; | ||
203 | u16 subsystem_device; | ||
204 | }; | ||
205 | |||
206 | /* GPIO definitions */ | ||
207 | |||
208 | /* The mask is the set of bits used by the operation */ | ||
209 | |||
210 | struct ivtv_gpio_init { /* set initial GPIO DIR and OUT values */ | ||
211 | u16 direction; /* DIR setting. Leave to 0 if no init is needed */ | ||
212 | u16 initial_value; | ||
213 | }; | ||
214 | |||
215 | struct ivtv_gpio_video_input { /* select tuner/line in input */ | ||
216 | u16 mask; /* leave to 0 if not supported */ | ||
217 | u16 tuner; | ||
218 | u16 composite; | ||
219 | u16 svideo; | ||
220 | }; | ||
221 | |||
222 | struct ivtv_gpio_audio_input { /* select tuner/line in input */ | ||
223 | u16 mask; /* leave to 0 if not supported */ | ||
224 | u16 tuner; | ||
225 | u16 linein; | ||
226 | u16 radio; | ||
227 | }; | ||
228 | |||
229 | struct ivtv_gpio_audio_mute { | ||
230 | u16 mask; /* leave to 0 if not supported */ | ||
231 | u16 mute; /* set this value to mute, 0 to unmute */ | ||
232 | }; | ||
233 | |||
234 | struct ivtv_gpio_audio_mode { | ||
235 | u16 mask; /* leave to 0 if not supported */ | ||
236 | u16 mono; /* set audio to mono */ | ||
237 | u16 stereo; /* set audio to stereo */ | ||
238 | u16 lang1; /* set audio to the first language */ | ||
239 | u16 lang2; /* set audio to the second language */ | ||
240 | u16 both; /* both languages are output */ | ||
241 | }; | ||
242 | |||
243 | struct ivtv_gpio_audio_freq { | ||
244 | u16 mask; /* leave to 0 if not supported */ | ||
245 | u16 f32000; | ||
246 | u16 f44100; | ||
247 | u16 f48000; | ||
248 | }; | ||
249 | |||
250 | struct ivtv_gpio_audio_detect { | ||
251 | u16 mask; /* leave to 0 if not supported */ | ||
252 | u16 stereo; /* if the input matches this value then | ||
253 | stereo is detected */ | ||
254 | }; | ||
255 | |||
256 | struct ivtv_card_tuner { | ||
257 | v4l2_std_id std; /* standard for which the tuner is suitable */ | ||
258 | int tuner; /* tuner ID (from tuner.h) */ | ||
259 | }; | ||
260 | |||
261 | struct ivtv_card_tuner_i2c { | ||
262 | unsigned short radio[2];/* radio tuner i2c address to probe */ | ||
263 | unsigned short demod[2];/* demodulator i2c address to probe */ | ||
264 | unsigned short tv[4]; /* tv tuner i2c addresses to probe */ | ||
265 | }; | ||
266 | |||
267 | /* for card information/parameters */ | ||
268 | struct ivtv_card { | ||
269 | int type; | ||
270 | char *name; | ||
271 | char *comment; | ||
272 | u32 v4l2_capabilities; | ||
273 | u32 hw_video; /* hardware used to process video */ | ||
274 | u32 hw_audio; /* hardware used to process audio */ | ||
275 | u32 hw_audio_ctrl; /* hardware used for the V4L2 controls (only 1 dev allowed) */ | ||
276 | u32 hw_muxer; /* hardware used to multiplex audio input */ | ||
277 | u32 hw_all; /* all hardware used by the board */ | ||
278 | struct ivtv_card_video_input video_inputs[IVTV_CARD_MAX_VIDEO_INPUTS]; | ||
279 | struct ivtv_card_audio_input audio_inputs[IVTV_CARD_MAX_AUDIO_INPUTS]; | ||
280 | struct ivtv_card_audio_input radio_input; | ||
281 | int nof_outputs; | ||
282 | const struct ivtv_card_output *video_outputs; | ||
283 | u8 gr_config; /* config byte for the ghost reduction device */ | ||
284 | u8 xceive_pin; /* XCeive tuner GPIO reset pin */ | ||
285 | |||
286 | /* GPIO card-specific settings */ | ||
287 | struct ivtv_gpio_init gpio_init; | ||
288 | struct ivtv_gpio_video_input gpio_video_input; | ||
289 | struct ivtv_gpio_audio_input gpio_audio_input; | ||
290 | struct ivtv_gpio_audio_mute gpio_audio_mute; | ||
291 | struct ivtv_gpio_audio_mode gpio_audio_mode; | ||
292 | struct ivtv_gpio_audio_freq gpio_audio_freq; | ||
293 | struct ivtv_gpio_audio_detect gpio_audio_detect; | ||
294 | |||
295 | struct ivtv_card_tuner tuners[IVTV_CARD_MAX_TUNERS]; | ||
296 | struct ivtv_card_tuner_i2c *i2c; | ||
297 | |||
298 | /* list of device and subsystem vendor/devices that | ||
299 | correspond to this card type. */ | ||
300 | const struct ivtv_card_pci_info *pci_list; | ||
301 | }; | ||
302 | |||
303 | int ivtv_get_input(struct ivtv *itv, u16 index, struct v4l2_input *input); | ||
304 | int ivtv_get_output(struct ivtv *itv, u16 index, struct v4l2_output *output); | ||
305 | int ivtv_get_audio_input(struct ivtv *itv, u16 index, struct v4l2_audio *input); | ||
306 | int ivtv_get_audio_output(struct ivtv *itv, u16 index, struct v4l2_audioout *output); | ||
307 | const struct ivtv_card *ivtv_get_card(u16 index); | ||
308 | |||
309 | #endif | ||
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c new file mode 100644 index 00000000000..b31ee1bceef --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-controls.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /* | ||
2 | ioctl control functions | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include "ivtv-driver.h" | ||
22 | #include "ivtv-ioctl.h" | ||
23 | #include "ivtv-controls.h" | ||
24 | |||
25 | static int ivtv_s_stream_vbi_fmt(struct cx2341x_handler *cxhdl, u32 fmt) | ||
26 | { | ||
27 | struct ivtv *itv = container_of(cxhdl, struct ivtv, cxhdl); | ||
28 | |||
29 | /* First try to allocate sliced VBI buffers if needed. */ | ||
30 | if (fmt && itv->vbi.sliced_mpeg_data[0] == NULL) { | ||
31 | int i; | ||
32 | |||
33 | for (i = 0; i < IVTV_VBI_FRAMES; i++) { | ||
34 | /* Yuck, hardcoded. Needs to be a define */ | ||
35 | itv->vbi.sliced_mpeg_data[i] = kmalloc(2049, GFP_KERNEL); | ||
36 | if (itv->vbi.sliced_mpeg_data[i] == NULL) { | ||
37 | while (--i >= 0) { | ||
38 | kfree(itv->vbi.sliced_mpeg_data[i]); | ||
39 | itv->vbi.sliced_mpeg_data[i] = NULL; | ||
40 | } | ||
41 | return -ENOMEM; | ||
42 | } | ||
43 | } | ||
44 | } | ||
45 | |||
46 | itv->vbi.insert_mpeg = fmt; | ||
47 | |||
48 | if (itv->vbi.insert_mpeg == 0) { | ||
49 | return 0; | ||
50 | } | ||
51 | /* Need sliced data for mpeg insertion */ | ||
52 | if (ivtv_get_service_set(itv->vbi.sliced_in) == 0) { | ||
53 | if (itv->is_60hz) | ||
54 | itv->vbi.sliced_in->service_set = V4L2_SLICED_CAPTION_525; | ||
55 | else | ||
56 | itv->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625; | ||
57 | ivtv_expand_service_set(itv->vbi.sliced_in, itv->is_50hz); | ||
58 | } | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | static int ivtv_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val) | ||
63 | { | ||
64 | struct ivtv *itv = container_of(cxhdl, struct ivtv, cxhdl); | ||
65 | int is_mpeg1 = val == V4L2_MPEG_VIDEO_ENCODING_MPEG_1; | ||
66 | struct v4l2_mbus_framefmt fmt; | ||
67 | |||
68 | /* fix videodecoder resolution */ | ||
69 | fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1); | ||
70 | fmt.height = cxhdl->height; | ||
71 | fmt.code = V4L2_MBUS_FMT_FIXED; | ||
72 | v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &fmt); | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static int ivtv_s_audio_sampling_freq(struct cx2341x_handler *cxhdl, u32 idx) | ||
77 | { | ||
78 | static const u32 freqs[3] = { 44100, 48000, 32000 }; | ||
79 | struct ivtv *itv = container_of(cxhdl, struct ivtv, cxhdl); | ||
80 | |||
81 | /* The audio clock of the digitizer must match the codec sample | ||
82 | rate otherwise you get some very strange effects. */ | ||
83 | if (idx < ARRAY_SIZE(freqs)) | ||
84 | ivtv_call_all(itv, audio, s_clock_freq, freqs[idx]); | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static int ivtv_s_audio_mode(struct cx2341x_handler *cxhdl, u32 val) | ||
89 | { | ||
90 | struct ivtv *itv = container_of(cxhdl, struct ivtv, cxhdl); | ||
91 | |||
92 | itv->dualwatch_stereo_mode = val; | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | struct cx2341x_handler_ops ivtv_cxhdl_ops = { | ||
97 | .s_audio_mode = ivtv_s_audio_mode, | ||
98 | .s_audio_sampling_freq = ivtv_s_audio_sampling_freq, | ||
99 | .s_video_encoding = ivtv_s_video_encoding, | ||
100 | .s_stream_vbi_fmt = ivtv_s_stream_vbi_fmt, | ||
101 | }; | ||
diff --git a/drivers/media/video/ivtv/ivtv-controls.h b/drivers/media/video/ivtv/ivtv-controls.h new file mode 100644 index 00000000000..d12893dd018 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-controls.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | ioctl control functions | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #ifndef IVTV_CONTROLS_H | ||
22 | #define IVTV_CONTROLS_H | ||
23 | |||
24 | extern struct cx2341x_handler_ops ivtv_cxhdl_ops; | ||
25 | |||
26 | #endif | ||
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c new file mode 100644 index 00000000000..0fb75524484 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-driver.c | |||
@@ -0,0 +1,1472 @@ | |||
1 | /* | ||
2 | ivtv driver initialization and card probing | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2004 Chris Kennedy <c@groovy.org> | ||
5 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | /* Main Driver file for the ivtv project: | ||
23 | * Driver for the Conexant CX23415/CX23416 chip. | ||
24 | * Author: Kevin Thayer (nufan_wfk at yahoo.com) | ||
25 | * License: GPL | ||
26 | * http://www.ivtvdriver.org | ||
27 | * | ||
28 | * ----- | ||
29 | * MPG600/MPG160 support by T.Adachi <tadachi@tadachi-net.com> | ||
30 | * and Takeru KOMORIYA<komoriya@paken.org> | ||
31 | * | ||
32 | * AVerMedia M179 GPIO info by Chris Pinkham <cpinkham@bc2va.org> | ||
33 | * using information provided by Jiun-Kuei Jung @ AVerMedia. | ||
34 | * | ||
35 | * Kurouto Sikou CX23416GYC-STVLP tested by K.Ohta <alpha292@bremen.or.jp> | ||
36 | * using information from T.Adachi,Takeru KOMORIYA and others :-) | ||
37 | * | ||
38 | * Nagase TRANSGEAR 5000TV, Aopen VA2000MAX-STN6 and I/O data GV-MVP/RX | ||
39 | * version by T.Adachi. Special thanks Mr.Suzuki | ||
40 | */ | ||
41 | |||
42 | #include "ivtv-driver.h" | ||
43 | #include "ivtv-version.h" | ||
44 | #include "ivtv-fileops.h" | ||
45 | #include "ivtv-i2c.h" | ||
46 | #include "ivtv-firmware.h" | ||
47 | #include "ivtv-queue.h" | ||
48 | #include "ivtv-udma.h" | ||
49 | #include "ivtv-irq.h" | ||
50 | #include "ivtv-mailbox.h" | ||
51 | #include "ivtv-streams.h" | ||
52 | #include "ivtv-ioctl.h" | ||
53 | #include "ivtv-cards.h" | ||
54 | #include "ivtv-vbi.h" | ||
55 | #include "ivtv-routing.h" | ||
56 | #include "ivtv-controls.h" | ||
57 | #include "ivtv-gpio.h" | ||
58 | |||
59 | #include <media/tveeprom.h> | ||
60 | #include <media/saa7115.h> | ||
61 | #include <media/v4l2-chip-ident.h> | ||
62 | #include "tuner-xc2028.h" | ||
63 | |||
64 | /* If you have already X v4l cards, then set this to X. This way | ||
65 | the device numbers stay matched. Example: you have a WinTV card | ||
66 | without radio and a PVR-350 with. Normally this would give a | ||
67 | video1 device together with a radio0 device for the PVR. By | ||
68 | setting this to 1 you ensure that radio0 is now also radio1. */ | ||
69 | int ivtv_first_minor; | ||
70 | |||
71 | /* add your revision and whatnot here */ | ||
72 | static struct pci_device_id ivtv_pci_tbl[] __devinitdata = { | ||
73 | {PCI_VENDOR_ID_ICOMP, PCI_DEVICE_ID_IVTV15, | ||
74 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
75 | {PCI_VENDOR_ID_ICOMP, PCI_DEVICE_ID_IVTV16, | ||
76 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
77 | {0,} | ||
78 | }; | ||
79 | |||
80 | MODULE_DEVICE_TABLE(pci,ivtv_pci_tbl); | ||
81 | |||
82 | /* ivtv instance counter */ | ||
83 | static atomic_t ivtv_instance = ATOMIC_INIT(0); | ||
84 | |||
85 | /* Parameter declarations */ | ||
86 | static int cardtype[IVTV_MAX_CARDS]; | ||
87 | static int tuner[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, | ||
88 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
89 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
90 | -1, -1, -1, -1, -1, -1, -1, -1 }; | ||
91 | static int radio[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, | ||
92 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
93 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
94 | -1, -1, -1, -1, -1, -1, -1, -1 }; | ||
95 | static int i2c_clock_period[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, | ||
96 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
97 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
98 | -1, -1, -1, -1, -1, -1, -1, -1 }; | ||
99 | |||
100 | static unsigned int cardtype_c = 1; | ||
101 | static unsigned int tuner_c = 1; | ||
102 | static unsigned int radio_c = 1; | ||
103 | static unsigned int i2c_clock_period_c = 1; | ||
104 | static char pal[] = "---"; | ||
105 | static char secam[] = "--"; | ||
106 | static char ntsc[] = "-"; | ||
107 | |||
108 | /* Buffers */ | ||
109 | |||
110 | /* DMA Buffers, Default size in MB allocated */ | ||
111 | #define IVTV_DEFAULT_ENC_MPG_BUFFERS 4 | ||
112 | #define IVTV_DEFAULT_ENC_YUV_BUFFERS 2 | ||
113 | #define IVTV_DEFAULT_ENC_VBI_BUFFERS 1 | ||
114 | /* Exception: size in kB for this stream (MB is overkill) */ | ||
115 | #define IVTV_DEFAULT_ENC_PCM_BUFFERS 320 | ||
116 | #define IVTV_DEFAULT_DEC_MPG_BUFFERS 1 | ||
117 | #define IVTV_DEFAULT_DEC_YUV_BUFFERS 1 | ||
118 | /* Exception: size in kB for this stream (MB is way overkill) */ | ||
119 | #define IVTV_DEFAULT_DEC_VBI_BUFFERS 64 | ||
120 | |||
121 | static int enc_mpg_buffers = IVTV_DEFAULT_ENC_MPG_BUFFERS; | ||
122 | static int enc_yuv_buffers = IVTV_DEFAULT_ENC_YUV_BUFFERS; | ||
123 | static int enc_vbi_buffers = IVTV_DEFAULT_ENC_VBI_BUFFERS; | ||
124 | static int enc_pcm_buffers = IVTV_DEFAULT_ENC_PCM_BUFFERS; | ||
125 | static int dec_mpg_buffers = IVTV_DEFAULT_DEC_MPG_BUFFERS; | ||
126 | static int dec_yuv_buffers = IVTV_DEFAULT_DEC_YUV_BUFFERS; | ||
127 | static int dec_vbi_buffers = IVTV_DEFAULT_DEC_VBI_BUFFERS; | ||
128 | |||
129 | static int ivtv_yuv_mode; | ||
130 | static int ivtv_yuv_threshold = -1; | ||
131 | static int ivtv_pci_latency = 1; | ||
132 | |||
133 | int ivtv_debug; | ||
134 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
135 | int ivtv_fw_debug; | ||
136 | #endif | ||
137 | |||
138 | static int tunertype = -1; | ||
139 | static int newi2c = -1; | ||
140 | |||
141 | module_param_array(tuner, int, &tuner_c, 0644); | ||
142 | module_param_array(radio, bool, &radio_c, 0644); | ||
143 | module_param_array(cardtype, int, &cardtype_c, 0644); | ||
144 | module_param_string(pal, pal, sizeof(pal), 0644); | ||
145 | module_param_string(secam, secam, sizeof(secam), 0644); | ||
146 | module_param_string(ntsc, ntsc, sizeof(ntsc), 0644); | ||
147 | module_param_named(debug,ivtv_debug, int, 0644); | ||
148 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
149 | module_param_named(fw_debug, ivtv_fw_debug, int, 0644); | ||
150 | #endif | ||
151 | module_param(ivtv_pci_latency, int, 0644); | ||
152 | module_param(ivtv_yuv_mode, int, 0644); | ||
153 | module_param(ivtv_yuv_threshold, int, 0644); | ||
154 | module_param(ivtv_first_minor, int, 0644); | ||
155 | |||
156 | module_param(enc_mpg_buffers, int, 0644); | ||
157 | module_param(enc_yuv_buffers, int, 0644); | ||
158 | module_param(enc_vbi_buffers, int, 0644); | ||
159 | module_param(enc_pcm_buffers, int, 0644); | ||
160 | module_param(dec_mpg_buffers, int, 0644); | ||
161 | module_param(dec_yuv_buffers, int, 0644); | ||
162 | module_param(dec_vbi_buffers, int, 0644); | ||
163 | |||
164 | module_param(tunertype, int, 0644); | ||
165 | module_param(newi2c, int, 0644); | ||
166 | module_param_array(i2c_clock_period, int, &i2c_clock_period_c, 0644); | ||
167 | |||
168 | MODULE_PARM_DESC(tuner, "Tuner type selection,\n" | ||
169 | "\t\t\tsee tuner.h for values"); | ||
170 | MODULE_PARM_DESC(radio, | ||
171 | "Enable or disable the radio. Use only if autodetection\n" | ||
172 | "\t\t\tfails. 0 = disable, 1 = enable"); | ||
173 | MODULE_PARM_DESC(cardtype, | ||
174 | "Only use this option if your card is not detected properly.\n" | ||
175 | "\t\tSpecify card type:\n" | ||
176 | "\t\t\t 1 = WinTV PVR 250\n" | ||
177 | "\t\t\t 2 = WinTV PVR 350\n" | ||
178 | "\t\t\t 3 = WinTV PVR-150 or PVR-500\n" | ||
179 | "\t\t\t 4 = AVerMedia M179\n" | ||
180 | "\t\t\t 5 = YUAN MPG600/Kuroutoshikou iTVC16-STVLP\n" | ||
181 | "\t\t\t 6 = YUAN MPG160/Kuroutoshikou iTVC15-STVLP\n" | ||
182 | "\t\t\t 7 = YUAN PG600/DIAMONDMM PVR-550 (CX Falcon 2)\n" | ||
183 | "\t\t\t 8 = Adaptec AVC-2410\n" | ||
184 | "\t\t\t 9 = Adaptec AVC-2010\n" | ||
185 | "\t\t\t10 = NAGASE TRANSGEAR 5000TV\n" | ||
186 | "\t\t\t11 = AOpen VA2000MAX-STN6\n" | ||
187 | "\t\t\t12 = YUAN MPG600GR/Kuroutoshikou CX23416GYC-STVLP\n" | ||
188 | "\t\t\t13 = I/O Data GV-MVP/RX\n" | ||
189 | "\t\t\t14 = I/O Data GV-MVP/RX2E\n" | ||
190 | "\t\t\t15 = GOTVIEW PCI DVD\n" | ||
191 | "\t\t\t16 = GOTVIEW PCI DVD2 Deluxe\n" | ||
192 | "\t\t\t17 = Yuan MPC622\n" | ||
193 | "\t\t\t18 = Digital Cowboy DCT-MTVP1\n" | ||
194 | "\t\t\t19 = Yuan PG600V2/GotView PCI DVD Lite\n" | ||
195 | "\t\t\t20 = Club3D ZAP-TV1x01\n" | ||
196 | "\t\t\t21 = AverTV MCE 116 Plus\n" | ||
197 | "\t\t\t22 = ASUS Falcon2\n" | ||
198 | "\t\t\t23 = AverMedia PVR-150 Plus\n" | ||
199 | "\t\t\t24 = AverMedia EZMaker PCI Deluxe\n" | ||
200 | "\t\t\t25 = AverMedia M104 (not yet working)\n" | ||
201 | "\t\t\t26 = Buffalo PC-MV5L/PCI\n" | ||
202 | "\t\t\t27 = AVerMedia UltraTV 1500 MCE\n" | ||
203 | "\t\t\t28 = Sony VAIO Giga Pocket (ENX Kikyou)\n" | ||
204 | "\t\t\t 0 = Autodetect (default)\n" | ||
205 | "\t\t\t-1 = Ignore this card\n\t\t"); | ||
206 | MODULE_PARM_DESC(pal, "Set PAL standard: BGH, DK, I, M, N, Nc, 60"); | ||
207 | MODULE_PARM_DESC(secam, "Set SECAM standard: BGH, DK, L, LC"); | ||
208 | MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J (Japan), K (South Korea)"); | ||
209 | MODULE_PARM_DESC(tunertype, | ||
210 | "Specify tuner type:\n" | ||
211 | "\t\t\t 0 = tuner for PAL-B/G/H/D/K/I, SECAM-B/G/H/D/K/L/Lc\n" | ||
212 | "\t\t\t 1 = tuner for NTSC-M/J/K, PAL-M/N/Nc\n" | ||
213 | "\t\t\t-1 = Autodetect (default)\n"); | ||
214 | MODULE_PARM_DESC(debug, | ||
215 | "Debug level (bitmask). Default: 0\n" | ||
216 | "\t\t\t 1/0x0001: warning\n" | ||
217 | "\t\t\t 2/0x0002: info\n" | ||
218 | "\t\t\t 4/0x0004: mailbox\n" | ||
219 | "\t\t\t 8/0x0008: ioctl\n" | ||
220 | "\t\t\t 16/0x0010: file\n" | ||
221 | "\t\t\t 32/0x0020: dma\n" | ||
222 | "\t\t\t 64/0x0040: irq\n" | ||
223 | "\t\t\t 128/0x0080: decoder\n" | ||
224 | "\t\t\t 256/0x0100: yuv\n" | ||
225 | "\t\t\t 512/0x0200: i2c\n" | ||
226 | "\t\t\t1024/0x0400: high volume\n"); | ||
227 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
228 | MODULE_PARM_DESC(fw_debug, | ||
229 | "Enable code for debugging firmware problems. Default: 0\n"); | ||
230 | #endif | ||
231 | MODULE_PARM_DESC(ivtv_pci_latency, | ||
232 | "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n" | ||
233 | "\t\t\tDefault: Yes"); | ||
234 | MODULE_PARM_DESC(ivtv_yuv_mode, | ||
235 | "Specify the yuv playback mode:\n" | ||
236 | "\t\t\t0 = interlaced\n\t\t\t1 = progressive\n\t\t\t2 = auto\n" | ||
237 | "\t\t\tDefault: 0 (interlaced)"); | ||
238 | MODULE_PARM_DESC(ivtv_yuv_threshold, | ||
239 | "If ivtv_yuv_mode is 2 (auto) then playback content as\n\t\tprogressive if src height <= ivtv_yuvthreshold\n" | ||
240 | "\t\t\tDefault: 480"); | ||
241 | MODULE_PARM_DESC(enc_mpg_buffers, | ||
242 | "Encoder MPG Buffers (in MB)\n" | ||
243 | "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_MPG_BUFFERS)); | ||
244 | MODULE_PARM_DESC(enc_yuv_buffers, | ||
245 | "Encoder YUV Buffers (in MB)\n" | ||
246 | "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_YUV_BUFFERS)); | ||
247 | MODULE_PARM_DESC(enc_vbi_buffers, | ||
248 | "Encoder VBI Buffers (in MB)\n" | ||
249 | "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_VBI_BUFFERS)); | ||
250 | MODULE_PARM_DESC(enc_pcm_buffers, | ||
251 | "Encoder PCM buffers (in kB)\n" | ||
252 | "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_PCM_BUFFERS)); | ||
253 | MODULE_PARM_DESC(dec_mpg_buffers, | ||
254 | "Decoder MPG buffers (in MB)\n" | ||
255 | "\t\t\tDefault: " __stringify(IVTV_DEFAULT_DEC_MPG_BUFFERS)); | ||
256 | MODULE_PARM_DESC(dec_yuv_buffers, | ||
257 | "Decoder YUV buffers (in MB)\n" | ||
258 | "\t\t\tDefault: " __stringify(IVTV_DEFAULT_DEC_YUV_BUFFERS)); | ||
259 | MODULE_PARM_DESC(dec_vbi_buffers, | ||
260 | "Decoder VBI buffers (in kB)\n" | ||
261 | "\t\t\tDefault: " __stringify(IVTV_DEFAULT_DEC_VBI_BUFFERS)); | ||
262 | MODULE_PARM_DESC(newi2c, | ||
263 | "Use new I2C implementation\n" | ||
264 | "\t\t\t-1 is autodetect, 0 is off, 1 is on\n" | ||
265 | "\t\t\tDefault is autodetect"); | ||
266 | MODULE_PARM_DESC(i2c_clock_period, | ||
267 | "Period of SCL for the I2C bus controlled by the CX23415/6\n" | ||
268 | "\t\t\tMin: 10 usec (100 kHz), Max: 4500 usec (222 Hz)\n" | ||
269 | "\t\t\tDefault: " __stringify(IVTV_DEFAULT_I2C_CLOCK_PERIOD)); | ||
270 | |||
271 | MODULE_PARM_DESC(ivtv_first_minor, "Set device node number assigned to first card"); | ||
272 | |||
273 | MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil"); | ||
274 | MODULE_DESCRIPTION("CX23415/CX23416 driver"); | ||
275 | MODULE_SUPPORTED_DEVICE | ||
276 | ("CX23415/CX23416 MPEG2 encoder (WinTV PVR-150/250/350/500,\n" | ||
277 | "\t\t\tYuan MPG series and similar)"); | ||
278 | MODULE_LICENSE("GPL"); | ||
279 | |||
280 | MODULE_VERSION(IVTV_VERSION); | ||
281 | |||
282 | void ivtv_clear_irq_mask(struct ivtv *itv, u32 mask) | ||
283 | { | ||
284 | itv->irqmask &= ~mask; | ||
285 | write_reg_sync(itv->irqmask, IVTV_REG_IRQMASK); | ||
286 | } | ||
287 | |||
288 | void ivtv_set_irq_mask(struct ivtv *itv, u32 mask) | ||
289 | { | ||
290 | itv->irqmask |= mask; | ||
291 | write_reg_sync(itv->irqmask, IVTV_REG_IRQMASK); | ||
292 | } | ||
293 | |||
294 | int ivtv_set_output_mode(struct ivtv *itv, int mode) | ||
295 | { | ||
296 | int old_mode; | ||
297 | |||
298 | spin_lock(&itv->lock); | ||
299 | old_mode = itv->output_mode; | ||
300 | if (old_mode == 0) | ||
301 | itv->output_mode = old_mode = mode; | ||
302 | spin_unlock(&itv->lock); | ||
303 | return old_mode; | ||
304 | } | ||
305 | |||
306 | struct ivtv_stream *ivtv_get_output_stream(struct ivtv *itv) | ||
307 | { | ||
308 | switch (itv->output_mode) { | ||
309 | case OUT_MPG: | ||
310 | return &itv->streams[IVTV_DEC_STREAM_TYPE_MPG]; | ||
311 | case OUT_YUV: | ||
312 | return &itv->streams[IVTV_DEC_STREAM_TYPE_YUV]; | ||
313 | default: | ||
314 | return NULL; | ||
315 | } | ||
316 | } | ||
317 | |||
318 | int ivtv_waitq(wait_queue_head_t *waitq) | ||
319 | { | ||
320 | DEFINE_WAIT(wait); | ||
321 | |||
322 | prepare_to_wait(waitq, &wait, TASK_INTERRUPTIBLE); | ||
323 | schedule(); | ||
324 | finish_wait(waitq, &wait); | ||
325 | return signal_pending(current) ? -EINTR : 0; | ||
326 | } | ||
327 | |||
328 | /* Generic utility functions */ | ||
329 | int ivtv_msleep_timeout(unsigned int msecs, int intr) | ||
330 | { | ||
331 | int timeout = msecs_to_jiffies(msecs); | ||
332 | |||
333 | do { | ||
334 | set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); | ||
335 | timeout = schedule_timeout(timeout); | ||
336 | if (intr) { | ||
337 | int ret = signal_pending(current); | ||
338 | |||
339 | if (ret) | ||
340 | return ret; | ||
341 | } | ||
342 | } while (timeout); | ||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | /* Release ioremapped memory */ | ||
347 | static void ivtv_iounmap(struct ivtv *itv) | ||
348 | { | ||
349 | if (itv == NULL) | ||
350 | return; | ||
351 | |||
352 | /* Release registers memory */ | ||
353 | if (itv->reg_mem != NULL) { | ||
354 | IVTV_DEBUG_INFO("releasing reg_mem\n"); | ||
355 | iounmap(itv->reg_mem); | ||
356 | itv->reg_mem = NULL; | ||
357 | } | ||
358 | /* Release io memory */ | ||
359 | if (itv->has_cx23415 && itv->dec_mem != NULL) { | ||
360 | IVTV_DEBUG_INFO("releasing dec_mem\n"); | ||
361 | iounmap(itv->dec_mem); | ||
362 | } | ||
363 | itv->dec_mem = NULL; | ||
364 | |||
365 | /* Release io memory */ | ||
366 | if (itv->enc_mem != NULL) { | ||
367 | IVTV_DEBUG_INFO("releasing enc_mem\n"); | ||
368 | iounmap(itv->enc_mem); | ||
369 | itv->enc_mem = NULL; | ||
370 | } | ||
371 | } | ||
372 | |||
373 | /* Hauppauge card? get values from tveeprom */ | ||
374 | void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv) | ||
375 | { | ||
376 | u8 eedata[256]; | ||
377 | |||
378 | itv->i2c_client.addr = 0xA0 >> 1; | ||
379 | tveeprom_read(&itv->i2c_client, eedata, sizeof(eedata)); | ||
380 | tveeprom_hauppauge_analog(&itv->i2c_client, tv, eedata); | ||
381 | } | ||
382 | |||
383 | static void ivtv_process_eeprom(struct ivtv *itv) | ||
384 | { | ||
385 | struct tveeprom tv; | ||
386 | int pci_slot = PCI_SLOT(itv->pdev->devfn); | ||
387 | |||
388 | ivtv_read_eeprom(itv, &tv); | ||
389 | |||
390 | /* Many thanks to Steven Toth from Hauppauge for providing the | ||
391 | model numbers */ | ||
392 | switch (tv.model) { | ||
393 | /* In a few cases the PCI subsystem IDs do not correctly | ||
394 | identify the card. A better method is to check the | ||
395 | model number from the eeprom instead. */ | ||
396 | case 30012 ... 30039: /* Low profile PVR250 */ | ||
397 | case 32000 ... 32999: | ||
398 | case 48000 ... 48099: /* 48??? range are PVR250s with a cx23415 */ | ||
399 | case 48400 ... 48599: | ||
400 | itv->card = ivtv_get_card(IVTV_CARD_PVR_250); | ||
401 | break; | ||
402 | case 48100 ... 48399: | ||
403 | case 48600 ... 48999: | ||
404 | itv->card = ivtv_get_card(IVTV_CARD_PVR_350); | ||
405 | break; | ||
406 | case 23000 ... 23999: /* PVR500 */ | ||
407 | case 25000 ... 25999: /* Low profile PVR150 */ | ||
408 | case 26000 ... 26999: /* Regular PVR150 */ | ||
409 | itv->card = ivtv_get_card(IVTV_CARD_PVR_150); | ||
410 | break; | ||
411 | case 0: | ||
412 | IVTV_ERR("Invalid EEPROM\n"); | ||
413 | return; | ||
414 | default: | ||
415 | IVTV_ERR("Unknown model %d, defaulting to PVR-150\n", tv.model); | ||
416 | itv->card = ivtv_get_card(IVTV_CARD_PVR_150); | ||
417 | break; | ||
418 | } | ||
419 | |||
420 | switch (tv.model) { | ||
421 | /* Old style PVR350 (with an saa7114) uses this input for | ||
422 | the tuner. */ | ||
423 | case 48254: | ||
424 | itv->card = ivtv_get_card(IVTV_CARD_PVR_350_V1); | ||
425 | break; | ||
426 | default: | ||
427 | break; | ||
428 | } | ||
429 | |||
430 | itv->v4l2_cap = itv->card->v4l2_capabilities; | ||
431 | itv->card_name = itv->card->name; | ||
432 | itv->card_i2c = itv->card->i2c; | ||
433 | |||
434 | /* If this is a PVR500 then it should be possible to detect whether it is the | ||
435 | first or second unit by looking at the subsystem device ID: is bit 4 is | ||
436 | set, then it is the second unit (according to info from Hauppauge). | ||
437 | |||
438 | However, while this works for most cards, I have seen a few PVR500 cards | ||
439 | where both units have the same subsystem ID. | ||
440 | |||
441 | So instead I look at the reported 'PCI slot' (which is the slot on the PVR500 | ||
442 | PCI bridge) and if it is 8, then it is assumed to be the first unit, otherwise | ||
443 | it is the second unit. It is possible that it is a different slot when ivtv is | ||
444 | used in Xen, in that case I ignore this card here. The worst that can happen | ||
445 | is that the card presents itself with a non-working radio device. | ||
446 | |||
447 | This detection is needed since the eeprom reports incorrectly that a radio is | ||
448 | present on the second unit. */ | ||
449 | if (tv.model / 1000 == 23) { | ||
450 | static const struct ivtv_card_tuner_i2c ivtv_i2c_radio = { | ||
451 | .radio = { 0x60, I2C_CLIENT_END }, | ||
452 | .demod = { 0x43, I2C_CLIENT_END }, | ||
453 | .tv = { 0x61, I2C_CLIENT_END }, | ||
454 | }; | ||
455 | |||
456 | itv->card_name = "WinTV PVR 500"; | ||
457 | itv->card_i2c = &ivtv_i2c_radio; | ||
458 | if (pci_slot == 8 || pci_slot == 9) { | ||
459 | int is_first = (pci_slot & 1) == 0; | ||
460 | |||
461 | itv->card_name = is_first ? "WinTV PVR 500 (unit #1)" : | ||
462 | "WinTV PVR 500 (unit #2)"; | ||
463 | if (!is_first) { | ||
464 | IVTV_INFO("Correcting tveeprom data: no radio present on second unit\n"); | ||
465 | tv.has_radio = 0; | ||
466 | } | ||
467 | } | ||
468 | } | ||
469 | IVTV_INFO("Autodetected %s\n", itv->card_name); | ||
470 | |||
471 | switch (tv.tuner_hauppauge_model) { | ||
472 | case 85: | ||
473 | case 99: | ||
474 | case 112: | ||
475 | itv->pvr150_workaround = 1; | ||
476 | break; | ||
477 | default: | ||
478 | break; | ||
479 | } | ||
480 | if (tv.tuner_type == TUNER_ABSENT) | ||
481 | IVTV_ERR("tveeprom cannot autodetect tuner!\n"); | ||
482 | |||
483 | if (itv->options.tuner == -1) | ||
484 | itv->options.tuner = tv.tuner_type; | ||
485 | if (itv->options.radio == -1) | ||
486 | itv->options.radio = (tv.has_radio != 0); | ||
487 | /* only enable newi2c if an IR blaster is present */ | ||
488 | if (itv->options.newi2c == -1 && tv.has_ir) { | ||
489 | itv->options.newi2c = (tv.has_ir & 4) ? 1 : 0; | ||
490 | if (itv->options.newi2c) { | ||
491 | IVTV_INFO("Reopen i2c bus for IR-blaster support\n"); | ||
492 | exit_ivtv_i2c(itv); | ||
493 | init_ivtv_i2c(itv); | ||
494 | } | ||
495 | } | ||
496 | |||
497 | if (itv->std != 0) | ||
498 | /* user specified tuner standard */ | ||
499 | return; | ||
500 | |||
501 | /* autodetect tuner standard */ | ||
502 | if (tv.tuner_formats & V4L2_STD_PAL) { | ||
503 | IVTV_DEBUG_INFO("PAL tuner detected\n"); | ||
504 | itv->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H; | ||
505 | } else if (tv.tuner_formats & V4L2_STD_NTSC) { | ||
506 | IVTV_DEBUG_INFO("NTSC tuner detected\n"); | ||
507 | itv->std |= V4L2_STD_NTSC_M; | ||
508 | } else if (tv.tuner_formats & V4L2_STD_SECAM) { | ||
509 | IVTV_DEBUG_INFO("SECAM tuner detected\n"); | ||
510 | itv->std |= V4L2_STD_SECAM_L; | ||
511 | } else { | ||
512 | IVTV_INFO("No tuner detected, default to NTSC-M\n"); | ||
513 | itv->std |= V4L2_STD_NTSC_M; | ||
514 | } | ||
515 | } | ||
516 | |||
517 | static v4l2_std_id ivtv_parse_std(struct ivtv *itv) | ||
518 | { | ||
519 | switch (pal[0]) { | ||
520 | case '6': | ||
521 | tunertype = 0; | ||
522 | return V4L2_STD_PAL_60; | ||
523 | case 'b': | ||
524 | case 'B': | ||
525 | case 'g': | ||
526 | case 'G': | ||
527 | case 'h': | ||
528 | case 'H': | ||
529 | tunertype = 0; | ||
530 | return V4L2_STD_PAL_BG | V4L2_STD_PAL_H; | ||
531 | case 'n': | ||
532 | case 'N': | ||
533 | tunertype = 1; | ||
534 | if (pal[1] == 'c' || pal[1] == 'C') | ||
535 | return V4L2_STD_PAL_Nc; | ||
536 | return V4L2_STD_PAL_N; | ||
537 | case 'i': | ||
538 | case 'I': | ||
539 | tunertype = 0; | ||
540 | return V4L2_STD_PAL_I; | ||
541 | case 'd': | ||
542 | case 'D': | ||
543 | case 'k': | ||
544 | case 'K': | ||
545 | tunertype = 0; | ||
546 | return V4L2_STD_PAL_DK; | ||
547 | case 'M': | ||
548 | case 'm': | ||
549 | tunertype = 1; | ||
550 | return V4L2_STD_PAL_M; | ||
551 | case '-': | ||
552 | break; | ||
553 | default: | ||
554 | IVTV_WARN("pal= argument not recognised\n"); | ||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | switch (secam[0]) { | ||
559 | case 'b': | ||
560 | case 'B': | ||
561 | case 'g': | ||
562 | case 'G': | ||
563 | case 'h': | ||
564 | case 'H': | ||
565 | tunertype = 0; | ||
566 | return V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H; | ||
567 | case 'd': | ||
568 | case 'D': | ||
569 | case 'k': | ||
570 | case 'K': | ||
571 | tunertype = 0; | ||
572 | return V4L2_STD_SECAM_DK; | ||
573 | case 'l': | ||
574 | case 'L': | ||
575 | tunertype = 0; | ||
576 | if (secam[1] == 'C' || secam[1] == 'c') | ||
577 | return V4L2_STD_SECAM_LC; | ||
578 | return V4L2_STD_SECAM_L; | ||
579 | case '-': | ||
580 | break; | ||
581 | default: | ||
582 | IVTV_WARN("secam= argument not recognised\n"); | ||
583 | return 0; | ||
584 | } | ||
585 | |||
586 | switch (ntsc[0]) { | ||
587 | case 'm': | ||
588 | case 'M': | ||
589 | tunertype = 1; | ||
590 | return V4L2_STD_NTSC_M; | ||
591 | case 'j': | ||
592 | case 'J': | ||
593 | tunertype = 1; | ||
594 | return V4L2_STD_NTSC_M_JP; | ||
595 | case 'k': | ||
596 | case 'K': | ||
597 | tunertype = 1; | ||
598 | return V4L2_STD_NTSC_M_KR; | ||
599 | case '-': | ||
600 | break; | ||
601 | default: | ||
602 | IVTV_WARN("ntsc= argument not recognised\n"); | ||
603 | return 0; | ||
604 | } | ||
605 | |||
606 | /* no match found */ | ||
607 | return 0; | ||
608 | } | ||
609 | |||
610 | static void ivtv_process_options(struct ivtv *itv) | ||
611 | { | ||
612 | const char *chipname; | ||
613 | int i, j; | ||
614 | |||
615 | itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers * 1024; | ||
616 | itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers * 1024; | ||
617 | itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers * 1024; | ||
618 | itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers; | ||
619 | itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_MPG] = dec_mpg_buffers * 1024; | ||
620 | itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_YUV] = dec_yuv_buffers * 1024; | ||
621 | itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_VBI] = dec_vbi_buffers; | ||
622 | itv->options.cardtype = cardtype[itv->instance]; | ||
623 | itv->options.tuner = tuner[itv->instance]; | ||
624 | itv->options.radio = radio[itv->instance]; | ||
625 | |||
626 | itv->options.i2c_clock_period = i2c_clock_period[itv->instance]; | ||
627 | if (itv->options.i2c_clock_period == -1) | ||
628 | itv->options.i2c_clock_period = IVTV_DEFAULT_I2C_CLOCK_PERIOD; | ||
629 | else if (itv->options.i2c_clock_period < 10) | ||
630 | itv->options.i2c_clock_period = 10; | ||
631 | else if (itv->options.i2c_clock_period > 4500) | ||
632 | itv->options.i2c_clock_period = 4500; | ||
633 | |||
634 | itv->options.newi2c = newi2c; | ||
635 | if (tunertype < -1 || tunertype > 1) { | ||
636 | IVTV_WARN("Invalid tunertype argument, will autodetect instead\n"); | ||
637 | tunertype = -1; | ||
638 | } | ||
639 | itv->std = ivtv_parse_std(itv); | ||
640 | if (itv->std == 0 && tunertype >= 0) | ||
641 | itv->std = tunertype ? V4L2_STD_MN : (V4L2_STD_ALL & ~V4L2_STD_MN); | ||
642 | itv->has_cx23415 = (itv->pdev->device == PCI_DEVICE_ID_IVTV15); | ||
643 | chipname = itv->has_cx23415 ? "cx23415" : "cx23416"; | ||
644 | if (itv->options.cardtype == -1) { | ||
645 | IVTV_INFO("Ignore card (detected %s based chip)\n", chipname); | ||
646 | return; | ||
647 | } | ||
648 | if ((itv->card = ivtv_get_card(itv->options.cardtype - 1))) { | ||
649 | IVTV_INFO("User specified %s card (detected %s based chip)\n", | ||
650 | itv->card->name, chipname); | ||
651 | } else if (itv->options.cardtype != 0) { | ||
652 | IVTV_ERR("Unknown user specified type, trying to autodetect card\n"); | ||
653 | } | ||
654 | if (itv->card == NULL) { | ||
655 | if (itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE || | ||
656 | itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT1 || | ||
657 | itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT2) { | ||
658 | itv->card = ivtv_get_card(itv->has_cx23415 ? IVTV_CARD_PVR_350 : IVTV_CARD_PVR_150); | ||
659 | IVTV_INFO("Autodetected Hauppauge card (%s based)\n", | ||
660 | chipname); | ||
661 | } | ||
662 | } | ||
663 | if (itv->card == NULL) { | ||
664 | for (i = 0; (itv->card = ivtv_get_card(i)); i++) { | ||
665 | if (itv->card->pci_list == NULL) | ||
666 | continue; | ||
667 | for (j = 0; itv->card->pci_list[j].device; j++) { | ||
668 | if (itv->pdev->device != | ||
669 | itv->card->pci_list[j].device) | ||
670 | continue; | ||
671 | if (itv->pdev->subsystem_vendor != | ||
672 | itv->card->pci_list[j].subsystem_vendor) | ||
673 | continue; | ||
674 | if (itv->pdev->subsystem_device != | ||
675 | itv->card->pci_list[j].subsystem_device) | ||
676 | continue; | ||
677 | IVTV_INFO("Autodetected %s card (%s based)\n", | ||
678 | itv->card->name, chipname); | ||
679 | goto done; | ||
680 | } | ||
681 | } | ||
682 | } | ||
683 | done: | ||
684 | |||
685 | if (itv->card == NULL) { | ||
686 | itv->card = ivtv_get_card(IVTV_CARD_PVR_150); | ||
687 | IVTV_ERR("Unknown card: vendor/device: [%04x:%04x]\n", | ||
688 | itv->pdev->vendor, itv->pdev->device); | ||
689 | IVTV_ERR(" subsystem vendor/device: [%04x:%04x]\n", | ||
690 | itv->pdev->subsystem_vendor, itv->pdev->subsystem_device); | ||
691 | IVTV_ERR(" %s based\n", chipname); | ||
692 | IVTV_ERR("Defaulting to %s card\n", itv->card->name); | ||
693 | IVTV_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n"); | ||
694 | IVTV_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n"); | ||
695 | IVTV_ERR("Prefix your subject line with [UNKNOWN IVTV CARD].\n"); | ||
696 | } | ||
697 | itv->v4l2_cap = itv->card->v4l2_capabilities; | ||
698 | itv->card_name = itv->card->name; | ||
699 | itv->card_i2c = itv->card->i2c; | ||
700 | } | ||
701 | |||
702 | /* Precondition: the ivtv structure has been memset to 0. Only | ||
703 | the dev and num fields have been filled in. | ||
704 | No assumptions on the card type may be made here (see ivtv_init_struct2 | ||
705 | for that). | ||
706 | */ | ||
707 | static int __devinit ivtv_init_struct1(struct ivtv *itv) | ||
708 | { | ||
709 | struct sched_param param = { .sched_priority = 99 }; | ||
710 | |||
711 | itv->base_addr = pci_resource_start(itv->pdev, 0); | ||
712 | itv->enc_mbox.max_mbox = 2; /* the encoder has 3 mailboxes (0-2) */ | ||
713 | itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */ | ||
714 | |||
715 | mutex_init(&itv->serialize_lock); | ||
716 | mutex_init(&itv->i2c_bus_lock); | ||
717 | mutex_init(&itv->udma.lock); | ||
718 | |||
719 | spin_lock_init(&itv->lock); | ||
720 | spin_lock_init(&itv->dma_reg_lock); | ||
721 | |||
722 | init_kthread_worker(&itv->irq_worker); | ||
723 | itv->irq_worker_task = kthread_run(kthread_worker_fn, &itv->irq_worker, | ||
724 | itv->v4l2_dev.name); | ||
725 | if (IS_ERR(itv->irq_worker_task)) { | ||
726 | IVTV_ERR("Could not create ivtv task\n"); | ||
727 | return -1; | ||
728 | } | ||
729 | /* must use the FIFO scheduler as it is realtime sensitive */ | ||
730 | sched_setscheduler(itv->irq_worker_task, SCHED_FIFO, ¶m); | ||
731 | |||
732 | init_kthread_work(&itv->irq_work, ivtv_irq_work_handler); | ||
733 | |||
734 | /* start counting open_id at 1 */ | ||
735 | itv->open_id = 1; | ||
736 | |||
737 | /* Initial settings */ | ||
738 | itv->cxhdl.port = CX2341X_PORT_MEMORY; | ||
739 | itv->cxhdl.capabilities = CX2341X_CAP_HAS_SLICED_VBI; | ||
740 | init_waitqueue_head(&itv->eos_waitq); | ||
741 | init_waitqueue_head(&itv->event_waitq); | ||
742 | init_waitqueue_head(&itv->vsync_waitq); | ||
743 | init_waitqueue_head(&itv->dma_waitq); | ||
744 | init_timer(&itv->dma_timer); | ||
745 | itv->dma_timer.function = ivtv_unfinished_dma; | ||
746 | itv->dma_timer.data = (unsigned long)itv; | ||
747 | |||
748 | itv->cur_dma_stream = -1; | ||
749 | itv->cur_pio_stream = -1; | ||
750 | itv->audio_stereo_mode = AUDIO_STEREO; | ||
751 | itv->audio_bilingual_mode = AUDIO_MONO_LEFT; | ||
752 | |||
753 | /* Ctrls */ | ||
754 | itv->speed = 1000; | ||
755 | |||
756 | /* VBI */ | ||
757 | itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
758 | itv->vbi.sliced_in = &itv->vbi.in.fmt.sliced; | ||
759 | |||
760 | /* Init the sg table for osd/yuv output */ | ||
761 | sg_init_table(itv->udma.SGlist, IVTV_DMA_SG_OSD_ENT); | ||
762 | |||
763 | /* OSD */ | ||
764 | itv->osd_global_alpha_state = 1; | ||
765 | itv->osd_global_alpha = 255; | ||
766 | |||
767 | /* YUV */ | ||
768 | atomic_set(&itv->yuv_info.next_dma_frame, -1); | ||
769 | itv->yuv_info.lace_mode = ivtv_yuv_mode; | ||
770 | itv->yuv_info.lace_threshold = ivtv_yuv_threshold; | ||
771 | itv->yuv_info.max_frames_buffered = 3; | ||
772 | itv->yuv_info.track_osd = 1; | ||
773 | return 0; | ||
774 | } | ||
775 | |||
776 | /* Second initialization part. Here the card type has been | ||
777 | autodetected. */ | ||
778 | static void __devinit ivtv_init_struct2(struct ivtv *itv) | ||
779 | { | ||
780 | int i; | ||
781 | |||
782 | for (i = 0; i < IVTV_CARD_MAX_VIDEO_INPUTS; i++) | ||
783 | if (itv->card->video_inputs[i].video_type == 0) | ||
784 | break; | ||
785 | itv->nof_inputs = i; | ||
786 | for (i = 0; i < IVTV_CARD_MAX_AUDIO_INPUTS; i++) | ||
787 | if (itv->card->audio_inputs[i].audio_type == 0) | ||
788 | break; | ||
789 | itv->nof_audio_inputs = i; | ||
790 | |||
791 | if (itv->card->hw_all & IVTV_HW_CX25840) { | ||
792 | itv->vbi.sliced_size = 288; /* multiple of 16, real size = 284 */ | ||
793 | } else { | ||
794 | itv->vbi.sliced_size = 64; /* multiple of 16, real size = 52 */ | ||
795 | } | ||
796 | |||
797 | /* Find tuner input */ | ||
798 | for (i = 0; i < itv->nof_inputs; i++) { | ||
799 | if (itv->card->video_inputs[i].video_type == | ||
800 | IVTV_CARD_INPUT_VID_TUNER) | ||
801 | break; | ||
802 | } | ||
803 | if (i == itv->nof_inputs) | ||
804 | i = 0; | ||
805 | itv->active_input = i; | ||
806 | itv->audio_input = itv->card->video_inputs[i].audio_index; | ||
807 | } | ||
808 | |||
809 | static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev, | ||
810 | const struct pci_device_id *pci_id) | ||
811 | { | ||
812 | u16 cmd; | ||
813 | unsigned char pci_latency; | ||
814 | |||
815 | IVTV_DEBUG_INFO("Enabling pci device\n"); | ||
816 | |||
817 | if (pci_enable_device(pdev)) { | ||
818 | IVTV_ERR("Can't enable device!\n"); | ||
819 | return -EIO; | ||
820 | } | ||
821 | if (pci_set_dma_mask(pdev, 0xffffffff)) { | ||
822 | IVTV_ERR("No suitable DMA available.\n"); | ||
823 | return -EIO; | ||
824 | } | ||
825 | if (!request_mem_region(itv->base_addr, IVTV_ENCODER_SIZE, "ivtv encoder")) { | ||
826 | IVTV_ERR("Cannot request encoder memory region.\n"); | ||
827 | return -EIO; | ||
828 | } | ||
829 | |||
830 | if (!request_mem_region(itv->base_addr + IVTV_REG_OFFSET, | ||
831 | IVTV_REG_SIZE, "ivtv registers")) { | ||
832 | IVTV_ERR("Cannot request register memory region.\n"); | ||
833 | release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE); | ||
834 | return -EIO; | ||
835 | } | ||
836 | |||
837 | if (itv->has_cx23415 && | ||
838 | !request_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, | ||
839 | IVTV_DECODER_SIZE, "ivtv decoder")) { | ||
840 | IVTV_ERR("Cannot request decoder memory region.\n"); | ||
841 | release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE); | ||
842 | release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); | ||
843 | return -EIO; | ||
844 | } | ||
845 | |||
846 | /* Check for bus mastering */ | ||
847 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); | ||
848 | if (!(cmd & PCI_COMMAND_MASTER)) { | ||
849 | IVTV_DEBUG_INFO("Attempting to enable Bus Mastering\n"); | ||
850 | pci_set_master(pdev); | ||
851 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); | ||
852 | if (!(cmd & PCI_COMMAND_MASTER)) { | ||
853 | IVTV_ERR("Bus Mastering is not enabled\n"); | ||
854 | return -ENXIO; | ||
855 | } | ||
856 | } | ||
857 | IVTV_DEBUG_INFO("Bus Mastering Enabled.\n"); | ||
858 | |||
859 | pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency); | ||
860 | |||
861 | if (pci_latency < 64 && ivtv_pci_latency) { | ||
862 | IVTV_INFO("Unreasonably low latency timer, " | ||
863 | "setting to 64 (was %d)\n", pci_latency); | ||
864 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); | ||
865 | pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency); | ||
866 | } | ||
867 | /* This config space value relates to DMA latencies. The | ||
868 | default value 0x8080 is too low however and will lead | ||
869 | to DMA errors. 0xffff is the max value which solves | ||
870 | these problems. */ | ||
871 | pci_write_config_dword(pdev, 0x40, 0xffff); | ||
872 | |||
873 | IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, " | ||
874 | "irq: %d, latency: %d, memory: 0x%lx\n", | ||
875 | pdev->device, pdev->revision, pdev->bus->number, | ||
876 | PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), | ||
877 | pdev->irq, pci_latency, (unsigned long)itv->base_addr); | ||
878 | |||
879 | return 0; | ||
880 | } | ||
881 | |||
882 | static void ivtv_load_and_init_modules(struct ivtv *itv) | ||
883 | { | ||
884 | u32 hw = itv->card->hw_all; | ||
885 | unsigned i; | ||
886 | |||
887 | /* check which i2c devices are actually found */ | ||
888 | for (i = 0; i < 32; i++) { | ||
889 | u32 device = 1 << i; | ||
890 | |||
891 | if (!(device & hw)) | ||
892 | continue; | ||
893 | if (device == IVTV_HW_GPIO || device == IVTV_HW_TVEEPROM) { | ||
894 | /* GPIO and TVEEPROM do not use i2c probing */ | ||
895 | itv->hw_flags |= device; | ||
896 | continue; | ||
897 | } | ||
898 | if (ivtv_i2c_register(itv, i) == 0) | ||
899 | itv->hw_flags |= device; | ||
900 | } | ||
901 | |||
902 | /* probe for legacy IR controllers that aren't in card definitions */ | ||
903 | if ((itv->hw_flags & IVTV_HW_IR_ANY) == 0) | ||
904 | ivtv_i2c_new_ir_legacy(itv); | ||
905 | |||
906 | if (itv->card->hw_all & IVTV_HW_CX25840) | ||
907 | itv->sd_video = ivtv_find_hw(itv, IVTV_HW_CX25840); | ||
908 | else if (itv->card->hw_all & IVTV_HW_SAA717X) | ||
909 | itv->sd_video = ivtv_find_hw(itv, IVTV_HW_SAA717X); | ||
910 | else if (itv->card->hw_all & IVTV_HW_SAA7114) | ||
911 | itv->sd_video = ivtv_find_hw(itv, IVTV_HW_SAA7114); | ||
912 | else | ||
913 | itv->sd_video = ivtv_find_hw(itv, IVTV_HW_SAA7115); | ||
914 | itv->sd_audio = ivtv_find_hw(itv, itv->card->hw_audio_ctrl); | ||
915 | itv->sd_muxer = ivtv_find_hw(itv, itv->card->hw_muxer); | ||
916 | |||
917 | hw = itv->hw_flags; | ||
918 | |||
919 | if (itv->card->type == IVTV_CARD_CX23416GYC) { | ||
920 | /* Several variations of this card exist, detect which card | ||
921 | type should be used. */ | ||
922 | if ((hw & (IVTV_HW_UPD64031A | IVTV_HW_UPD6408X)) == 0) | ||
923 | itv->card = ivtv_get_card(IVTV_CARD_CX23416GYC_NOGRYCS); | ||
924 | else if ((hw & IVTV_HW_UPD64031A) == 0) | ||
925 | itv->card = ivtv_get_card(IVTV_CARD_CX23416GYC_NOGR); | ||
926 | } | ||
927 | else if (itv->card->type == IVTV_CARD_GV_MVPRX || | ||
928 | itv->card->type == IVTV_CARD_GV_MVPRX2E) { | ||
929 | /* The crystal frequency of GVMVPRX is 24.576MHz */ | ||
930 | v4l2_subdev_call(itv->sd_video, video, s_crystal_freq, | ||
931 | SAA7115_FREQ_24_576_MHZ, SAA7115_FREQ_FL_UCGC); | ||
932 | } | ||
933 | |||
934 | if (hw & IVTV_HW_CX25840) { | ||
935 | itv->vbi.raw_decoder_line_size = 1444; | ||
936 | itv->vbi.raw_decoder_sav_odd_field = 0x20; | ||
937 | itv->vbi.raw_decoder_sav_even_field = 0x60; | ||
938 | itv->vbi.sliced_decoder_line_size = 272; | ||
939 | itv->vbi.sliced_decoder_sav_odd_field = 0xB0; | ||
940 | itv->vbi.sliced_decoder_sav_even_field = 0xF0; | ||
941 | } | ||
942 | |||
943 | if (hw & IVTV_HW_SAA711X) { | ||
944 | struct v4l2_dbg_chip_ident v; | ||
945 | |||
946 | /* determine the exact saa711x model */ | ||
947 | itv->hw_flags &= ~IVTV_HW_SAA711X; | ||
948 | |||
949 | v.match.type = V4L2_CHIP_MATCH_I2C_DRIVER; | ||
950 | strlcpy(v.match.name, "saa7115", sizeof(v.match.name)); | ||
951 | ivtv_call_hw(itv, IVTV_HW_SAA711X, core, g_chip_ident, &v); | ||
952 | if (v.ident == V4L2_IDENT_SAA7114) { | ||
953 | itv->hw_flags |= IVTV_HW_SAA7114; | ||
954 | /* VBI is not yet supported by the saa7114 driver. */ | ||
955 | itv->v4l2_cap &= ~(V4L2_CAP_SLICED_VBI_CAPTURE|V4L2_CAP_VBI_CAPTURE); | ||
956 | } else { | ||
957 | itv->hw_flags |= IVTV_HW_SAA7115; | ||
958 | } | ||
959 | itv->vbi.raw_decoder_line_size = 1443; | ||
960 | itv->vbi.raw_decoder_sav_odd_field = 0x25; | ||
961 | itv->vbi.raw_decoder_sav_even_field = 0x62; | ||
962 | itv->vbi.sliced_decoder_line_size = 51; | ||
963 | itv->vbi.sliced_decoder_sav_odd_field = 0xAB; | ||
964 | itv->vbi.sliced_decoder_sav_even_field = 0xEC; | ||
965 | } | ||
966 | |||
967 | if (hw & IVTV_HW_SAA717X) { | ||
968 | itv->vbi.raw_decoder_line_size = 1443; | ||
969 | itv->vbi.raw_decoder_sav_odd_field = 0x25; | ||
970 | itv->vbi.raw_decoder_sav_even_field = 0x62; | ||
971 | itv->vbi.sliced_decoder_line_size = 51; | ||
972 | itv->vbi.sliced_decoder_sav_odd_field = 0xAB; | ||
973 | itv->vbi.sliced_decoder_sav_even_field = 0xEC; | ||
974 | } | ||
975 | } | ||
976 | |||
977 | static int __devinit ivtv_probe(struct pci_dev *pdev, | ||
978 | const struct pci_device_id *pci_id) | ||
979 | { | ||
980 | int retval = 0; | ||
981 | int vbi_buf_size; | ||
982 | struct ivtv *itv; | ||
983 | |||
984 | itv = kzalloc(sizeof(struct ivtv), GFP_ATOMIC); | ||
985 | if (itv == NULL) | ||
986 | return -ENOMEM; | ||
987 | itv->pdev = pdev; | ||
988 | itv->instance = v4l2_device_set_name(&itv->v4l2_dev, "ivtv", | ||
989 | &ivtv_instance); | ||
990 | |||
991 | retval = v4l2_device_register(&pdev->dev, &itv->v4l2_dev); | ||
992 | if (retval) { | ||
993 | kfree(itv); | ||
994 | return retval; | ||
995 | } | ||
996 | IVTV_INFO("Initializing card %d\n", itv->instance); | ||
997 | |||
998 | ivtv_process_options(itv); | ||
999 | if (itv->options.cardtype == -1) { | ||
1000 | retval = -ENODEV; | ||
1001 | goto err; | ||
1002 | } | ||
1003 | if (ivtv_init_struct1(itv)) { | ||
1004 | retval = -ENOMEM; | ||
1005 | goto err; | ||
1006 | } | ||
1007 | retval = cx2341x_handler_init(&itv->cxhdl, 50); | ||
1008 | if (retval) | ||
1009 | goto err; | ||
1010 | itv->v4l2_dev.ctrl_handler = &itv->cxhdl.hdl; | ||
1011 | itv->cxhdl.ops = &ivtv_cxhdl_ops; | ||
1012 | itv->cxhdl.priv = itv; | ||
1013 | itv->cxhdl.func = ivtv_api_func; | ||
1014 | |||
1015 | IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr); | ||
1016 | |||
1017 | /* PCI Device Setup */ | ||
1018 | retval = ivtv_setup_pci(itv, pdev, pci_id); | ||
1019 | if (retval == -EIO) | ||
1020 | goto free_worker; | ||
1021 | if (retval == -ENXIO) | ||
1022 | goto free_mem; | ||
1023 | |||
1024 | /* map io memory */ | ||
1025 | IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", | ||
1026 | itv->base_addr + IVTV_ENCODER_OFFSET, IVTV_ENCODER_SIZE); | ||
1027 | itv->enc_mem = ioremap_nocache(itv->base_addr + IVTV_ENCODER_OFFSET, | ||
1028 | IVTV_ENCODER_SIZE); | ||
1029 | if (!itv->enc_mem) { | ||
1030 | IVTV_ERR("ioremap failed. Can't get a window into CX23415/6 " | ||
1031 | "encoder memory\n"); | ||
1032 | IVTV_ERR("Each capture card with a CX23415/6 needs 8 MB of " | ||
1033 | "vmalloc address space for this window\n"); | ||
1034 | IVTV_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n"); | ||
1035 | IVTV_ERR("Use the vmalloc= kernel command line option to set " | ||
1036 | "VmallocTotal to a larger value\n"); | ||
1037 | retval = -ENOMEM; | ||
1038 | goto free_mem; | ||
1039 | } | ||
1040 | |||
1041 | if (itv->has_cx23415) { | ||
1042 | IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", | ||
1043 | itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); | ||
1044 | itv->dec_mem = ioremap_nocache(itv->base_addr + IVTV_DECODER_OFFSET, | ||
1045 | IVTV_DECODER_SIZE); | ||
1046 | if (!itv->dec_mem) { | ||
1047 | IVTV_ERR("ioremap failed. Can't get a window into " | ||
1048 | "CX23415 decoder memory\n"); | ||
1049 | IVTV_ERR("Each capture card with a CX23415 needs 8 MB " | ||
1050 | "of vmalloc address space for this window\n"); | ||
1051 | IVTV_ERR("Check the output of 'grep Vmalloc " | ||
1052 | "/proc/meminfo'\n"); | ||
1053 | IVTV_ERR("Use the vmalloc= kernel command line option " | ||
1054 | "to set VmallocTotal to a larger value\n"); | ||
1055 | retval = -ENOMEM; | ||
1056 | goto free_mem; | ||
1057 | } | ||
1058 | } | ||
1059 | else { | ||
1060 | itv->dec_mem = itv->enc_mem; | ||
1061 | } | ||
1062 | |||
1063 | /* map registers memory */ | ||
1064 | IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", | ||
1065 | itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); | ||
1066 | itv->reg_mem = | ||
1067 | ioremap_nocache(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); | ||
1068 | if (!itv->reg_mem) { | ||
1069 | IVTV_ERR("ioremap failed. Can't get a window into CX23415/6 " | ||
1070 | "register space\n"); | ||
1071 | IVTV_ERR("Each capture card with a CX23415/6 needs 64 kB of " | ||
1072 | "vmalloc address space for this window\n"); | ||
1073 | IVTV_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n"); | ||
1074 | IVTV_ERR("Use the vmalloc= kernel command line option to set " | ||
1075 | "VmallocTotal to a larger value\n"); | ||
1076 | retval = -ENOMEM; | ||
1077 | goto free_io; | ||
1078 | } | ||
1079 | |||
1080 | retval = ivtv_gpio_init(itv); | ||
1081 | if (retval) | ||
1082 | goto free_io; | ||
1083 | |||
1084 | /* active i2c */ | ||
1085 | IVTV_DEBUG_INFO("activating i2c...\n"); | ||
1086 | if (init_ivtv_i2c(itv)) { | ||
1087 | IVTV_ERR("Could not initialize i2c\n"); | ||
1088 | goto free_io; | ||
1089 | } | ||
1090 | |||
1091 | if (itv->card->hw_all & IVTV_HW_TVEEPROM) { | ||
1092 | /* Based on the model number the cardtype may be changed. | ||
1093 | The PCI IDs are not always reliable. */ | ||
1094 | ivtv_process_eeprom(itv); | ||
1095 | } | ||
1096 | if (itv->card->comment) | ||
1097 | IVTV_INFO("%s", itv->card->comment); | ||
1098 | if (itv->card->v4l2_capabilities == 0) { | ||
1099 | /* card was detected but is not supported */ | ||
1100 | retval = -ENODEV; | ||
1101 | goto free_i2c; | ||
1102 | } | ||
1103 | |||
1104 | if (itv->std == 0) { | ||
1105 | itv->std = V4L2_STD_NTSC_M; | ||
1106 | } | ||
1107 | |||
1108 | if (itv->options.tuner == -1) { | ||
1109 | int i; | ||
1110 | |||
1111 | for (i = 0; i < IVTV_CARD_MAX_TUNERS; i++) { | ||
1112 | if ((itv->std & itv->card->tuners[i].std) == 0) | ||
1113 | continue; | ||
1114 | itv->options.tuner = itv->card->tuners[i].tuner; | ||
1115 | break; | ||
1116 | } | ||
1117 | } | ||
1118 | /* if no tuner was found, then pick the first tuner in the card list */ | ||
1119 | if (itv->options.tuner == -1 && itv->card->tuners[0].std) { | ||
1120 | itv->std = itv->card->tuners[0].std; | ||
1121 | if (itv->std & V4L2_STD_PAL) | ||
1122 | itv->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H; | ||
1123 | else if (itv->std & V4L2_STD_NTSC) | ||
1124 | itv->std = V4L2_STD_NTSC_M; | ||
1125 | else if (itv->std & V4L2_STD_SECAM) | ||
1126 | itv->std = V4L2_STD_SECAM_L; | ||
1127 | itv->options.tuner = itv->card->tuners[0].tuner; | ||
1128 | } | ||
1129 | if (itv->options.radio == -1) | ||
1130 | itv->options.radio = (itv->card->radio_input.audio_type != 0); | ||
1131 | |||
1132 | /* The card is now fully identified, continue with card-specific | ||
1133 | initialization. */ | ||
1134 | ivtv_init_struct2(itv); | ||
1135 | |||
1136 | ivtv_load_and_init_modules(itv); | ||
1137 | |||
1138 | if (itv->std & V4L2_STD_525_60) { | ||
1139 | itv->is_60hz = 1; | ||
1140 | itv->is_out_60hz = 1; | ||
1141 | } else { | ||
1142 | itv->is_50hz = 1; | ||
1143 | itv->is_out_50hz = 1; | ||
1144 | } | ||
1145 | |||
1146 | itv->yuv_info.osd_full_w = 720; | ||
1147 | itv->yuv_info.osd_full_h = itv->is_out_50hz ? 576 : 480; | ||
1148 | itv->yuv_info.v4l2_src_w = itv->yuv_info.osd_full_w; | ||
1149 | itv->yuv_info.v4l2_src_h = itv->yuv_info.osd_full_h; | ||
1150 | |||
1151 | cx2341x_handler_set_50hz(&itv->cxhdl, itv->is_50hz); | ||
1152 | |||
1153 | itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_MPG] = 0x08000; | ||
1154 | itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_PCM] = 0x01200; | ||
1155 | itv->stream_buf_size[IVTV_DEC_STREAM_TYPE_MPG] = 0x10000; | ||
1156 | itv->stream_buf_size[IVTV_DEC_STREAM_TYPE_YUV] = 0x10000; | ||
1157 | itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_YUV] = 0x08000; | ||
1158 | |||
1159 | /* Setup VBI Raw Size. Should be big enough to hold PAL. | ||
1160 | It is possible to switch between PAL and NTSC, so we need to | ||
1161 | take the largest size here. */ | ||
1162 | /* 1456 is multiple of 16, real size = 1444 */ | ||
1163 | itv->vbi.raw_size = 1456; | ||
1164 | /* We use a buffer size of 1/2 of the total size needed for a | ||
1165 | frame. This is actually very useful, since we now receive | ||
1166 | a field at a time and that makes 'compressing' the raw data | ||
1167 | down to size by stripping off the SAV codes a lot easier. | ||
1168 | Note: having two different buffer sizes prevents standard | ||
1169 | switching on the fly. We need to find a better solution... */ | ||
1170 | vbi_buf_size = itv->vbi.raw_size * (itv->is_60hz ? 24 : 36) / 2; | ||
1171 | itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_VBI] = vbi_buf_size; | ||
1172 | itv->stream_buf_size[IVTV_DEC_STREAM_TYPE_VBI] = sizeof(struct v4l2_sliced_vbi_data) * 36; | ||
1173 | |||
1174 | if (itv->options.radio > 0) | ||
1175 | itv->v4l2_cap |= V4L2_CAP_RADIO; | ||
1176 | |||
1177 | if (itv->options.tuner > -1) { | ||
1178 | struct tuner_setup setup; | ||
1179 | |||
1180 | setup.addr = ADDR_UNSET; | ||
1181 | setup.type = itv->options.tuner; | ||
1182 | setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */ | ||
1183 | setup.tuner_callback = (setup.type == TUNER_XC2028) ? | ||
1184 | ivtv_reset_tuner_gpio : NULL; | ||
1185 | ivtv_call_all(itv, tuner, s_type_addr, &setup); | ||
1186 | if (setup.type == TUNER_XC2028) { | ||
1187 | static struct xc2028_ctrl ctrl = { | ||
1188 | .fname = XC2028_DEFAULT_FIRMWARE, | ||
1189 | .max_len = 64, | ||
1190 | }; | ||
1191 | struct v4l2_priv_tun_config cfg = { | ||
1192 | .tuner = itv->options.tuner, | ||
1193 | .priv = &ctrl, | ||
1194 | }; | ||
1195 | ivtv_call_all(itv, tuner, s_config, &cfg); | ||
1196 | } | ||
1197 | } | ||
1198 | |||
1199 | /* The tuner is fixed to the standard. The other inputs (e.g. S-Video) | ||
1200 | are not. */ | ||
1201 | itv->tuner_std = itv->std; | ||
1202 | |||
1203 | if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { | ||
1204 | ivtv_call_all(itv, video, s_std_output, itv->std); | ||
1205 | /* Turn off the output signal. The mpeg decoder is not yet | ||
1206 | active so without this you would get a green image until the | ||
1207 | mpeg decoder becomes active. */ | ||
1208 | ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 0); | ||
1209 | } | ||
1210 | |||
1211 | /* clear interrupt mask, effectively disabling interrupts */ | ||
1212 | ivtv_set_irq_mask(itv, 0xffffffff); | ||
1213 | |||
1214 | /* Register IRQ */ | ||
1215 | retval = request_irq(itv->pdev->irq, ivtv_irq_handler, | ||
1216 | IRQF_SHARED | IRQF_DISABLED, itv->v4l2_dev.name, (void *)itv); | ||
1217 | if (retval) { | ||
1218 | IVTV_ERR("Failed to register irq %d\n", retval); | ||
1219 | goto free_i2c; | ||
1220 | } | ||
1221 | |||
1222 | retval = ivtv_streams_setup(itv); | ||
1223 | if (retval) { | ||
1224 | IVTV_ERR("Error %d setting up streams\n", retval); | ||
1225 | goto free_irq; | ||
1226 | } | ||
1227 | retval = ivtv_streams_register(itv); | ||
1228 | if (retval) { | ||
1229 | IVTV_ERR("Error %d registering devices\n", retval); | ||
1230 | goto free_streams; | ||
1231 | } | ||
1232 | IVTV_INFO("Initialized card: %s\n", itv->card_name); | ||
1233 | return 0; | ||
1234 | |||
1235 | free_streams: | ||
1236 | ivtv_streams_cleanup(itv, 1); | ||
1237 | free_irq: | ||
1238 | free_irq(itv->pdev->irq, (void *)itv); | ||
1239 | free_i2c: | ||
1240 | exit_ivtv_i2c(itv); | ||
1241 | free_io: | ||
1242 | ivtv_iounmap(itv); | ||
1243 | free_mem: | ||
1244 | release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE); | ||
1245 | release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); | ||
1246 | if (itv->has_cx23415) | ||
1247 | release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); | ||
1248 | free_worker: | ||
1249 | kthread_stop(itv->irq_worker_task); | ||
1250 | err: | ||
1251 | if (retval == 0) | ||
1252 | retval = -ENODEV; | ||
1253 | IVTV_ERR("Error %d on initialization\n", retval); | ||
1254 | |||
1255 | v4l2_device_unregister(&itv->v4l2_dev); | ||
1256 | kfree(itv); | ||
1257 | return retval; | ||
1258 | } | ||
1259 | |||
1260 | int ivtv_init_on_first_open(struct ivtv *itv) | ||
1261 | { | ||
1262 | struct v4l2_frequency vf; | ||
1263 | /* Needed to call ioctls later */ | ||
1264 | struct ivtv_open_id fh; | ||
1265 | int fw_retry_count = 3; | ||
1266 | int video_input; | ||
1267 | |||
1268 | fh.itv = itv; | ||
1269 | |||
1270 | if (test_bit(IVTV_F_I_FAILED, &itv->i_flags)) | ||
1271 | return -ENXIO; | ||
1272 | |||
1273 | if (test_and_set_bit(IVTV_F_I_INITED, &itv->i_flags)) | ||
1274 | return 0; | ||
1275 | |||
1276 | while (--fw_retry_count > 0) { | ||
1277 | /* load firmware */ | ||
1278 | if (ivtv_firmware_init(itv) == 0) | ||
1279 | break; | ||
1280 | if (fw_retry_count > 1) | ||
1281 | IVTV_WARN("Retry loading firmware\n"); | ||
1282 | } | ||
1283 | |||
1284 | if (fw_retry_count == 0) { | ||
1285 | set_bit(IVTV_F_I_FAILED, &itv->i_flags); | ||
1286 | return -ENXIO; | ||
1287 | } | ||
1288 | |||
1289 | /* Try and get firmware versions */ | ||
1290 | IVTV_DEBUG_INFO("Getting firmware version..\n"); | ||
1291 | ivtv_firmware_versions(itv); | ||
1292 | |||
1293 | if (itv->card->hw_all & IVTV_HW_CX25840) | ||
1294 | v4l2_subdev_call(itv->sd_video, core, load_fw); | ||
1295 | |||
1296 | vf.tuner = 0; | ||
1297 | vf.type = V4L2_TUNER_ANALOG_TV; | ||
1298 | vf.frequency = 6400; /* the tuner 'baseline' frequency */ | ||
1299 | |||
1300 | /* Set initial frequency. For PAL/SECAM broadcasts no | ||
1301 | 'default' channel exists AFAIK. */ | ||
1302 | if (itv->std == V4L2_STD_NTSC_M_JP) { | ||
1303 | vf.frequency = 1460; /* ch. 1 91250*16/1000 */ | ||
1304 | } | ||
1305 | else if (itv->std & V4L2_STD_NTSC_M) { | ||
1306 | vf.frequency = 1076; /* ch. 4 67250*16/1000 */ | ||
1307 | } | ||
1308 | |||
1309 | video_input = itv->active_input; | ||
1310 | itv->active_input++; /* Force update of input */ | ||
1311 | ivtv_s_input(NULL, &fh, video_input); | ||
1312 | |||
1313 | /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code | ||
1314 | in one place. */ | ||
1315 | itv->std++; /* Force full standard initialization */ | ||
1316 | itv->std_out = itv->std; | ||
1317 | ivtv_s_frequency(NULL, &fh, &vf); | ||
1318 | |||
1319 | if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) { | ||
1320 | /* Turn on the TV-out: ivtv_init_mpeg_decoder() initializes | ||
1321 | the mpeg decoder so now the saa7127 receives a proper | ||
1322 | signal. */ | ||
1323 | ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1); | ||
1324 | ivtv_init_mpeg_decoder(itv); | ||
1325 | } | ||
1326 | |||
1327 | /* On a cx23416 this seems to be able to enable DMA to the chip? */ | ||
1328 | if (!itv->has_cx23415) | ||
1329 | write_reg_sync(0x03, IVTV_REG_DMACONTROL); | ||
1330 | |||
1331 | ivtv_s_std_enc(itv, &itv->tuner_std); | ||
1332 | |||
1333 | /* Default interrupts enabled. For the PVR350 this includes the | ||
1334 | decoder VSYNC interrupt, which is always on. It is not only used | ||
1335 | during decoding but also by the OSD. | ||
1336 | Some old PVR250 cards had a cx23415, so testing for that is too | ||
1337 | general. Instead test if the card has video output capability. */ | ||
1338 | if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { | ||
1339 | ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT | IVTV_IRQ_DEC_VSYNC); | ||
1340 | ivtv_set_osd_alpha(itv); | ||
1341 | ivtv_s_std_dec(itv, &itv->tuner_std); | ||
1342 | } else { | ||
1343 | ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT); | ||
1344 | } | ||
1345 | |||
1346 | /* Setup initial controls */ | ||
1347 | cx2341x_handler_setup(&itv->cxhdl); | ||
1348 | return 0; | ||
1349 | } | ||
1350 | |||
1351 | static void ivtv_remove(struct pci_dev *pdev) | ||
1352 | { | ||
1353 | struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); | ||
1354 | struct ivtv *itv = to_ivtv(v4l2_dev); | ||
1355 | int i; | ||
1356 | |||
1357 | IVTV_DEBUG_INFO("Removing card\n"); | ||
1358 | |||
1359 | if (test_bit(IVTV_F_I_INITED, &itv->i_flags)) { | ||
1360 | /* Stop all captures */ | ||
1361 | IVTV_DEBUG_INFO("Stopping all streams\n"); | ||
1362 | if (atomic_read(&itv->capturing) > 0) | ||
1363 | ivtv_stop_all_captures(itv); | ||
1364 | |||
1365 | /* Stop all decoding */ | ||
1366 | IVTV_DEBUG_INFO("Stopping decoding\n"); | ||
1367 | |||
1368 | /* Turn off the TV-out */ | ||
1369 | if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) | ||
1370 | ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 0); | ||
1371 | if (atomic_read(&itv->decoding) > 0) { | ||
1372 | int type; | ||
1373 | |||
1374 | if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) | ||
1375 | type = IVTV_DEC_STREAM_TYPE_YUV; | ||
1376 | else | ||
1377 | type = IVTV_DEC_STREAM_TYPE_MPG; | ||
1378 | ivtv_stop_v4l2_decode_stream(&itv->streams[type], | ||
1379 | VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0); | ||
1380 | } | ||
1381 | ivtv_halt_firmware(itv); | ||
1382 | } | ||
1383 | |||
1384 | /* Interrupts */ | ||
1385 | ivtv_set_irq_mask(itv, 0xffffffff); | ||
1386 | del_timer_sync(&itv->dma_timer); | ||
1387 | |||
1388 | /* Kill irq worker */ | ||
1389 | flush_kthread_worker(&itv->irq_worker); | ||
1390 | kthread_stop(itv->irq_worker_task); | ||
1391 | |||
1392 | ivtv_streams_cleanup(itv, 1); | ||
1393 | ivtv_udma_free(itv); | ||
1394 | |||
1395 | exit_ivtv_i2c(itv); | ||
1396 | |||
1397 | free_irq(itv->pdev->irq, (void *)itv); | ||
1398 | ivtv_iounmap(itv); | ||
1399 | |||
1400 | release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE); | ||
1401 | release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); | ||
1402 | if (itv->has_cx23415) | ||
1403 | release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); | ||
1404 | |||
1405 | pci_disable_device(itv->pdev); | ||
1406 | for (i = 0; i < IVTV_VBI_FRAMES; i++) | ||
1407 | kfree(itv->vbi.sliced_mpeg_data[i]); | ||
1408 | |||
1409 | printk(KERN_INFO "ivtv: Removed %s\n", itv->card_name); | ||
1410 | |||
1411 | v4l2_device_unregister(&itv->v4l2_dev); | ||
1412 | kfree(itv); | ||
1413 | } | ||
1414 | |||
1415 | /* define a pci_driver for card detection */ | ||
1416 | static struct pci_driver ivtv_pci_driver = { | ||
1417 | .name = "ivtv", | ||
1418 | .id_table = ivtv_pci_tbl, | ||
1419 | .probe = ivtv_probe, | ||
1420 | .remove = ivtv_remove, | ||
1421 | }; | ||
1422 | |||
1423 | static int __init module_start(void) | ||
1424 | { | ||
1425 | printk(KERN_INFO "ivtv: Start initialization, version %s\n", IVTV_VERSION); | ||
1426 | |||
1427 | /* Validate parameters */ | ||
1428 | if (ivtv_first_minor < 0 || ivtv_first_minor >= IVTV_MAX_CARDS) { | ||
1429 | printk(KERN_ERR "ivtv: Exiting, ivtv_first_minor must be between 0 and %d\n", | ||
1430 | IVTV_MAX_CARDS - 1); | ||
1431 | return -1; | ||
1432 | } | ||
1433 | |||
1434 | if (ivtv_debug < 0 || ivtv_debug > 2047) { | ||
1435 | ivtv_debug = 0; | ||
1436 | printk(KERN_INFO "ivtv: Debug value must be >= 0 and <= 2047\n"); | ||
1437 | } | ||
1438 | |||
1439 | if (pci_register_driver(&ivtv_pci_driver)) { | ||
1440 | printk(KERN_ERR "ivtv: Error detecting PCI card\n"); | ||
1441 | return -ENODEV; | ||
1442 | } | ||
1443 | printk(KERN_INFO "ivtv: End initialization\n"); | ||
1444 | return 0; | ||
1445 | } | ||
1446 | |||
1447 | static void __exit module_cleanup(void) | ||
1448 | { | ||
1449 | pci_unregister_driver(&ivtv_pci_driver); | ||
1450 | } | ||
1451 | |||
1452 | /* Note: These symbols are exported because they are used by the ivtvfb | ||
1453 | framebuffer module and an infrared module for the IR-blaster. */ | ||
1454 | EXPORT_SYMBOL(ivtv_set_irq_mask); | ||
1455 | EXPORT_SYMBOL(ivtv_api); | ||
1456 | EXPORT_SYMBOL(ivtv_vapi); | ||
1457 | EXPORT_SYMBOL(ivtv_vapi_result); | ||
1458 | EXPORT_SYMBOL(ivtv_clear_irq_mask); | ||
1459 | EXPORT_SYMBOL(ivtv_debug); | ||
1460 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1461 | EXPORT_SYMBOL(ivtv_fw_debug); | ||
1462 | #endif | ||
1463 | EXPORT_SYMBOL(ivtv_reset_ir_gpio); | ||
1464 | EXPORT_SYMBOL(ivtv_udma_setup); | ||
1465 | EXPORT_SYMBOL(ivtv_udma_unmap); | ||
1466 | EXPORT_SYMBOL(ivtv_udma_alloc); | ||
1467 | EXPORT_SYMBOL(ivtv_udma_prepare); | ||
1468 | EXPORT_SYMBOL(ivtv_init_on_first_open); | ||
1469 | EXPORT_SYMBOL(ivtv_firmware_check); | ||
1470 | |||
1471 | module_init(module_start); | ||
1472 | module_exit(module_cleanup); | ||
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h new file mode 100644 index 00000000000..8f9cc17b518 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-driver.h | |||
@@ -0,0 +1,831 @@ | |||
1 | /* | ||
2 | ivtv driver internal defines and structures | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2004 Chris Kennedy <c@groovy.org> | ||
5 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #ifndef IVTV_DRIVER_H | ||
23 | #define IVTV_DRIVER_H | ||
24 | |||
25 | /* Internal header for ivtv project: | ||
26 | * Driver for the cx23415/6 chip. | ||
27 | * Author: Kevin Thayer (nufan_wfk at yahoo.com) | ||
28 | * License: GPL | ||
29 | * http://www.ivtvdriver.org | ||
30 | * | ||
31 | * ----- | ||
32 | * MPG600/MPG160 support by T.Adachi <tadachi@tadachi-net.com> | ||
33 | * and Takeru KOMORIYA<komoriya@paken.org> | ||
34 | * | ||
35 | * AVerMedia M179 GPIO info by Chris Pinkham <cpinkham@bc2va.org> | ||
36 | * using information provided by Jiun-Kuei Jung @ AVerMedia. | ||
37 | */ | ||
38 | |||
39 | #include <linux/module.h> | ||
40 | #include <linux/init.h> | ||
41 | #include <linux/delay.h> | ||
42 | #include <linux/sched.h> | ||
43 | #include <linux/fs.h> | ||
44 | #include <linux/pci.h> | ||
45 | #include <linux/interrupt.h> | ||
46 | #include <linux/spinlock.h> | ||
47 | #include <linux/i2c.h> | ||
48 | #include <linux/i2c-algo-bit.h> | ||
49 | #include <linux/list.h> | ||
50 | #include <linux/unistd.h> | ||
51 | #include <linux/pagemap.h> | ||
52 | #include <linux/scatterlist.h> | ||
53 | #include <linux/kthread.h> | ||
54 | #include <linux/mutex.h> | ||
55 | #include <linux/slab.h> | ||
56 | #include <asm/uaccess.h> | ||
57 | #include <asm/system.h> | ||
58 | #include <asm/byteorder.h> | ||
59 | |||
60 | #include <linux/dvb/video.h> | ||
61 | #include <linux/dvb/audio.h> | ||
62 | #include <media/v4l2-common.h> | ||
63 | #include <media/v4l2-ioctl.h> | ||
64 | #include <media/v4l2-ctrls.h> | ||
65 | #include <media/v4l2-device.h> | ||
66 | #include <media/v4l2-fh.h> | ||
67 | #include <media/tuner.h> | ||
68 | #include <media/cx2341x.h> | ||
69 | #include <media/ir-kbd-i2c.h> | ||
70 | |||
71 | #include <linux/ivtv.h> | ||
72 | |||
73 | /* Memory layout */ | ||
74 | #define IVTV_ENCODER_OFFSET 0x00000000 | ||
75 | #define IVTV_ENCODER_SIZE 0x00800000 /* Total size is 0x01000000, but only first half is used */ | ||
76 | #define IVTV_DECODER_OFFSET 0x01000000 | ||
77 | #define IVTV_DECODER_SIZE 0x00800000 /* Total size is 0x01000000, but only first half is used */ | ||
78 | #define IVTV_REG_OFFSET 0x02000000 | ||
79 | #define IVTV_REG_SIZE 0x00010000 | ||
80 | |||
81 | /* Maximum ivtv driver instances. Some people have a huge number of | ||
82 | capture cards, so set this to a high value. */ | ||
83 | #define IVTV_MAX_CARDS 32 | ||
84 | |||
85 | #define IVTV_ENC_STREAM_TYPE_MPG 0 | ||
86 | #define IVTV_ENC_STREAM_TYPE_YUV 1 | ||
87 | #define IVTV_ENC_STREAM_TYPE_VBI 2 | ||
88 | #define IVTV_ENC_STREAM_TYPE_PCM 3 | ||
89 | #define IVTV_ENC_STREAM_TYPE_RAD 4 | ||
90 | #define IVTV_DEC_STREAM_TYPE_MPG 5 | ||
91 | #define IVTV_DEC_STREAM_TYPE_VBI 6 | ||
92 | #define IVTV_DEC_STREAM_TYPE_VOUT 7 | ||
93 | #define IVTV_DEC_STREAM_TYPE_YUV 8 | ||
94 | #define IVTV_MAX_STREAMS 9 | ||
95 | |||
96 | #define IVTV_DMA_SG_OSD_ENT (2883584/PAGE_SIZE) /* sg entities */ | ||
97 | |||
98 | /* DMA Registers */ | ||
99 | #define IVTV_REG_DMAXFER (0x0000) | ||
100 | #define IVTV_REG_DMASTATUS (0x0004) | ||
101 | #define IVTV_REG_DECDMAADDR (0x0008) | ||
102 | #define IVTV_REG_ENCDMAADDR (0x000c) | ||
103 | #define IVTV_REG_DMACONTROL (0x0010) | ||
104 | #define IVTV_REG_IRQSTATUS (0x0040) | ||
105 | #define IVTV_REG_IRQMASK (0x0048) | ||
106 | |||
107 | /* Setup Registers */ | ||
108 | #define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8) | ||
109 | #define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC) | ||
110 | #define IVTV_REG_DEC_SDRAM_REFRESH (0x08F8) | ||
111 | #define IVTV_REG_DEC_SDRAM_PRECHARGE (0x08FC) | ||
112 | #define IVTV_REG_VDM (0x2800) | ||
113 | #define IVTV_REG_AO (0x2D00) | ||
114 | #define IVTV_REG_BYTEFLUSH (0x2D24) | ||
115 | #define IVTV_REG_SPU (0x9050) | ||
116 | #define IVTV_REG_HW_BLOCKS (0x9054) | ||
117 | #define IVTV_REG_VPU (0x9058) | ||
118 | #define IVTV_REG_APU (0xA064) | ||
119 | |||
120 | /* Other registers */ | ||
121 | #define IVTV_REG_DEC_LINE_FIELD (0x28C0) | ||
122 | |||
123 | /* debugging */ | ||
124 | extern int ivtv_debug; | ||
125 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
126 | extern int ivtv_fw_debug; | ||
127 | #endif | ||
128 | |||
129 | #define IVTV_DBGFLG_WARN (1 << 0) | ||
130 | #define IVTV_DBGFLG_INFO (1 << 1) | ||
131 | #define IVTV_DBGFLG_MB (1 << 2) | ||
132 | #define IVTV_DBGFLG_IOCTL (1 << 3) | ||
133 | #define IVTV_DBGFLG_FILE (1 << 4) | ||
134 | #define IVTV_DBGFLG_DMA (1 << 5) | ||
135 | #define IVTV_DBGFLG_IRQ (1 << 6) | ||
136 | #define IVTV_DBGFLG_DEC (1 << 7) | ||
137 | #define IVTV_DBGFLG_YUV (1 << 8) | ||
138 | #define IVTV_DBGFLG_I2C (1 << 9) | ||
139 | /* Flag to turn on high volume debugging */ | ||
140 | #define IVTV_DBGFLG_HIGHVOL (1 << 10) | ||
141 | |||
142 | #define IVTV_DEBUG(x, type, fmt, args...) \ | ||
143 | do { \ | ||
144 | if ((x) & ivtv_debug) \ | ||
145 | v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args); \ | ||
146 | } while (0) | ||
147 | #define IVTV_DEBUG_WARN(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_WARN, "warn", fmt , ## args) | ||
148 | #define IVTV_DEBUG_INFO(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_INFO, "info", fmt , ## args) | ||
149 | #define IVTV_DEBUG_MB(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_MB, "mb", fmt , ## args) | ||
150 | #define IVTV_DEBUG_DMA(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_DMA, "dma", fmt , ## args) | ||
151 | #define IVTV_DEBUG_IOCTL(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_IOCTL, "ioctl", fmt , ## args) | ||
152 | #define IVTV_DEBUG_FILE(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_FILE, "file", fmt , ## args) | ||
153 | #define IVTV_DEBUG_I2C(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_I2C, "i2c", fmt , ## args) | ||
154 | #define IVTV_DEBUG_IRQ(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_IRQ, "irq", fmt , ## args) | ||
155 | #define IVTV_DEBUG_DEC(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_DEC, "dec", fmt , ## args) | ||
156 | #define IVTV_DEBUG_YUV(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_YUV, "yuv", fmt , ## args) | ||
157 | |||
158 | #define IVTV_DEBUG_HIGH_VOL(x, type, fmt, args...) \ | ||
159 | do { \ | ||
160 | if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) \ | ||
161 | v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args); \ | ||
162 | } while (0) | ||
163 | #define IVTV_DEBUG_HI_WARN(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN, "warn", fmt , ## args) | ||
164 | #define IVTV_DEBUG_HI_INFO(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_INFO, "info", fmt , ## args) | ||
165 | #define IVTV_DEBUG_HI_MB(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_MB, "mb", fmt , ## args) | ||
166 | #define IVTV_DEBUG_HI_DMA(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DMA, "dma", fmt , ## args) | ||
167 | #define IVTV_DEBUG_HI_IOCTL(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_IOCTL, "ioctl", fmt , ## args) | ||
168 | #define IVTV_DEBUG_HI_FILE(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_FILE, "file", fmt , ## args) | ||
169 | #define IVTV_DEBUG_HI_I2C(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_I2C, "i2c", fmt , ## args) | ||
170 | #define IVTV_DEBUG_HI_IRQ(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_IRQ, "irq", fmt , ## args) | ||
171 | #define IVTV_DEBUG_HI_DEC(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DEC, "dec", fmt , ## args) | ||
172 | #define IVTV_DEBUG_HI_YUV(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_YUV, "yuv", fmt , ## args) | ||
173 | |||
174 | /* Standard kernel messages */ | ||
175 | #define IVTV_ERR(fmt, args...) v4l2_err(&itv->v4l2_dev, fmt , ## args) | ||
176 | #define IVTV_WARN(fmt, args...) v4l2_warn(&itv->v4l2_dev, fmt , ## args) | ||
177 | #define IVTV_INFO(fmt, args...) v4l2_info(&itv->v4l2_dev, fmt , ## args) | ||
178 | |||
179 | /* output modes (cx23415 only) */ | ||
180 | #define OUT_NONE 0 | ||
181 | #define OUT_MPG 1 | ||
182 | #define OUT_YUV 2 | ||
183 | #define OUT_UDMA_YUV 3 | ||
184 | #define OUT_PASSTHROUGH 4 | ||
185 | |||
186 | #define IVTV_MAX_PGM_INDEX (400) | ||
187 | |||
188 | /* Default I2C SCL period in microseconds */ | ||
189 | #define IVTV_DEFAULT_I2C_CLOCK_PERIOD 20 | ||
190 | |||
191 | struct ivtv_options { | ||
192 | int kilobytes[IVTV_MAX_STREAMS]; /* size in kilobytes of each stream */ | ||
193 | int cardtype; /* force card type on load */ | ||
194 | int tuner; /* set tuner on load */ | ||
195 | int radio; /* enable/disable radio */ | ||
196 | int newi2c; /* new I2C algorithm */ | ||
197 | int i2c_clock_period; /* period of SCL for I2C bus */ | ||
198 | }; | ||
199 | |||
200 | /* ivtv-specific mailbox template */ | ||
201 | struct ivtv_mailbox { | ||
202 | u32 flags; | ||
203 | u32 cmd; | ||
204 | u32 retval; | ||
205 | u32 timeout; | ||
206 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
207 | }; | ||
208 | |||
209 | struct ivtv_api_cache { | ||
210 | unsigned long last_jiffies; /* when last command was issued */ | ||
211 | u32 data[CX2341X_MBOX_MAX_DATA]; /* last sent api data */ | ||
212 | }; | ||
213 | |||
214 | struct ivtv_mailbox_data { | ||
215 | volatile struct ivtv_mailbox __iomem *mbox; | ||
216 | /* Bits 0-2 are for the encoder mailboxes, 0-1 are for the decoder mailboxes. | ||
217 | If the bit is set, then the corresponding mailbox is in use by the driver. */ | ||
218 | unsigned long busy; | ||
219 | u8 max_mbox; | ||
220 | }; | ||
221 | |||
222 | /* per-buffer bit flags */ | ||
223 | #define IVTV_F_B_NEED_BUF_SWAP (1 << 0) /* this buffer should be byte swapped */ | ||
224 | |||
225 | /* per-stream, s_flags */ | ||
226 | #define IVTV_F_S_DMA_PENDING 0 /* this stream has pending DMA */ | ||
227 | #define IVTV_F_S_DMA_HAS_VBI 1 /* the current DMA request also requests VBI data */ | ||
228 | #define IVTV_F_S_NEEDS_DATA 2 /* this decoding stream needs more data */ | ||
229 | |||
230 | #define IVTV_F_S_CLAIMED 3 /* this stream is claimed */ | ||
231 | #define IVTV_F_S_STREAMING 4 /* the fw is decoding/encoding this stream */ | ||
232 | #define IVTV_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */ | ||
233 | #define IVTV_F_S_PASSTHROUGH 6 /* this stream is in passthrough mode */ | ||
234 | #define IVTV_F_S_STREAMOFF 7 /* signal end of stream EOS */ | ||
235 | #define IVTV_F_S_APPL_IO 8 /* this stream is used read/written by an application */ | ||
236 | |||
237 | #define IVTV_F_S_PIO_PENDING 9 /* this stream has pending PIO */ | ||
238 | #define IVTV_F_S_PIO_HAS_VBI 1 /* the current PIO request also requests VBI data */ | ||
239 | |||
240 | /* per-ivtv, i_flags */ | ||
241 | #define IVTV_F_I_DMA 0 /* DMA in progress */ | ||
242 | #define IVTV_F_I_UDMA 1 /* UDMA in progress */ | ||
243 | #define IVTV_F_I_UDMA_PENDING 2 /* UDMA pending */ | ||
244 | #define IVTV_F_I_SPEED_CHANGE 3 /* a speed change is in progress */ | ||
245 | #define IVTV_F_I_EOS 4 /* end of encoder stream reached */ | ||
246 | #define IVTV_F_I_RADIO_USER 5 /* the radio tuner is selected */ | ||
247 | #define IVTV_F_I_DIG_RST 6 /* reset digitizer */ | ||
248 | #define IVTV_F_I_DEC_YUV 7 /* YUV instead of MPG is being decoded */ | ||
249 | #define IVTV_F_I_UPDATE_CC 9 /* CC should be updated */ | ||
250 | #define IVTV_F_I_UPDATE_WSS 10 /* WSS should be updated */ | ||
251 | #define IVTV_F_I_UPDATE_VPS 11 /* VPS should be updated */ | ||
252 | #define IVTV_F_I_DECODING_YUV 12 /* this stream is YUV frame decoding */ | ||
253 | #define IVTV_F_I_ENC_PAUSED 13 /* the encoder is paused */ | ||
254 | #define IVTV_F_I_VALID_DEC_TIMINGS 14 /* last_dec_timing is valid */ | ||
255 | #define IVTV_F_I_HAVE_WORK 15 /* used in the interrupt handler: there is work to be done */ | ||
256 | #define IVTV_F_I_WORK_HANDLER_VBI 16 /* there is work to be done for VBI */ | ||
257 | #define IVTV_F_I_WORK_HANDLER_YUV 17 /* there is work to be done for YUV */ | ||
258 | #define IVTV_F_I_WORK_HANDLER_PIO 18 /* there is work to be done for PIO */ | ||
259 | #define IVTV_F_I_PIO 19 /* PIO in progress */ | ||
260 | #define IVTV_F_I_DEC_PAUSED 20 /* the decoder is paused */ | ||
261 | #define IVTV_F_I_INITED 21 /* set after first open */ | ||
262 | #define IVTV_F_I_FAILED 22 /* set if first open failed */ | ||
263 | |||
264 | /* Event notifications */ | ||
265 | #define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */ | ||
266 | #define IVTV_F_I_EV_VSYNC 29 /* VSYNC event */ | ||
267 | #define IVTV_F_I_EV_VSYNC_FIELD 30 /* VSYNC event field (0 = first, 1 = second field) */ | ||
268 | #define IVTV_F_I_EV_VSYNC_ENABLED 31 /* VSYNC event enabled */ | ||
269 | |||
270 | /* Scatter-Gather array element, used in DMA transfers */ | ||
271 | struct ivtv_sg_element { | ||
272 | __le32 src; | ||
273 | __le32 dst; | ||
274 | __le32 size; | ||
275 | }; | ||
276 | |||
277 | struct ivtv_sg_host_element { | ||
278 | u32 src; | ||
279 | u32 dst; | ||
280 | u32 size; | ||
281 | }; | ||
282 | |||
283 | struct ivtv_user_dma { | ||
284 | struct mutex lock; | ||
285 | int page_count; | ||
286 | struct page *map[IVTV_DMA_SG_OSD_ENT]; | ||
287 | /* Needed when dealing with highmem userspace buffers */ | ||
288 | struct page *bouncemap[IVTV_DMA_SG_OSD_ENT]; | ||
289 | |||
290 | /* Base Dev SG Array for cx23415/6 */ | ||
291 | struct ivtv_sg_element SGarray[IVTV_DMA_SG_OSD_ENT]; | ||
292 | dma_addr_t SG_handle; | ||
293 | int SG_length; | ||
294 | |||
295 | /* SG List of Buffers */ | ||
296 | struct scatterlist SGlist[IVTV_DMA_SG_OSD_ENT]; | ||
297 | }; | ||
298 | |||
299 | struct ivtv_dma_page_info { | ||
300 | unsigned long uaddr; | ||
301 | unsigned long first; | ||
302 | unsigned long last; | ||
303 | unsigned int offset; | ||
304 | unsigned int tail; | ||
305 | int page_count; | ||
306 | }; | ||
307 | |||
308 | struct ivtv_buffer { | ||
309 | struct list_head list; | ||
310 | dma_addr_t dma_handle; | ||
311 | unsigned short b_flags; | ||
312 | unsigned short dma_xfer_cnt; | ||
313 | char *buf; | ||
314 | u32 bytesused; | ||
315 | u32 readpos; | ||
316 | }; | ||
317 | |||
318 | struct ivtv_queue { | ||
319 | struct list_head list; /* the list of buffers in this queue */ | ||
320 | u32 buffers; /* number of buffers in this queue */ | ||
321 | u32 length; /* total number of bytes of available buffer space */ | ||
322 | u32 bytesused; /* total number of bytes used in this queue */ | ||
323 | }; | ||
324 | |||
325 | struct ivtv; /* forward reference */ | ||
326 | |||
327 | struct ivtv_stream { | ||
328 | /* These first four fields are always set, even if the stream | ||
329 | is not actually created. */ | ||
330 | struct video_device *vdev; /* NULL when stream not created */ | ||
331 | struct ivtv *itv; /* for ease of use */ | ||
332 | const char *name; /* name of the stream */ | ||
333 | int type; /* stream type */ | ||
334 | |||
335 | u32 id; | ||
336 | spinlock_t qlock; /* locks access to the queues */ | ||
337 | unsigned long s_flags; /* status flags, see above */ | ||
338 | int dma; /* can be PCI_DMA_TODEVICE, PCI_DMA_FROMDEVICE or PCI_DMA_NONE */ | ||
339 | u32 pending_offset; | ||
340 | u32 pending_backup; | ||
341 | u64 pending_pts; | ||
342 | |||
343 | u32 dma_offset; | ||
344 | u32 dma_backup; | ||
345 | u64 dma_pts; | ||
346 | |||
347 | int subtype; | ||
348 | wait_queue_head_t waitq; | ||
349 | u32 dma_last_offset; | ||
350 | |||
351 | /* Buffer Stats */ | ||
352 | u32 buffers; | ||
353 | u32 buf_size; | ||
354 | u32 buffers_stolen; | ||
355 | |||
356 | /* Buffer Queues */ | ||
357 | struct ivtv_queue q_free; /* free buffers */ | ||
358 | struct ivtv_queue q_full; /* full buffers */ | ||
359 | struct ivtv_queue q_io; /* waiting for I/O */ | ||
360 | struct ivtv_queue q_dma; /* waiting for DMA */ | ||
361 | struct ivtv_queue q_predma; /* waiting for DMA */ | ||
362 | |||
363 | /* DMA xfer counter, buffers belonging to the same DMA | ||
364 | xfer will have the same dma_xfer_cnt. */ | ||
365 | u16 dma_xfer_cnt; | ||
366 | |||
367 | /* Base Dev SG Array for cx23415/6 */ | ||
368 | struct ivtv_sg_host_element *sg_pending; | ||
369 | struct ivtv_sg_host_element *sg_processing; | ||
370 | struct ivtv_sg_element *sg_dma; | ||
371 | dma_addr_t sg_handle; | ||
372 | int sg_pending_size; | ||
373 | int sg_processing_size; | ||
374 | int sg_processed; | ||
375 | |||
376 | /* SG List of Buffers */ | ||
377 | struct scatterlist *SGlist; | ||
378 | }; | ||
379 | |||
380 | struct ivtv_open_id { | ||
381 | struct v4l2_fh fh; | ||
382 | u32 open_id; /* unique ID for this file descriptor */ | ||
383 | int type; /* stream type */ | ||
384 | int yuv_frames; /* 1: started OUT_UDMA_YUV output mode */ | ||
385 | struct ivtv *itv; | ||
386 | }; | ||
387 | |||
388 | static inline struct ivtv_open_id *fh2id(struct v4l2_fh *fh) | ||
389 | { | ||
390 | return container_of(fh, struct ivtv_open_id, fh); | ||
391 | } | ||
392 | |||
393 | struct yuv_frame_info | ||
394 | { | ||
395 | u32 update; | ||
396 | s32 src_x; | ||
397 | s32 src_y; | ||
398 | u32 src_w; | ||
399 | u32 src_h; | ||
400 | s32 dst_x; | ||
401 | s32 dst_y; | ||
402 | u32 dst_w; | ||
403 | u32 dst_h; | ||
404 | s32 pan_x; | ||
405 | s32 pan_y; | ||
406 | u32 vis_w; | ||
407 | u32 vis_h; | ||
408 | u32 interlaced_y; | ||
409 | u32 interlaced_uv; | ||
410 | s32 tru_x; | ||
411 | u32 tru_w; | ||
412 | u32 tru_h; | ||
413 | u32 offset_y; | ||
414 | s32 lace_mode; | ||
415 | u32 sync_field; | ||
416 | u32 delay; | ||
417 | u32 interlaced; | ||
418 | }; | ||
419 | |||
420 | #define IVTV_YUV_MODE_INTERLACED 0x00 | ||
421 | #define IVTV_YUV_MODE_PROGRESSIVE 0x01 | ||
422 | #define IVTV_YUV_MODE_AUTO 0x02 | ||
423 | #define IVTV_YUV_MODE_MASK 0x03 | ||
424 | |||
425 | #define IVTV_YUV_SYNC_EVEN 0x00 | ||
426 | #define IVTV_YUV_SYNC_ODD 0x04 | ||
427 | #define IVTV_YUV_SYNC_MASK 0x04 | ||
428 | |||
429 | #define IVTV_YUV_BUFFERS 8 | ||
430 | |||
431 | struct yuv_playback_info | ||
432 | { | ||
433 | u32 reg_2834; | ||
434 | u32 reg_2838; | ||
435 | u32 reg_283c; | ||
436 | u32 reg_2840; | ||
437 | u32 reg_2844; | ||
438 | u32 reg_2848; | ||
439 | u32 reg_2854; | ||
440 | u32 reg_285c; | ||
441 | u32 reg_2864; | ||
442 | |||
443 | u32 reg_2870; | ||
444 | u32 reg_2874; | ||
445 | u32 reg_2890; | ||
446 | u32 reg_2898; | ||
447 | u32 reg_289c; | ||
448 | |||
449 | u32 reg_2918; | ||
450 | u32 reg_291c; | ||
451 | u32 reg_2920; | ||
452 | u32 reg_2924; | ||
453 | u32 reg_2928; | ||
454 | u32 reg_292c; | ||
455 | u32 reg_2930; | ||
456 | |||
457 | u32 reg_2934; | ||
458 | |||
459 | u32 reg_2938; | ||
460 | u32 reg_293c; | ||
461 | u32 reg_2940; | ||
462 | u32 reg_2944; | ||
463 | u32 reg_2948; | ||
464 | u32 reg_294c; | ||
465 | u32 reg_2950; | ||
466 | u32 reg_2954; | ||
467 | u32 reg_2958; | ||
468 | u32 reg_295c; | ||
469 | u32 reg_2960; | ||
470 | u32 reg_2964; | ||
471 | u32 reg_2968; | ||
472 | u32 reg_296c; | ||
473 | |||
474 | u32 reg_2970; | ||
475 | |||
476 | int v_filter_1; | ||
477 | int v_filter_2; | ||
478 | int h_filter; | ||
479 | |||
480 | u8 track_osd; /* Should yuv output track the OSD size & position */ | ||
481 | |||
482 | u32 osd_x_offset; | ||
483 | u32 osd_y_offset; | ||
484 | |||
485 | u32 osd_x_pan; | ||
486 | u32 osd_y_pan; | ||
487 | |||
488 | u32 osd_vis_w; | ||
489 | u32 osd_vis_h; | ||
490 | |||
491 | u32 osd_full_w; | ||
492 | u32 osd_full_h; | ||
493 | |||
494 | int decode_height; | ||
495 | |||
496 | int lace_mode; | ||
497 | int lace_threshold; | ||
498 | int lace_sync_field; | ||
499 | |||
500 | atomic_t next_dma_frame; | ||
501 | atomic_t next_fill_frame; | ||
502 | |||
503 | u32 yuv_forced_update; | ||
504 | int update_frame; | ||
505 | |||
506 | u8 fields_lapsed; /* Counter used when delaying a frame */ | ||
507 | |||
508 | struct yuv_frame_info new_frame_info[IVTV_YUV_BUFFERS]; | ||
509 | struct yuv_frame_info old_frame_info; | ||
510 | struct yuv_frame_info old_frame_info_args; | ||
511 | |||
512 | void *blanking_ptr; | ||
513 | dma_addr_t blanking_dmaptr; | ||
514 | |||
515 | int stream_size; | ||
516 | |||
517 | u8 draw_frame; /* PVR350 buffer to draw into */ | ||
518 | u8 max_frames_buffered; /* Maximum number of frames to buffer */ | ||
519 | |||
520 | struct v4l2_rect main_rect; | ||
521 | u32 v4l2_src_w; | ||
522 | u32 v4l2_src_h; | ||
523 | |||
524 | u8 running; /* Have any frames been displayed */ | ||
525 | }; | ||
526 | |||
527 | #define IVTV_VBI_FRAMES 32 | ||
528 | |||
529 | /* VBI data */ | ||
530 | struct vbi_cc { | ||
531 | u8 odd[2]; /* two-byte payload of odd field */ | ||
532 | u8 even[2]; /* two-byte payload of even field */; | ||
533 | }; | ||
534 | |||
535 | struct vbi_vps { | ||
536 | u8 data[5]; /* five-byte VPS payload */ | ||
537 | }; | ||
538 | |||
539 | struct vbi_info { | ||
540 | /* VBI general data, does not change during streaming */ | ||
541 | |||
542 | u32 raw_decoder_line_size; /* raw VBI line size from digitizer */ | ||
543 | u8 raw_decoder_sav_odd_field; /* raw VBI Start Active Video digitizer code of odd field */ | ||
544 | u8 raw_decoder_sav_even_field; /* raw VBI Start Active Video digitizer code of even field */ | ||
545 | u32 sliced_decoder_line_size; /* sliced VBI line size from digitizer */ | ||
546 | u8 sliced_decoder_sav_odd_field; /* sliced VBI Start Active Video digitizer code of odd field */ | ||
547 | u8 sliced_decoder_sav_even_field; /* sliced VBI Start Active Video digitizer code of even field */ | ||
548 | |||
549 | u32 start[2]; /* start of first VBI line in the odd/even fields */ | ||
550 | u32 count; /* number of VBI lines per field */ | ||
551 | u32 raw_size; /* size of raw VBI line from the digitizer */ | ||
552 | u32 sliced_size; /* size of sliced VBI line from the digitizer */ | ||
553 | |||
554 | u32 dec_start; /* start in decoder memory of VBI re-insertion buffers */ | ||
555 | u32 enc_start; /* start in encoder memory of VBI capture buffers */ | ||
556 | u32 enc_size; /* size of VBI capture area */ | ||
557 | int fpi; /* number of VBI frames per interrupt */ | ||
558 | |||
559 | struct v4l2_format in; /* current VBI capture format */ | ||
560 | struct v4l2_sliced_vbi_format *sliced_in; /* convenience pointer to sliced struct in vbi.in union */ | ||
561 | int insert_mpeg; /* if non-zero, then embed VBI data in MPEG stream */ | ||
562 | |||
563 | /* Raw VBI compatibility hack */ | ||
564 | |||
565 | u32 frame; /* frame counter hack needed for backwards compatibility | ||
566 | of old VBI software */ | ||
567 | |||
568 | /* Sliced VBI output data */ | ||
569 | |||
570 | struct vbi_cc cc_payload[256]; /* sliced VBI CC payload array: it is an array to | ||
571 | prevent dropping CC data if they couldn't be | ||
572 | processed fast enough */ | ||
573 | int cc_payload_idx; /* index in cc_payload */ | ||
574 | u8 cc_missing_cnt; /* counts number of frames without CC for passthrough mode */ | ||
575 | int wss_payload; /* sliced VBI WSS payload */ | ||
576 | u8 wss_missing_cnt; /* counts number of frames without WSS for passthrough mode */ | ||
577 | struct vbi_vps vps_payload; /* sliced VBI VPS payload */ | ||
578 | |||
579 | /* Sliced VBI capture data */ | ||
580 | |||
581 | struct v4l2_sliced_vbi_data sliced_data[36]; /* sliced VBI storage for VBI encoder stream */ | ||
582 | struct v4l2_sliced_vbi_data sliced_dec_data[36];/* sliced VBI storage for VBI decoder stream */ | ||
583 | |||
584 | /* VBI Embedding data */ | ||
585 | |||
586 | /* Buffer for VBI data inserted into MPEG stream. | ||
587 | The first byte is a dummy byte that's never used. | ||
588 | The next 16 bytes contain the MPEG header for the VBI data, | ||
589 | the remainder is the actual VBI data. | ||
590 | The max size accepted by the MPEG VBI reinsertion turns out | ||
591 | to be 1552 bytes, which happens to be 4 + (1 + 42) * (2 * 18) bytes, | ||
592 | where 4 is a four byte header, 42 is the max sliced VBI payload, 1 is | ||
593 | a single line header byte and 2 * 18 is the number of VBI lines per frame. | ||
594 | |||
595 | However, it seems that the data must be 1K aligned, so we have to | ||
596 | pad the data until the 1 or 2 K boundary. | ||
597 | |||
598 | This pointer array will allocate 2049 bytes to store each VBI frame. */ | ||
599 | u8 *sliced_mpeg_data[IVTV_VBI_FRAMES]; | ||
600 | u32 sliced_mpeg_size[IVTV_VBI_FRAMES]; | ||
601 | struct ivtv_buffer sliced_mpeg_buf; /* temporary buffer holding data from sliced_mpeg_data */ | ||
602 | u32 inserted_frame; /* index in sliced_mpeg_size of next sliced data | ||
603 | to be inserted in the MPEG stream */ | ||
604 | }; | ||
605 | |||
606 | /* forward declaration of struct defined in ivtv-cards.h */ | ||
607 | struct ivtv_card; | ||
608 | |||
609 | /* Struct to hold info about ivtv cards */ | ||
610 | struct ivtv { | ||
611 | /* General fixed card data */ | ||
612 | struct pci_dev *pdev; /* PCI device */ | ||
613 | const struct ivtv_card *card; /* card information */ | ||
614 | const char *card_name; /* full name of the card */ | ||
615 | const struct ivtv_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */ | ||
616 | u8 has_cx23415; /* 1 if it is a cx23415 based card, 0 for cx23416 */ | ||
617 | u8 pvr150_workaround; /* 1 if the cx25840 needs to workaround a PVR150 bug */ | ||
618 | u8 nof_inputs; /* number of video inputs */ | ||
619 | u8 nof_audio_inputs; /* number of audio inputs */ | ||
620 | u32 v4l2_cap; /* V4L2 capabilities of card */ | ||
621 | u32 hw_flags; /* hardware description of the board */ | ||
622 | v4l2_std_id tuner_std; /* the norm of the card's tuner (fixed) */ | ||
623 | struct v4l2_subdev *sd_video; /* controlling video decoder subdev */ | ||
624 | struct v4l2_subdev *sd_audio; /* controlling audio subdev */ | ||
625 | struct v4l2_subdev *sd_muxer; /* controlling audio muxer subdev */ | ||
626 | u32 base_addr; /* PCI resource base address */ | ||
627 | volatile void __iomem *enc_mem; /* pointer to mapped encoder memory */ | ||
628 | volatile void __iomem *dec_mem; /* pointer to mapped decoder memory */ | ||
629 | volatile void __iomem *reg_mem; /* pointer to mapped registers */ | ||
630 | struct ivtv_options options; /* user options */ | ||
631 | |||
632 | struct v4l2_device v4l2_dev; | ||
633 | struct cx2341x_handler cxhdl; | ||
634 | struct v4l2_ctrl_handler hdl_gpio; | ||
635 | struct v4l2_subdev sd_gpio; /* GPIO sub-device */ | ||
636 | u16 instance; | ||
637 | |||
638 | /* High-level state info */ | ||
639 | unsigned long i_flags; /* global ivtv flags */ | ||
640 | u8 is_50hz; /* 1 if the current capture standard is 50 Hz */ | ||
641 | u8 is_60hz /* 1 if the current capture standard is 60 Hz */; | ||
642 | u8 is_out_50hz /* 1 if the current TV output standard is 50 Hz */; | ||
643 | u8 is_out_60hz /* 1 if the current TV output standard is 60 Hz */; | ||
644 | int output_mode; /* decoder output mode: NONE, MPG, YUV, UDMA YUV, passthrough */ | ||
645 | u32 audio_input; /* current audio input */ | ||
646 | u32 active_input; /* current video input */ | ||
647 | u32 active_output; /* current video output */ | ||
648 | v4l2_std_id std; /* current capture TV standard */ | ||
649 | v4l2_std_id std_out; /* current TV output standard */ | ||
650 | u8 audio_stereo_mode; /* decoder setting how to handle stereo MPEG audio */ | ||
651 | u8 audio_bilingual_mode; /* decoder setting how to handle bilingual MPEG audio */ | ||
652 | |||
653 | |||
654 | /* Locking */ | ||
655 | spinlock_t lock; /* lock access to this struct */ | ||
656 | struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */ | ||
657 | |||
658 | /* Streams */ | ||
659 | int stream_buf_size[IVTV_MAX_STREAMS]; /* stream buffer size */ | ||
660 | struct ivtv_stream streams[IVTV_MAX_STREAMS]; /* stream data */ | ||
661 | atomic_t capturing; /* count number of active capture streams */ | ||
662 | atomic_t decoding; /* count number of active decoding streams */ | ||
663 | |||
664 | |||
665 | /* Interrupts & DMA */ | ||
666 | u32 irqmask; /* active interrupts */ | ||
667 | u32 irq_rr_idx; /* round-robin stream index */ | ||
668 | struct kthread_worker irq_worker; /* kthread worker for PIO/YUV/VBI actions */ | ||
669 | struct task_struct *irq_worker_task; /* task for irq_worker */ | ||
670 | struct kthread_work irq_work; /* kthread work entry */ | ||
671 | spinlock_t dma_reg_lock; /* lock access to DMA engine registers */ | ||
672 | int cur_dma_stream; /* index of current stream doing DMA (-1 if none) */ | ||
673 | int cur_pio_stream; /* index of current stream doing PIO (-1 if none) */ | ||
674 | u32 dma_data_req_offset; /* store offset in decoder memory of current DMA request */ | ||
675 | u32 dma_data_req_size; /* store size of current DMA request */ | ||
676 | int dma_retries; /* current DMA retry attempt */ | ||
677 | struct ivtv_user_dma udma; /* user based DMA for OSD */ | ||
678 | struct timer_list dma_timer; /* timer used to catch unfinished DMAs */ | ||
679 | u32 last_vsync_field; /* last seen vsync field */ | ||
680 | wait_queue_head_t dma_waitq; /* wake up when the current DMA is finished */ | ||
681 | wait_queue_head_t eos_waitq; /* wake up when EOS arrives */ | ||
682 | wait_queue_head_t event_waitq; /* wake up when the next decoder event arrives */ | ||
683 | wait_queue_head_t vsync_waitq; /* wake up when the next decoder vsync arrives */ | ||
684 | |||
685 | |||
686 | /* Mailbox */ | ||
687 | struct ivtv_mailbox_data enc_mbox; /* encoder mailboxes */ | ||
688 | struct ivtv_mailbox_data dec_mbox; /* decoder mailboxes */ | ||
689 | struct ivtv_api_cache api_cache[256]; /* cached API commands */ | ||
690 | |||
691 | |||
692 | /* I2C */ | ||
693 | struct i2c_adapter i2c_adap; | ||
694 | struct i2c_algo_bit_data i2c_algo; | ||
695 | struct i2c_client i2c_client; | ||
696 | int i2c_state; /* i2c bit state */ | ||
697 | struct mutex i2c_bus_lock; /* lock i2c bus */ | ||
698 | |||
699 | struct IR_i2c_init_data ir_i2c_init_data; | ||
700 | |||
701 | /* Program Index information */ | ||
702 | u32 pgm_info_offset; /* start of pgm info in encoder memory */ | ||
703 | u32 pgm_info_num; /* number of elements in the pgm cyclic buffer in encoder memory */ | ||
704 | u32 pgm_info_write_idx; /* last index written by the card that was transferred to pgm_info[] */ | ||
705 | u32 pgm_info_read_idx; /* last index in pgm_info read by the application */ | ||
706 | struct v4l2_enc_idx_entry pgm_info[IVTV_MAX_PGM_INDEX]; /* filled from the pgm cyclic buffer on the card */ | ||
707 | |||
708 | |||
709 | /* Miscellaneous */ | ||
710 | u32 open_id; /* incremented each time an open occurs, is >= 1 */ | ||
711 | int search_pack_header; /* 1 if ivtv_copy_buf_to_user() is scanning for a pack header (0xba) */ | ||
712 | int speed; /* current playback speed setting */ | ||
713 | u8 speed_mute_audio; /* 1 if audio should be muted when fast forward */ | ||
714 | u64 mpg_data_received; /* number of bytes received from the MPEG stream */ | ||
715 | u64 vbi_data_inserted; /* number of VBI bytes inserted into the MPEG stream */ | ||
716 | u32 last_dec_timing[3]; /* cache last retrieved pts/scr/frame values */ | ||
717 | unsigned long dualwatch_jiffies;/* jiffies value of the previous dualwatch check */ | ||
718 | u32 dualwatch_stereo_mode; /* current detected dualwatch stereo mode */ | ||
719 | |||
720 | |||
721 | /* VBI state info */ | ||
722 | struct vbi_info vbi; /* VBI-specific data */ | ||
723 | |||
724 | |||
725 | /* YUV playback */ | ||
726 | struct yuv_playback_info yuv_info; /* YUV playback data */ | ||
727 | |||
728 | |||
729 | /* OSD support */ | ||
730 | unsigned long osd_video_pbase; | ||
731 | int osd_global_alpha_state; /* 1 = global alpha is on */ | ||
732 | int osd_local_alpha_state; /* 1 = local alpha is on */ | ||
733 | int osd_chroma_key_state; /* 1 = chroma-keying is on */ | ||
734 | u8 osd_global_alpha; /* current global alpha */ | ||
735 | u32 osd_chroma_key; /* current chroma key */ | ||
736 | struct v4l2_rect osd_rect; /* current OSD position and size */ | ||
737 | struct v4l2_rect main_rect; /* current Main window position and size */ | ||
738 | struct osd_info *osd_info; /* ivtvfb private OSD info */ | ||
739 | void (*ivtvfb_restore)(struct ivtv *itv); /* Used for a warm start */ | ||
740 | }; | ||
741 | |||
742 | static inline struct ivtv *to_ivtv(struct v4l2_device *v4l2_dev) | ||
743 | { | ||
744 | return container_of(v4l2_dev, struct ivtv, v4l2_dev); | ||
745 | } | ||
746 | |||
747 | /* Globals */ | ||
748 | extern int ivtv_first_minor; | ||
749 | |||
750 | /*==============Prototypes==================*/ | ||
751 | |||
752 | /* Hardware/IRQ */ | ||
753 | void ivtv_set_irq_mask(struct ivtv *itv, u32 mask); | ||
754 | void ivtv_clear_irq_mask(struct ivtv *itv, u32 mask); | ||
755 | |||
756 | /* try to set output mode, return current mode. */ | ||
757 | int ivtv_set_output_mode(struct ivtv *itv, int mode); | ||
758 | |||
759 | /* return current output stream based on current mode */ | ||
760 | struct ivtv_stream *ivtv_get_output_stream(struct ivtv *itv); | ||
761 | |||
762 | /* Return non-zero if a signal is pending */ | ||
763 | int ivtv_msleep_timeout(unsigned int msecs, int intr); | ||
764 | |||
765 | /* Wait on queue, returns -EINTR if interrupted */ | ||
766 | int ivtv_waitq(wait_queue_head_t *waitq); | ||
767 | |||
768 | /* Read Hauppauge eeprom */ | ||
769 | struct tveeprom; /* forward reference */ | ||
770 | void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv); | ||
771 | |||
772 | /* First-open initialization: load firmware, init cx25840, etc. */ | ||
773 | int ivtv_init_on_first_open(struct ivtv *itv); | ||
774 | |||
775 | /* Test if the current VBI mode is raw (1) or sliced (0) */ | ||
776 | static inline int ivtv_raw_vbi(const struct ivtv *itv) | ||
777 | { | ||
778 | return itv->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE; | ||
779 | } | ||
780 | |||
781 | /* This is a PCI post thing, where if the pci register is not read, then | ||
782 | the write doesn't always take effect right away. By reading back the | ||
783 | register any pending PCI writes will be performed (in order), and so | ||
784 | you can be sure that the writes are guaranteed to be done. | ||
785 | |||
786 | Rarely needed, only in some timing sensitive cases. | ||
787 | Apparently if this is not done some motherboards seem | ||
788 | to kill the firmware and get into the broken state until computer is | ||
789 | rebooted. */ | ||
790 | #define write_sync(val, reg) \ | ||
791 | do { writel(val, reg); readl(reg); } while (0) | ||
792 | |||
793 | #define read_reg(reg) readl(itv->reg_mem + (reg)) | ||
794 | #define write_reg(val, reg) writel(val, itv->reg_mem + (reg)) | ||
795 | #define write_reg_sync(val, reg) \ | ||
796 | do { write_reg(val, reg); read_reg(reg); } while (0) | ||
797 | |||
798 | #define read_enc(addr) readl(itv->enc_mem + (u32)(addr)) | ||
799 | #define write_enc(val, addr) writel(val, itv->enc_mem + (u32)(addr)) | ||
800 | #define write_enc_sync(val, addr) \ | ||
801 | do { write_enc(val, addr); read_enc(addr); } while (0) | ||
802 | |||
803 | #define read_dec(addr) readl(itv->dec_mem + (u32)(addr)) | ||
804 | #define write_dec(val, addr) writel(val, itv->dec_mem + (u32)(addr)) | ||
805 | #define write_dec_sync(val, addr) \ | ||
806 | do { write_dec(val, addr); read_dec(addr); } while (0) | ||
807 | |||
808 | /* Call the specified callback for all subdevs matching hw (if 0, then | ||
809 | match them all). Ignore any errors. */ | ||
810 | #define ivtv_call_hw(itv, hw, o, f, args...) \ | ||
811 | do { \ | ||
812 | struct v4l2_subdev *__sd; \ | ||
813 | __v4l2_device_call_subdevs_p(&(itv)->v4l2_dev, __sd, \ | ||
814 | !(hw) || (__sd->grp_id & (hw)), o, f , ##args); \ | ||
815 | } while (0) | ||
816 | |||
817 | #define ivtv_call_all(itv, o, f, args...) ivtv_call_hw(itv, 0, o, f , ##args) | ||
818 | |||
819 | /* Call the specified callback for all subdevs matching hw (if 0, then | ||
820 | match them all). If the callback returns an error other than 0 or | ||
821 | -ENOIOCTLCMD, then return with that error code. */ | ||
822 | #define ivtv_call_hw_err(itv, hw, o, f, args...) \ | ||
823 | ({ \ | ||
824 | struct v4l2_subdev *__sd; \ | ||
825 | __v4l2_device_call_subdevs_until_err_p(&(itv)->v4l2_dev, __sd, \ | ||
826 | !(hw) || (__sd->grp_id & (hw)), o, f , ##args); \ | ||
827 | }) | ||
828 | |||
829 | #define ivtv_call_all_err(itv, o, f, args...) ivtv_call_hw_err(itv, 0, o, f , ##args) | ||
830 | |||
831 | #endif | ||
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c new file mode 100644 index 00000000000..38f052257f4 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
@@ -0,0 +1,1066 @@ | |||
1 | /* | ||
2 | file operation functions | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2004 Chris Kennedy <c@groovy.org> | ||
5 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include "ivtv-driver.h" | ||
23 | #include "ivtv-fileops.h" | ||
24 | #include "ivtv-i2c.h" | ||
25 | #include "ivtv-queue.h" | ||
26 | #include "ivtv-udma.h" | ||
27 | #include "ivtv-irq.h" | ||
28 | #include "ivtv-vbi.h" | ||
29 | #include "ivtv-mailbox.h" | ||
30 | #include "ivtv-routing.h" | ||
31 | #include "ivtv-streams.h" | ||
32 | #include "ivtv-yuv.h" | ||
33 | #include "ivtv-ioctl.h" | ||
34 | #include "ivtv-cards.h" | ||
35 | #include "ivtv-firmware.h" | ||
36 | #include <media/v4l2-event.h> | ||
37 | #include <media/saa7115.h> | ||
38 | |||
39 | /* This function tries to claim the stream for a specific file descriptor. | ||
40 | If no one else is using this stream then the stream is claimed and | ||
41 | associated VBI streams are also automatically claimed. | ||
42 | Possible error returns: -EBUSY if someone else has claimed | ||
43 | the stream or 0 on success. */ | ||
44 | static int ivtv_claim_stream(struct ivtv_open_id *id, int type) | ||
45 | { | ||
46 | struct ivtv *itv = id->itv; | ||
47 | struct ivtv_stream *s = &itv->streams[type]; | ||
48 | struct ivtv_stream *s_vbi; | ||
49 | int vbi_type; | ||
50 | |||
51 | if (test_and_set_bit(IVTV_F_S_CLAIMED, &s->s_flags)) { | ||
52 | /* someone already claimed this stream */ | ||
53 | if (s->id == id->open_id) { | ||
54 | /* yes, this file descriptor did. So that's OK. */ | ||
55 | return 0; | ||
56 | } | ||
57 | if (s->id == -1 && (type == IVTV_DEC_STREAM_TYPE_VBI || | ||
58 | type == IVTV_ENC_STREAM_TYPE_VBI)) { | ||
59 | /* VBI is handled already internally, now also assign | ||
60 | the file descriptor to this stream for external | ||
61 | reading of the stream. */ | ||
62 | s->id = id->open_id; | ||
63 | IVTV_DEBUG_INFO("Start Read VBI\n"); | ||
64 | return 0; | ||
65 | } | ||
66 | /* someone else is using this stream already */ | ||
67 | IVTV_DEBUG_INFO("Stream %d is busy\n", type); | ||
68 | return -EBUSY; | ||
69 | } | ||
70 | s->id = id->open_id; | ||
71 | if (type == IVTV_DEC_STREAM_TYPE_VBI) { | ||
72 | /* Enable reinsertion interrupt */ | ||
73 | ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT); | ||
74 | } | ||
75 | |||
76 | /* IVTV_DEC_STREAM_TYPE_MPG needs to claim IVTV_DEC_STREAM_TYPE_VBI, | ||
77 | IVTV_ENC_STREAM_TYPE_MPG needs to claim IVTV_ENC_STREAM_TYPE_VBI | ||
78 | (provided VBI insertion is on and sliced VBI is selected), for all | ||
79 | other streams we're done */ | ||
80 | if (type == IVTV_DEC_STREAM_TYPE_MPG) { | ||
81 | vbi_type = IVTV_DEC_STREAM_TYPE_VBI; | ||
82 | } else if (type == IVTV_ENC_STREAM_TYPE_MPG && | ||
83 | itv->vbi.insert_mpeg && !ivtv_raw_vbi(itv)) { | ||
84 | vbi_type = IVTV_ENC_STREAM_TYPE_VBI; | ||
85 | } else { | ||
86 | return 0; | ||
87 | } | ||
88 | s_vbi = &itv->streams[vbi_type]; | ||
89 | |||
90 | if (!test_and_set_bit(IVTV_F_S_CLAIMED, &s_vbi->s_flags)) { | ||
91 | /* Enable reinsertion interrupt */ | ||
92 | if (vbi_type == IVTV_DEC_STREAM_TYPE_VBI) | ||
93 | ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT); | ||
94 | } | ||
95 | /* mark that it is used internally */ | ||
96 | set_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags); | ||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | /* This function releases a previously claimed stream. It will take into | ||
101 | account associated VBI streams. */ | ||
102 | void ivtv_release_stream(struct ivtv_stream *s) | ||
103 | { | ||
104 | struct ivtv *itv = s->itv; | ||
105 | struct ivtv_stream *s_vbi; | ||
106 | |||
107 | s->id = -1; | ||
108 | if ((s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type == IVTV_ENC_STREAM_TYPE_VBI) && | ||
109 | test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) { | ||
110 | /* this stream is still in use internally */ | ||
111 | return; | ||
112 | } | ||
113 | if (!test_and_clear_bit(IVTV_F_S_CLAIMED, &s->s_flags)) { | ||
114 | IVTV_DEBUG_WARN("Release stream %s not in use!\n", s->name); | ||
115 | return; | ||
116 | } | ||
117 | |||
118 | ivtv_flush_queues(s); | ||
119 | |||
120 | /* disable reinsertion interrupt */ | ||
121 | if (s->type == IVTV_DEC_STREAM_TYPE_VBI) | ||
122 | ivtv_set_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT); | ||
123 | |||
124 | /* IVTV_DEC_STREAM_TYPE_MPG needs to release IVTV_DEC_STREAM_TYPE_VBI, | ||
125 | IVTV_ENC_STREAM_TYPE_MPG needs to release IVTV_ENC_STREAM_TYPE_VBI, | ||
126 | for all other streams we're done */ | ||
127 | if (s->type == IVTV_DEC_STREAM_TYPE_MPG) | ||
128 | s_vbi = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI]; | ||
129 | else if (s->type == IVTV_ENC_STREAM_TYPE_MPG) | ||
130 | s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; | ||
131 | else | ||
132 | return; | ||
133 | |||
134 | /* clear internal use flag */ | ||
135 | if (!test_and_clear_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags)) { | ||
136 | /* was already cleared */ | ||
137 | return; | ||
138 | } | ||
139 | if (s_vbi->id != -1) { | ||
140 | /* VBI stream still claimed by a file descriptor */ | ||
141 | return; | ||
142 | } | ||
143 | /* disable reinsertion interrupt */ | ||
144 | if (s_vbi->type == IVTV_DEC_STREAM_TYPE_VBI) | ||
145 | ivtv_set_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT); | ||
146 | clear_bit(IVTV_F_S_CLAIMED, &s_vbi->s_flags); | ||
147 | ivtv_flush_queues(s_vbi); | ||
148 | } | ||
149 | |||
150 | static void ivtv_dualwatch(struct ivtv *itv) | ||
151 | { | ||
152 | struct v4l2_tuner vt; | ||
153 | u32 new_stereo_mode; | ||
154 | const u32 dual = 0x02; | ||
155 | |||
156 | new_stereo_mode = v4l2_ctrl_g_ctrl(itv->cxhdl.audio_mode); | ||
157 | memset(&vt, 0, sizeof(vt)); | ||
158 | ivtv_call_all(itv, tuner, g_tuner, &vt); | ||
159 | if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 && (vt.rxsubchans & V4L2_TUNER_SUB_LANG2)) | ||
160 | new_stereo_mode = dual; | ||
161 | |||
162 | if (new_stereo_mode == itv->dualwatch_stereo_mode) | ||
163 | return; | ||
164 | |||
165 | IVTV_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x.\n", | ||
166 | itv->dualwatch_stereo_mode, new_stereo_mode); | ||
167 | if (v4l2_ctrl_s_ctrl(itv->cxhdl.audio_mode, new_stereo_mode)) | ||
168 | IVTV_DEBUG_INFO("dualwatch: changing stereo flag failed\n"); | ||
169 | } | ||
170 | |||
171 | static void ivtv_update_pgm_info(struct ivtv *itv) | ||
172 | { | ||
173 | u32 wr_idx = (read_enc(itv->pgm_info_offset) - itv->pgm_info_offset - 4) / 24; | ||
174 | int cnt; | ||
175 | int i = 0; | ||
176 | |||
177 | if (wr_idx >= itv->pgm_info_num) { | ||
178 | IVTV_DEBUG_WARN("Invalid PGM index %d (>= %d)\n", wr_idx, itv->pgm_info_num); | ||
179 | return; | ||
180 | } | ||
181 | cnt = (wr_idx + itv->pgm_info_num - itv->pgm_info_write_idx) % itv->pgm_info_num; | ||
182 | while (i < cnt) { | ||
183 | int idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num; | ||
184 | struct v4l2_enc_idx_entry *e = itv->pgm_info + idx; | ||
185 | u32 addr = itv->pgm_info_offset + 4 + idx * 24; | ||
186 | const int mapping[8] = { -1, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_P, -1, | ||
187 | V4L2_ENC_IDX_FRAME_B, -1, -1, -1 }; | ||
188 | // 1=I, 2=P, 4=B | ||
189 | |||
190 | e->offset = read_enc(addr + 4) + ((u64)read_enc(addr + 8) << 32); | ||
191 | if (e->offset > itv->mpg_data_received) { | ||
192 | break; | ||
193 | } | ||
194 | e->offset += itv->vbi_data_inserted; | ||
195 | e->length = read_enc(addr); | ||
196 | e->pts = read_enc(addr + 16) + ((u64)(read_enc(addr + 20) & 1) << 32); | ||
197 | e->flags = mapping[read_enc(addr + 12) & 7]; | ||
198 | i++; | ||
199 | } | ||
200 | itv->pgm_info_write_idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num; | ||
201 | } | ||
202 | |||
203 | static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block, int *err) | ||
204 | { | ||
205 | struct ivtv *itv = s->itv; | ||
206 | struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; | ||
207 | struct ivtv_buffer *buf; | ||
208 | DEFINE_WAIT(wait); | ||
209 | |||
210 | *err = 0; | ||
211 | while (1) { | ||
212 | if (s->type == IVTV_ENC_STREAM_TYPE_MPG) { | ||
213 | /* Process pending program info updates and pending VBI data */ | ||
214 | ivtv_update_pgm_info(itv); | ||
215 | |||
216 | if (time_after(jiffies, | ||
217 | itv->dualwatch_jiffies + | ||
218 | msecs_to_jiffies(1000))) { | ||
219 | itv->dualwatch_jiffies = jiffies; | ||
220 | ivtv_dualwatch(itv); | ||
221 | } | ||
222 | |||
223 | if (test_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags) && | ||
224 | !test_bit(IVTV_F_S_APPL_IO, &s_vbi->s_flags)) { | ||
225 | while ((buf = ivtv_dequeue(s_vbi, &s_vbi->q_full))) { | ||
226 | /* byteswap and process VBI data */ | ||
227 | ivtv_process_vbi_data(itv, buf, s_vbi->dma_pts, s_vbi->type); | ||
228 | ivtv_enqueue(s_vbi, buf, &s_vbi->q_free); | ||
229 | } | ||
230 | } | ||
231 | buf = &itv->vbi.sliced_mpeg_buf; | ||
232 | if (buf->readpos != buf->bytesused) { | ||
233 | return buf; | ||
234 | } | ||
235 | } | ||
236 | |||
237 | /* do we have leftover data? */ | ||
238 | buf = ivtv_dequeue(s, &s->q_io); | ||
239 | if (buf) | ||
240 | return buf; | ||
241 | |||
242 | /* do we have new data? */ | ||
243 | buf = ivtv_dequeue(s, &s->q_full); | ||
244 | if (buf) { | ||
245 | if ((buf->b_flags & IVTV_F_B_NEED_BUF_SWAP) == 0) | ||
246 | return buf; | ||
247 | buf->b_flags &= ~IVTV_F_B_NEED_BUF_SWAP; | ||
248 | if (s->type == IVTV_ENC_STREAM_TYPE_MPG) | ||
249 | /* byteswap MPG data */ | ||
250 | ivtv_buf_swap(buf); | ||
251 | else if (s->type != IVTV_DEC_STREAM_TYPE_VBI) { | ||
252 | /* byteswap and process VBI data */ | ||
253 | ivtv_process_vbi_data(itv, buf, s->dma_pts, s->type); | ||
254 | } | ||
255 | return buf; | ||
256 | } | ||
257 | |||
258 | /* return if end of stream */ | ||
259 | if (s->type != IVTV_DEC_STREAM_TYPE_VBI && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { | ||
260 | IVTV_DEBUG_INFO("EOS %s\n", s->name); | ||
261 | return NULL; | ||
262 | } | ||
263 | |||
264 | /* return if file was opened with O_NONBLOCK */ | ||
265 | if (non_block) { | ||
266 | *err = -EAGAIN; | ||
267 | return NULL; | ||
268 | } | ||
269 | |||
270 | /* wait for more data to arrive */ | ||
271 | prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); | ||
272 | /* New buffers might have become available before we were added to the waitqueue */ | ||
273 | if (!s->q_full.buffers) | ||
274 | schedule(); | ||
275 | finish_wait(&s->waitq, &wait); | ||
276 | if (signal_pending(current)) { | ||
277 | /* return if a signal was received */ | ||
278 | IVTV_DEBUG_INFO("User stopped %s\n", s->name); | ||
279 | *err = -EINTR; | ||
280 | return NULL; | ||
281 | } | ||
282 | } | ||
283 | } | ||
284 | |||
285 | static void ivtv_setup_sliced_vbi_buf(struct ivtv *itv) | ||
286 | { | ||
287 | int idx = itv->vbi.inserted_frame % IVTV_VBI_FRAMES; | ||
288 | |||
289 | itv->vbi.sliced_mpeg_buf.buf = itv->vbi.sliced_mpeg_data[idx]; | ||
290 | itv->vbi.sliced_mpeg_buf.bytesused = itv->vbi.sliced_mpeg_size[idx]; | ||
291 | itv->vbi.sliced_mpeg_buf.readpos = 0; | ||
292 | } | ||
293 | |||
294 | static size_t ivtv_copy_buf_to_user(struct ivtv_stream *s, struct ivtv_buffer *buf, | ||
295 | char __user *ubuf, size_t ucount) | ||
296 | { | ||
297 | struct ivtv *itv = s->itv; | ||
298 | size_t len = buf->bytesused - buf->readpos; | ||
299 | |||
300 | if (len > ucount) len = ucount; | ||
301 | if (itv->vbi.insert_mpeg && s->type == IVTV_ENC_STREAM_TYPE_MPG && | ||
302 | !ivtv_raw_vbi(itv) && buf != &itv->vbi.sliced_mpeg_buf) { | ||
303 | const char *start = buf->buf + buf->readpos; | ||
304 | const char *p = start + 1; | ||
305 | const u8 *q; | ||
306 | u8 ch = itv->search_pack_header ? 0xba : 0xe0; | ||
307 | int stuffing, i; | ||
308 | |||
309 | while (start + len > p && (q = memchr(p, 0, start + len - p))) { | ||
310 | p = q + 1; | ||
311 | if ((char *)q + 15 >= buf->buf + buf->bytesused || | ||
312 | q[1] != 0 || q[2] != 1 || q[3] != ch) { | ||
313 | continue; | ||
314 | } | ||
315 | if (!itv->search_pack_header) { | ||
316 | if ((q[6] & 0xc0) != 0x80) | ||
317 | continue; | ||
318 | if (((q[7] & 0xc0) == 0x80 && (q[9] & 0xf0) == 0x20) || | ||
319 | ((q[7] & 0xc0) == 0xc0 && (q[9] & 0xf0) == 0x30)) { | ||
320 | ch = 0xba; | ||
321 | itv->search_pack_header = 1; | ||
322 | p = q + 9; | ||
323 | } | ||
324 | continue; | ||
325 | } | ||
326 | stuffing = q[13] & 7; | ||
327 | /* all stuffing bytes must be 0xff */ | ||
328 | for (i = 0; i < stuffing; i++) | ||
329 | if (q[14 + i] != 0xff) | ||
330 | break; | ||
331 | if (i == stuffing && (q[4] & 0xc4) == 0x44 && (q[12] & 3) == 3 && | ||
332 | q[14 + stuffing] == 0 && q[15 + stuffing] == 0 && | ||
333 | q[16 + stuffing] == 1) { | ||
334 | itv->search_pack_header = 0; | ||
335 | len = (char *)q - start; | ||
336 | ivtv_setup_sliced_vbi_buf(itv); | ||
337 | break; | ||
338 | } | ||
339 | } | ||
340 | } | ||
341 | if (copy_to_user(ubuf, (u8 *)buf->buf + buf->readpos, len)) { | ||
342 | IVTV_DEBUG_WARN("copy %zd bytes to user failed for %s\n", len, s->name); | ||
343 | return -EFAULT; | ||
344 | } | ||
345 | /*IVTV_INFO("copied %lld %d %d %d %d %d vbi %d\n", itv->mpg_data_received, len, ucount, | ||
346 | buf->readpos, buf->bytesused, buf->bytesused - buf->readpos - len, | ||
347 | buf == &itv->vbi.sliced_mpeg_buf); */ | ||
348 | buf->readpos += len; | ||
349 | if (s->type == IVTV_ENC_STREAM_TYPE_MPG && buf != &itv->vbi.sliced_mpeg_buf) | ||
350 | itv->mpg_data_received += len; | ||
351 | return len; | ||
352 | } | ||
353 | |||
354 | static ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_count, int non_block) | ||
355 | { | ||
356 | struct ivtv *itv = s->itv; | ||
357 | size_t tot_written = 0; | ||
358 | int single_frame = 0; | ||
359 | |||
360 | if (atomic_read(&itv->capturing) == 0 && s->id == -1) { | ||
361 | /* shouldn't happen */ | ||
362 | IVTV_DEBUG_WARN("Stream %s not initialized before read\n", s->name); | ||
363 | return -EIO; | ||
364 | } | ||
365 | |||
366 | /* Each VBI buffer is one frame, the v4l2 API says that for VBI the frames should | ||
367 | arrive one-by-one, so make sure we never output more than one VBI frame at a time */ | ||
368 | if (s->type == IVTV_DEC_STREAM_TYPE_VBI || | ||
369 | (s->type == IVTV_ENC_STREAM_TYPE_VBI && !ivtv_raw_vbi(itv))) | ||
370 | single_frame = 1; | ||
371 | |||
372 | for (;;) { | ||
373 | struct ivtv_buffer *buf; | ||
374 | int rc; | ||
375 | |||
376 | buf = ivtv_get_buffer(s, non_block, &rc); | ||
377 | /* if there is no data available... */ | ||
378 | if (buf == NULL) { | ||
379 | /* if we got data, then return that regardless */ | ||
380 | if (tot_written) | ||
381 | break; | ||
382 | /* EOS condition */ | ||
383 | if (rc == 0) { | ||
384 | clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags); | ||
385 | clear_bit(IVTV_F_S_APPL_IO, &s->s_flags); | ||
386 | ivtv_release_stream(s); | ||
387 | } | ||
388 | /* set errno */ | ||
389 | return rc; | ||
390 | } | ||
391 | rc = ivtv_copy_buf_to_user(s, buf, ubuf + tot_written, tot_count - tot_written); | ||
392 | if (buf != &itv->vbi.sliced_mpeg_buf) { | ||
393 | ivtv_enqueue(s, buf, (buf->readpos == buf->bytesused) ? &s->q_free : &s->q_io); | ||
394 | } | ||
395 | else if (buf->readpos == buf->bytesused) { | ||
396 | int idx = itv->vbi.inserted_frame % IVTV_VBI_FRAMES; | ||
397 | itv->vbi.sliced_mpeg_size[idx] = 0; | ||
398 | itv->vbi.inserted_frame++; | ||
399 | itv->vbi_data_inserted += buf->bytesused; | ||
400 | } | ||
401 | if (rc < 0) | ||
402 | return rc; | ||
403 | tot_written += rc; | ||
404 | |||
405 | if (tot_written == tot_count || single_frame) | ||
406 | break; | ||
407 | } | ||
408 | return tot_written; | ||
409 | } | ||
410 | |||
411 | static ssize_t ivtv_read_pos(struct ivtv_stream *s, char __user *ubuf, size_t count, | ||
412 | loff_t *pos, int non_block) | ||
413 | { | ||
414 | ssize_t rc = count ? ivtv_read(s, ubuf, count, non_block) : 0; | ||
415 | struct ivtv *itv = s->itv; | ||
416 | |||
417 | IVTV_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc); | ||
418 | if (rc > 0) | ||
419 | pos += rc; | ||
420 | return rc; | ||
421 | } | ||
422 | |||
423 | int ivtv_start_capture(struct ivtv_open_id *id) | ||
424 | { | ||
425 | struct ivtv *itv = id->itv; | ||
426 | struct ivtv_stream *s = &itv->streams[id->type]; | ||
427 | struct ivtv_stream *s_vbi; | ||
428 | |||
429 | if (s->type == IVTV_ENC_STREAM_TYPE_RAD || | ||
430 | s->type == IVTV_DEC_STREAM_TYPE_MPG || | ||
431 | s->type == IVTV_DEC_STREAM_TYPE_YUV || | ||
432 | s->type == IVTV_DEC_STREAM_TYPE_VOUT) { | ||
433 | /* you cannot read from these stream types. */ | ||
434 | return -EPERM; | ||
435 | } | ||
436 | |||
437 | /* Try to claim this stream. */ | ||
438 | if (ivtv_claim_stream(id, s->type)) | ||
439 | return -EBUSY; | ||
440 | |||
441 | /* This stream does not need to start capturing */ | ||
442 | if (s->type == IVTV_DEC_STREAM_TYPE_VBI) { | ||
443 | set_bit(IVTV_F_S_APPL_IO, &s->s_flags); | ||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | /* If capture is already in progress, then we also have to | ||
448 | do nothing extra. */ | ||
449 | if (test_bit(IVTV_F_S_STREAMOFF, &s->s_flags) || test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags)) { | ||
450 | set_bit(IVTV_F_S_APPL_IO, &s->s_flags); | ||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | /* Start VBI capture if required */ | ||
455 | s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; | ||
456 | if (s->type == IVTV_ENC_STREAM_TYPE_MPG && | ||
457 | test_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags) && | ||
458 | !test_and_set_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags)) { | ||
459 | /* Note: the IVTV_ENC_STREAM_TYPE_VBI is claimed | ||
460 | automatically when the MPG stream is claimed. | ||
461 | We only need to start the VBI capturing. */ | ||
462 | if (ivtv_start_v4l2_encode_stream(s_vbi)) { | ||
463 | IVTV_DEBUG_WARN("VBI capture start failed\n"); | ||
464 | |||
465 | /* Failure, clean up and return an error */ | ||
466 | clear_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags); | ||
467 | clear_bit(IVTV_F_S_STREAMING, &s->s_flags); | ||
468 | /* also releases the associated VBI stream */ | ||
469 | ivtv_release_stream(s); | ||
470 | return -EIO; | ||
471 | } | ||
472 | IVTV_DEBUG_INFO("VBI insertion started\n"); | ||
473 | } | ||
474 | |||
475 | /* Tell the card to start capturing */ | ||
476 | if (!ivtv_start_v4l2_encode_stream(s)) { | ||
477 | /* We're done */ | ||
478 | set_bit(IVTV_F_S_APPL_IO, &s->s_flags); | ||
479 | /* Resume a possibly paused encoder */ | ||
480 | if (test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags)) | ||
481 | ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1); | ||
482 | return 0; | ||
483 | } | ||
484 | |||
485 | /* failure, clean up */ | ||
486 | IVTV_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name); | ||
487 | |||
488 | /* Note: the IVTV_ENC_STREAM_TYPE_VBI is released | ||
489 | automatically when the MPG stream is released. | ||
490 | We only need to stop the VBI capturing. */ | ||
491 | if (s->type == IVTV_ENC_STREAM_TYPE_MPG && | ||
492 | test_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags)) { | ||
493 | ivtv_stop_v4l2_encode_stream(s_vbi, 0); | ||
494 | clear_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags); | ||
495 | } | ||
496 | clear_bit(IVTV_F_S_STREAMING, &s->s_flags); | ||
497 | ivtv_release_stream(s); | ||
498 | return -EIO; | ||
499 | } | ||
500 | |||
501 | ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_t * pos) | ||
502 | { | ||
503 | struct ivtv_open_id *id = fh2id(filp->private_data); | ||
504 | struct ivtv *itv = id->itv; | ||
505 | struct ivtv_stream *s = &itv->streams[id->type]; | ||
506 | int rc; | ||
507 | |||
508 | IVTV_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name); | ||
509 | |||
510 | mutex_lock(&itv->serialize_lock); | ||
511 | rc = ivtv_start_capture(id); | ||
512 | mutex_unlock(&itv->serialize_lock); | ||
513 | if (rc) | ||
514 | return rc; | ||
515 | return ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK); | ||
516 | } | ||
517 | |||
518 | int ivtv_start_decoding(struct ivtv_open_id *id, int speed) | ||
519 | { | ||
520 | struct ivtv *itv = id->itv; | ||
521 | struct ivtv_stream *s = &itv->streams[id->type]; | ||
522 | int rc; | ||
523 | |||
524 | if (atomic_read(&itv->decoding) == 0) { | ||
525 | if (ivtv_claim_stream(id, s->type)) { | ||
526 | /* someone else is using this stream already */ | ||
527 | IVTV_DEBUG_WARN("start decode, stream already claimed\n"); | ||
528 | return -EBUSY; | ||
529 | } | ||
530 | rc = ivtv_start_v4l2_decode_stream(s, 0); | ||
531 | if (rc < 0) { | ||
532 | if (rc == -EAGAIN) | ||
533 | rc = ivtv_start_v4l2_decode_stream(s, 0); | ||
534 | if (rc < 0) | ||
535 | return rc; | ||
536 | } | ||
537 | } | ||
538 | if (s->type == IVTV_DEC_STREAM_TYPE_MPG) | ||
539 | return ivtv_set_speed(itv, speed); | ||
540 | return 0; | ||
541 | } | ||
542 | |||
543 | ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos) | ||
544 | { | ||
545 | struct ivtv_open_id *id = fh2id(filp->private_data); | ||
546 | struct ivtv *itv = id->itv; | ||
547 | struct ivtv_stream *s = &itv->streams[id->type]; | ||
548 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
549 | struct ivtv_buffer *buf; | ||
550 | struct ivtv_queue q; | ||
551 | int bytes_written = 0; | ||
552 | int mode; | ||
553 | int rc; | ||
554 | DEFINE_WAIT(wait); | ||
555 | |||
556 | IVTV_DEBUG_HI_FILE("write %zd bytes to %s\n", count, s->name); | ||
557 | |||
558 | if (s->type != IVTV_DEC_STREAM_TYPE_MPG && | ||
559 | s->type != IVTV_DEC_STREAM_TYPE_YUV && | ||
560 | s->type != IVTV_DEC_STREAM_TYPE_VOUT) | ||
561 | /* not decoder streams */ | ||
562 | return -EPERM; | ||
563 | |||
564 | /* Try to claim this stream */ | ||
565 | if (ivtv_claim_stream(id, s->type)) | ||
566 | return -EBUSY; | ||
567 | |||
568 | /* This stream does not need to start any decoding */ | ||
569 | if (s->type == IVTV_DEC_STREAM_TYPE_VOUT) { | ||
570 | int elems = count / sizeof(struct v4l2_sliced_vbi_data); | ||
571 | |||
572 | set_bit(IVTV_F_S_APPL_IO, &s->s_flags); | ||
573 | return ivtv_write_vbi_from_user(itv, | ||
574 | (const struct v4l2_sliced_vbi_data __user *)user_buf, elems); | ||
575 | } | ||
576 | |||
577 | mode = s->type == IVTV_DEC_STREAM_TYPE_MPG ? OUT_MPG : OUT_YUV; | ||
578 | |||
579 | if (ivtv_set_output_mode(itv, mode) != mode) { | ||
580 | ivtv_release_stream(s); | ||
581 | return -EBUSY; | ||
582 | } | ||
583 | ivtv_queue_init(&q); | ||
584 | set_bit(IVTV_F_S_APPL_IO, &s->s_flags); | ||
585 | |||
586 | /* Start decoder (returns 0 if already started) */ | ||
587 | mutex_lock(&itv->serialize_lock); | ||
588 | rc = ivtv_start_decoding(id, itv->speed); | ||
589 | mutex_unlock(&itv->serialize_lock); | ||
590 | if (rc) { | ||
591 | IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name); | ||
592 | |||
593 | /* failure, clean up */ | ||
594 | clear_bit(IVTV_F_S_STREAMING, &s->s_flags); | ||
595 | clear_bit(IVTV_F_S_APPL_IO, &s->s_flags); | ||
596 | return rc; | ||
597 | } | ||
598 | |||
599 | retry: | ||
600 | /* If possible, just DMA the entire frame - Check the data transfer size | ||
601 | since we may get here before the stream has been fully set-up */ | ||
602 | if (mode == OUT_YUV && s->q_full.length == 0 && itv->dma_data_req_size) { | ||
603 | while (count >= itv->dma_data_req_size) { | ||
604 | rc = ivtv_yuv_udma_stream_frame(itv, (void __user *)user_buf); | ||
605 | |||
606 | if (rc < 0) | ||
607 | return rc; | ||
608 | |||
609 | bytes_written += itv->dma_data_req_size; | ||
610 | user_buf += itv->dma_data_req_size; | ||
611 | count -= itv->dma_data_req_size; | ||
612 | } | ||
613 | if (count == 0) { | ||
614 | IVTV_DEBUG_HI_FILE("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused); | ||
615 | return bytes_written; | ||
616 | } | ||
617 | } | ||
618 | |||
619 | for (;;) { | ||
620 | /* Gather buffers */ | ||
621 | while (q.length - q.bytesused < count && (buf = ivtv_dequeue(s, &s->q_io))) | ||
622 | ivtv_enqueue(s, buf, &q); | ||
623 | while (q.length - q.bytesused < count && (buf = ivtv_dequeue(s, &s->q_free))) { | ||
624 | ivtv_enqueue(s, buf, &q); | ||
625 | } | ||
626 | if (q.buffers) | ||
627 | break; | ||
628 | if (filp->f_flags & O_NONBLOCK) | ||
629 | return -EAGAIN; | ||
630 | prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); | ||
631 | /* New buffers might have become free before we were added to the waitqueue */ | ||
632 | if (!s->q_free.buffers) | ||
633 | schedule(); | ||
634 | finish_wait(&s->waitq, &wait); | ||
635 | if (signal_pending(current)) { | ||
636 | IVTV_DEBUG_INFO("User stopped %s\n", s->name); | ||
637 | return -EINTR; | ||
638 | } | ||
639 | } | ||
640 | |||
641 | /* copy user data into buffers */ | ||
642 | while ((buf = ivtv_dequeue(s, &q))) { | ||
643 | /* yuv is a pain. Don't copy more data than needed for a single | ||
644 | frame, otherwise we lose sync with the incoming stream */ | ||
645 | if (s->type == IVTV_DEC_STREAM_TYPE_YUV && | ||
646 | yi->stream_size + count > itv->dma_data_req_size) | ||
647 | rc = ivtv_buf_copy_from_user(s, buf, user_buf, | ||
648 | itv->dma_data_req_size - yi->stream_size); | ||
649 | else | ||
650 | rc = ivtv_buf_copy_from_user(s, buf, user_buf, count); | ||
651 | |||
652 | /* Make sure we really got all the user data */ | ||
653 | if (rc < 0) { | ||
654 | ivtv_queue_move(s, &q, NULL, &s->q_free, 0); | ||
655 | return rc; | ||
656 | } | ||
657 | user_buf += rc; | ||
658 | count -= rc; | ||
659 | bytes_written += rc; | ||
660 | |||
661 | if (s->type == IVTV_DEC_STREAM_TYPE_YUV) { | ||
662 | yi->stream_size += rc; | ||
663 | /* If we have a complete yuv frame, break loop now */ | ||
664 | if (yi->stream_size == itv->dma_data_req_size) { | ||
665 | ivtv_enqueue(s, buf, &s->q_full); | ||
666 | yi->stream_size = 0; | ||
667 | break; | ||
668 | } | ||
669 | } | ||
670 | |||
671 | if (buf->bytesused != s->buf_size) { | ||
672 | /* incomplete, leave in q_io for next time */ | ||
673 | ivtv_enqueue(s, buf, &s->q_io); | ||
674 | break; | ||
675 | } | ||
676 | /* Byteswap MPEG buffer */ | ||
677 | if (s->type == IVTV_DEC_STREAM_TYPE_MPG) | ||
678 | ivtv_buf_swap(buf); | ||
679 | ivtv_enqueue(s, buf, &s->q_full); | ||
680 | } | ||
681 | |||
682 | if (test_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags)) { | ||
683 | if (s->q_full.length >= itv->dma_data_req_size) { | ||
684 | int got_sig; | ||
685 | |||
686 | if (mode == OUT_YUV) | ||
687 | ivtv_yuv_setup_stream_frame(itv); | ||
688 | |||
689 | prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); | ||
690 | while (!(got_sig = signal_pending(current)) && | ||
691 | test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags)) { | ||
692 | schedule(); | ||
693 | } | ||
694 | finish_wait(&itv->dma_waitq, &wait); | ||
695 | if (got_sig) { | ||
696 | IVTV_DEBUG_INFO("User interrupted %s\n", s->name); | ||
697 | return -EINTR; | ||
698 | } | ||
699 | |||
700 | clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags); | ||
701 | ivtv_queue_move(s, &s->q_full, NULL, &s->q_predma, itv->dma_data_req_size); | ||
702 | ivtv_dma_stream_dec_prepare(s, itv->dma_data_req_offset + IVTV_DECODER_OFFSET, 1); | ||
703 | } | ||
704 | } | ||
705 | /* more user data is available, wait until buffers become free | ||
706 | to transfer the rest. */ | ||
707 | if (count && !(filp->f_flags & O_NONBLOCK)) | ||
708 | goto retry; | ||
709 | IVTV_DEBUG_HI_FILE("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused); | ||
710 | return bytes_written; | ||
711 | } | ||
712 | |||
713 | unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait) | ||
714 | { | ||
715 | struct ivtv_open_id *id = fh2id(filp->private_data); | ||
716 | struct ivtv *itv = id->itv; | ||
717 | struct ivtv_stream *s = &itv->streams[id->type]; | ||
718 | int res = 0; | ||
719 | |||
720 | /* add stream's waitq to the poll list */ | ||
721 | IVTV_DEBUG_HI_FILE("Decoder poll\n"); | ||
722 | |||
723 | /* If there are subscribed events, then only use the new event | ||
724 | API instead of the old video.h based API. */ | ||
725 | if (!list_empty(&id->fh.subscribed)) { | ||
726 | poll_wait(filp, &id->fh.wait, wait); | ||
727 | /* Turn off the old-style vsync events */ | ||
728 | clear_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags); | ||
729 | if (v4l2_event_pending(&id->fh)) | ||
730 | res = POLLPRI; | ||
731 | } else { | ||
732 | /* This is the old-style API which is here only for backwards | ||
733 | compatibility. */ | ||
734 | poll_wait(filp, &s->waitq, wait); | ||
735 | set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags); | ||
736 | if (test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags) || | ||
737 | test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags)) | ||
738 | res = POLLPRI; | ||
739 | } | ||
740 | |||
741 | /* Allow write if buffers are available for writing */ | ||
742 | if (s->q_free.buffers) | ||
743 | res |= POLLOUT | POLLWRNORM; | ||
744 | return res; | ||
745 | } | ||
746 | |||
747 | unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait) | ||
748 | { | ||
749 | struct ivtv_open_id *id = fh2id(filp->private_data); | ||
750 | struct ivtv *itv = id->itv; | ||
751 | struct ivtv_stream *s = &itv->streams[id->type]; | ||
752 | int eof = test_bit(IVTV_F_S_STREAMOFF, &s->s_flags); | ||
753 | unsigned res = 0; | ||
754 | |||
755 | /* Start a capture if there is none */ | ||
756 | if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { | ||
757 | int rc; | ||
758 | |||
759 | mutex_lock(&itv->serialize_lock); | ||
760 | rc = ivtv_start_capture(id); | ||
761 | mutex_unlock(&itv->serialize_lock); | ||
762 | if (rc) { | ||
763 | IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n", | ||
764 | s->name, rc); | ||
765 | return POLLERR; | ||
766 | } | ||
767 | IVTV_DEBUG_FILE("Encoder poll started capture\n"); | ||
768 | } | ||
769 | |||
770 | /* add stream's waitq to the poll list */ | ||
771 | IVTV_DEBUG_HI_FILE("Encoder poll\n"); | ||
772 | poll_wait(filp, &s->waitq, wait); | ||
773 | if (v4l2_event_pending(&id->fh)) | ||
774 | res |= POLLPRI; | ||
775 | else | ||
776 | poll_wait(filp, &id->fh.wait, wait); | ||
777 | |||
778 | if (s->q_full.length || s->q_io.length) | ||
779 | return res | POLLIN | POLLRDNORM; | ||
780 | if (eof) | ||
781 | return res | POLLHUP; | ||
782 | return res; | ||
783 | } | ||
784 | |||
785 | void ivtv_stop_capture(struct ivtv_open_id *id, int gop_end) | ||
786 | { | ||
787 | struct ivtv *itv = id->itv; | ||
788 | struct ivtv_stream *s = &itv->streams[id->type]; | ||
789 | |||
790 | IVTV_DEBUG_FILE("close() of %s\n", s->name); | ||
791 | |||
792 | /* 'Unclaim' this stream */ | ||
793 | |||
794 | /* Stop capturing */ | ||
795 | if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { | ||
796 | struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; | ||
797 | |||
798 | IVTV_DEBUG_INFO("close stopping capture\n"); | ||
799 | /* Special case: a running VBI capture for VBI insertion | ||
800 | in the mpeg stream. Need to stop that too. */ | ||
801 | if (id->type == IVTV_ENC_STREAM_TYPE_MPG && | ||
802 | test_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags) && | ||
803 | !test_bit(IVTV_F_S_APPL_IO, &s_vbi->s_flags)) { | ||
804 | IVTV_DEBUG_INFO("close stopping embedded VBI capture\n"); | ||
805 | ivtv_stop_v4l2_encode_stream(s_vbi, 0); | ||
806 | } | ||
807 | if ((id->type == IVTV_DEC_STREAM_TYPE_VBI || | ||
808 | id->type == IVTV_ENC_STREAM_TYPE_VBI) && | ||
809 | test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) { | ||
810 | /* Also used internally, don't stop capturing */ | ||
811 | s->id = -1; | ||
812 | } | ||
813 | else { | ||
814 | ivtv_stop_v4l2_encode_stream(s, gop_end); | ||
815 | } | ||
816 | } | ||
817 | if (!gop_end) { | ||
818 | clear_bit(IVTV_F_S_APPL_IO, &s->s_flags); | ||
819 | clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags); | ||
820 | ivtv_release_stream(s); | ||
821 | } | ||
822 | } | ||
823 | |||
824 | static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts) | ||
825 | { | ||
826 | struct ivtv *itv = id->itv; | ||
827 | struct ivtv_stream *s = &itv->streams[id->type]; | ||
828 | |||
829 | IVTV_DEBUG_FILE("close() of %s\n", s->name); | ||
830 | |||
831 | if (id->type == IVTV_DEC_STREAM_TYPE_YUV && | ||
832 | test_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags)) { | ||
833 | /* Restore registers we've changed & clean up any mess */ | ||
834 | ivtv_yuv_close(itv); | ||
835 | } | ||
836 | |||
837 | /* Stop decoding */ | ||
838 | if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { | ||
839 | IVTV_DEBUG_INFO("close stopping decode\n"); | ||
840 | |||
841 | ivtv_stop_v4l2_decode_stream(s, flags, pts); | ||
842 | itv->output_mode = OUT_NONE; | ||
843 | } | ||
844 | clear_bit(IVTV_F_S_APPL_IO, &s->s_flags); | ||
845 | clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags); | ||
846 | |||
847 | if (itv->output_mode == OUT_UDMA_YUV && id->yuv_frames) | ||
848 | itv->output_mode = OUT_NONE; | ||
849 | |||
850 | itv->speed = 0; | ||
851 | clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags); | ||
852 | ivtv_release_stream(s); | ||
853 | } | ||
854 | |||
855 | int ivtv_v4l2_close(struct file *filp) | ||
856 | { | ||
857 | struct v4l2_fh *fh = filp->private_data; | ||
858 | struct ivtv_open_id *id = fh2id(fh); | ||
859 | struct ivtv *itv = id->itv; | ||
860 | struct ivtv_stream *s = &itv->streams[id->type]; | ||
861 | |||
862 | IVTV_DEBUG_FILE("close %s\n", s->name); | ||
863 | |||
864 | v4l2_fh_del(fh); | ||
865 | v4l2_fh_exit(fh); | ||
866 | |||
867 | /* Easy case first: this stream was never claimed by us */ | ||
868 | if (s->id != id->open_id) { | ||
869 | kfree(id); | ||
870 | return 0; | ||
871 | } | ||
872 | |||
873 | /* 'Unclaim' this stream */ | ||
874 | |||
875 | /* Stop radio */ | ||
876 | mutex_lock(&itv->serialize_lock); | ||
877 | if (id->type == IVTV_ENC_STREAM_TYPE_RAD) { | ||
878 | /* Closing radio device, return to TV mode */ | ||
879 | ivtv_mute(itv); | ||
880 | /* Mark that the radio is no longer in use */ | ||
881 | clear_bit(IVTV_F_I_RADIO_USER, &itv->i_flags); | ||
882 | /* Switch tuner to TV */ | ||
883 | ivtv_call_all(itv, core, s_std, itv->std); | ||
884 | /* Select correct audio input (i.e. TV tuner or Line in) */ | ||
885 | ivtv_audio_set_io(itv); | ||
886 | if (itv->hw_flags & IVTV_HW_SAA711X) { | ||
887 | ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq, | ||
888 | SAA7115_FREQ_32_11_MHZ, 0); | ||
889 | } | ||
890 | if (atomic_read(&itv->capturing) > 0) { | ||
891 | /* Undo video mute */ | ||
892 | ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1, | ||
893 | v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute) | | ||
894 | (v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute_yuv) << 8)); | ||
895 | } | ||
896 | /* Done! Unmute and continue. */ | ||
897 | ivtv_unmute(itv); | ||
898 | ivtv_release_stream(s); | ||
899 | } else if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) { | ||
900 | struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT]; | ||
901 | |||
902 | ivtv_stop_decoding(id, VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0); | ||
903 | |||
904 | /* If all output streams are closed, and if the user doesn't have | ||
905 | IVTV_DEC_STREAM_TYPE_VOUT open, then disable CC on TV-out. */ | ||
906 | if (itv->output_mode == OUT_NONE && !test_bit(IVTV_F_S_APPL_IO, &s_vout->s_flags)) { | ||
907 | /* disable CC on TV-out */ | ||
908 | ivtv_disable_cc(itv); | ||
909 | } | ||
910 | } else { | ||
911 | ivtv_stop_capture(id, 0); | ||
912 | } | ||
913 | kfree(id); | ||
914 | mutex_unlock(&itv->serialize_lock); | ||
915 | return 0; | ||
916 | } | ||
917 | |||
918 | static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp) | ||
919 | { | ||
920 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
921 | struct video_device *vdev = video_devdata(filp); | ||
922 | #endif | ||
923 | struct ivtv *itv = s->itv; | ||
924 | struct ivtv_open_id *item; | ||
925 | int res = 0; | ||
926 | |||
927 | IVTV_DEBUG_FILE("open %s\n", s->name); | ||
928 | |||
929 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
930 | /* Unless ivtv_fw_debug is set, error out if firmware dead. */ | ||
931 | if (ivtv_fw_debug) { | ||
932 | IVTV_WARN("Opening %s with dead firmware lockout disabled\n", | ||
933 | video_device_node_name(vdev)); | ||
934 | IVTV_WARN("Selected firmware errors will be ignored\n"); | ||
935 | } else { | ||
936 | #else | ||
937 | if (1) { | ||
938 | #endif | ||
939 | res = ivtv_firmware_check(itv, "ivtv_serialized_open"); | ||
940 | if (res == -EAGAIN) | ||
941 | res = ivtv_firmware_check(itv, "ivtv_serialized_open"); | ||
942 | if (res < 0) | ||
943 | return -EIO; | ||
944 | } | ||
945 | |||
946 | if (s->type == IVTV_DEC_STREAM_TYPE_MPG && | ||
947 | test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_YUV].s_flags)) | ||
948 | return -EBUSY; | ||
949 | |||
950 | if (s->type == IVTV_DEC_STREAM_TYPE_YUV && | ||
951 | test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_MPG].s_flags)) | ||
952 | return -EBUSY; | ||
953 | |||
954 | if (s->type == IVTV_DEC_STREAM_TYPE_YUV) { | ||
955 | if (read_reg(0x82c) == 0) { | ||
956 | IVTV_ERR("Tried to open YUV output device but need to send data to mpeg decoder before it can be used\n"); | ||
957 | /* return -ENODEV; */ | ||
958 | } | ||
959 | ivtv_udma_alloc(itv); | ||
960 | } | ||
961 | |||
962 | /* Allocate memory */ | ||
963 | item = kzalloc(sizeof(struct ivtv_open_id), GFP_KERNEL); | ||
964 | if (NULL == item) { | ||
965 | IVTV_DEBUG_WARN("nomem on v4l2 open\n"); | ||
966 | return -ENOMEM; | ||
967 | } | ||
968 | v4l2_fh_init(&item->fh, s->vdev); | ||
969 | if (res < 0) { | ||
970 | v4l2_fh_exit(&item->fh); | ||
971 | kfree(item); | ||
972 | return res; | ||
973 | } | ||
974 | item->itv = itv; | ||
975 | item->type = s->type; | ||
976 | |||
977 | item->open_id = itv->open_id++; | ||
978 | filp->private_data = &item->fh; | ||
979 | |||
980 | if (item->type == IVTV_ENC_STREAM_TYPE_RAD) { | ||
981 | /* Try to claim this stream */ | ||
982 | if (ivtv_claim_stream(item, item->type)) { | ||
983 | /* No, it's already in use */ | ||
984 | v4l2_fh_exit(&item->fh); | ||
985 | kfree(item); | ||
986 | return -EBUSY; | ||
987 | } | ||
988 | |||
989 | if (!test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { | ||
990 | if (atomic_read(&itv->capturing) > 0) { | ||
991 | /* switching to radio while capture is | ||
992 | in progress is not polite */ | ||
993 | ivtv_release_stream(s); | ||
994 | v4l2_fh_exit(&item->fh); | ||
995 | kfree(item); | ||
996 | return -EBUSY; | ||
997 | } | ||
998 | } | ||
999 | /* Mark that the radio is being used. */ | ||
1000 | set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags); | ||
1001 | /* We have the radio */ | ||
1002 | ivtv_mute(itv); | ||
1003 | /* Switch tuner to radio */ | ||
1004 | ivtv_call_all(itv, tuner, s_radio); | ||
1005 | /* Select the correct audio input (i.e. radio tuner) */ | ||
1006 | ivtv_audio_set_io(itv); | ||
1007 | if (itv->hw_flags & IVTV_HW_SAA711X) { | ||
1008 | ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq, | ||
1009 | SAA7115_FREQ_32_11_MHZ, SAA7115_FREQ_FL_APLL); | ||
1010 | } | ||
1011 | /* Done! Unmute and continue. */ | ||
1012 | ivtv_unmute(itv); | ||
1013 | } | ||
1014 | |||
1015 | /* YUV or MPG Decoding Mode? */ | ||
1016 | if (s->type == IVTV_DEC_STREAM_TYPE_MPG) { | ||
1017 | clear_bit(IVTV_F_I_DEC_YUV, &itv->i_flags); | ||
1018 | } else if (s->type == IVTV_DEC_STREAM_TYPE_YUV) { | ||
1019 | set_bit(IVTV_F_I_DEC_YUV, &itv->i_flags); | ||
1020 | /* For yuv, we need to know the dma size before we start */ | ||
1021 | itv->dma_data_req_size = | ||
1022 | 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31); | ||
1023 | itv->yuv_info.stream_size = 0; | ||
1024 | } | ||
1025 | v4l2_fh_add(&item->fh); | ||
1026 | return 0; | ||
1027 | } | ||
1028 | |||
1029 | int ivtv_v4l2_open(struct file *filp) | ||
1030 | { | ||
1031 | int res; | ||
1032 | struct ivtv *itv = NULL; | ||
1033 | struct ivtv_stream *s = NULL; | ||
1034 | struct video_device *vdev = video_devdata(filp); | ||
1035 | |||
1036 | s = video_get_drvdata(vdev); | ||
1037 | itv = s->itv; | ||
1038 | |||
1039 | mutex_lock(&itv->serialize_lock); | ||
1040 | if (ivtv_init_on_first_open(itv)) { | ||
1041 | IVTV_ERR("Failed to initialize on device %s\n", | ||
1042 | video_device_node_name(vdev)); | ||
1043 | mutex_unlock(&itv->serialize_lock); | ||
1044 | return -ENXIO; | ||
1045 | } | ||
1046 | res = ivtv_serialized_open(s, filp); | ||
1047 | mutex_unlock(&itv->serialize_lock); | ||
1048 | return res; | ||
1049 | } | ||
1050 | |||
1051 | void ivtv_mute(struct ivtv *itv) | ||
1052 | { | ||
1053 | if (atomic_read(&itv->capturing)) | ||
1054 | ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 1); | ||
1055 | IVTV_DEBUG_INFO("Mute\n"); | ||
1056 | } | ||
1057 | |||
1058 | void ivtv_unmute(struct ivtv *itv) | ||
1059 | { | ||
1060 | if (atomic_read(&itv->capturing)) { | ||
1061 | ivtv_msleep_timeout(100, 0); | ||
1062 | ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12); | ||
1063 | ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 0); | ||
1064 | } | ||
1065 | IVTV_DEBUG_INFO("Unmute\n"); | ||
1066 | } | ||
diff --git a/drivers/media/video/ivtv/ivtv-fileops.h b/drivers/media/video/ivtv/ivtv-fileops.h new file mode 100644 index 00000000000..049a2923965 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-fileops.h | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | file operation functions | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #ifndef IVTV_FILEOPS_H | ||
22 | #define IVTV_FILEOPS_H | ||
23 | |||
24 | /* Testing/Debugging */ | ||
25 | int ivtv_v4l2_open(struct file *filp); | ||
26 | ssize_t ivtv_v4l2_read(struct file *filp, char __user *buf, size_t count, | ||
27 | loff_t * pos); | ||
28 | ssize_t ivtv_v4l2_write(struct file *filp, const char __user *buf, size_t count, | ||
29 | loff_t * pos); | ||
30 | int ivtv_v4l2_close(struct file *filp); | ||
31 | unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait); | ||
32 | unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table * wait); | ||
33 | int ivtv_start_capture(struct ivtv_open_id *id); | ||
34 | void ivtv_stop_capture(struct ivtv_open_id *id, int gop_end); | ||
35 | int ivtv_start_decoding(struct ivtv_open_id *id, int speed); | ||
36 | void ivtv_mute(struct ivtv *itv); | ||
37 | void ivtv_unmute(struct ivtv *itv); | ||
38 | |||
39 | /* Utilities */ | ||
40 | |||
41 | /* Release a previously claimed stream. */ | ||
42 | void ivtv_release_stream(struct ivtv_stream *s); | ||
43 | |||
44 | #endif | ||
diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/video/ivtv/ivtv-firmware.c new file mode 100644 index 00000000000..02c5adebf51 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-firmware.c | |||
@@ -0,0 +1,398 @@ | |||
1 | /* | ||
2 | ivtv firmware functions. | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2004 Chris Kennedy <c@groovy.org> | ||
5 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include "ivtv-driver.h" | ||
23 | #include "ivtv-mailbox.h" | ||
24 | #include "ivtv-firmware.h" | ||
25 | #include "ivtv-yuv.h" | ||
26 | #include "ivtv-ioctl.h" | ||
27 | #include "ivtv-cards.h" | ||
28 | #include <linux/firmware.h> | ||
29 | #include <media/saa7127.h> | ||
30 | |||
31 | #define IVTV_MASK_SPU_ENABLE 0xFFFFFFFE | ||
32 | #define IVTV_MASK_VPU_ENABLE15 0xFFFFFFF6 | ||
33 | #define IVTV_MASK_VPU_ENABLE16 0xFFFFFFFB | ||
34 | #define IVTV_CMD_VDM_STOP 0x00000000 | ||
35 | #define IVTV_CMD_AO_STOP 0x00000005 | ||
36 | #define IVTV_CMD_APU_PING 0x00000000 | ||
37 | #define IVTV_CMD_VPU_STOP15 0xFFFFFFFE | ||
38 | #define IVTV_CMD_VPU_STOP16 0xFFFFFFEE | ||
39 | #define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF | ||
40 | #define IVTV_CMD_SPU_STOP 0x00000001 | ||
41 | #define IVTV_CMD_SDRAM_PRECHARGE_INIT 0x0000001A | ||
42 | #define IVTV_CMD_SDRAM_REFRESH_INIT 0x80000640 | ||
43 | #define IVTV_SDRAM_SLEEPTIME 600 | ||
44 | |||
45 | #define IVTV_DECODE_INIT_MPEG_FILENAME "v4l-cx2341x-init.mpg" | ||
46 | #define IVTV_DECODE_INIT_MPEG_SIZE (152*1024) | ||
47 | |||
48 | /* Encoder/decoder firmware sizes */ | ||
49 | #define IVTV_FW_ENC_SIZE (376836) | ||
50 | #define IVTV_FW_DEC_SIZE (256*1024) | ||
51 | |||
52 | static int load_fw_direct(const char *fn, volatile u8 __iomem *mem, struct ivtv *itv, long size) | ||
53 | { | ||
54 | const struct firmware *fw = NULL; | ||
55 | int retries = 3; | ||
56 | |||
57 | retry: | ||
58 | if (retries && request_firmware(&fw, fn, &itv->pdev->dev) == 0) { | ||
59 | int i; | ||
60 | volatile u32 __iomem *dst = (volatile u32 __iomem *)mem; | ||
61 | const u32 *src = (const u32 *)fw->data; | ||
62 | |||
63 | if (fw->size != size) { | ||
64 | /* Due to race conditions in firmware loading (esp. with udev <0.95) | ||
65 | the wrong file was sometimes loaded. So we check filesizes to | ||
66 | see if at least the right-sized file was loaded. If not, then we | ||
67 | retry. */ | ||
68 | IVTV_INFO("Retry: file loaded was not %s (expected size %ld, got %zd)\n", fn, size, fw->size); | ||
69 | release_firmware(fw); | ||
70 | retries--; | ||
71 | goto retry; | ||
72 | } | ||
73 | for (i = 0; i < fw->size; i += 4) { | ||
74 | /* no need for endianness conversion on the ppc */ | ||
75 | __raw_writel(*src, dst); | ||
76 | dst++; | ||
77 | src++; | ||
78 | } | ||
79 | IVTV_INFO("Loaded %s firmware (%zd bytes)\n", fn, fw->size); | ||
80 | release_firmware(fw); | ||
81 | return size; | ||
82 | } | ||
83 | IVTV_ERR("Unable to open firmware %s (must be %ld bytes)\n", fn, size); | ||
84 | IVTV_ERR("Did you put the firmware in the hotplug firmware directory?\n"); | ||
85 | return -ENOMEM; | ||
86 | } | ||
87 | |||
88 | void ivtv_halt_firmware(struct ivtv *itv) | ||
89 | { | ||
90 | IVTV_DEBUG_INFO("Preparing for firmware halt.\n"); | ||
91 | if (itv->has_cx23415 && itv->dec_mbox.mbox) | ||
92 | ivtv_vapi(itv, CX2341X_DEC_HALT_FW, 0); | ||
93 | if (itv->enc_mbox.mbox) | ||
94 | ivtv_vapi(itv, CX2341X_ENC_HALT_FW, 0); | ||
95 | |||
96 | ivtv_msleep_timeout(10, 0); | ||
97 | itv->enc_mbox.mbox = itv->dec_mbox.mbox = NULL; | ||
98 | |||
99 | IVTV_DEBUG_INFO("Stopping VDM\n"); | ||
100 | write_reg(IVTV_CMD_VDM_STOP, IVTV_REG_VDM); | ||
101 | |||
102 | IVTV_DEBUG_INFO("Stopping AO\n"); | ||
103 | write_reg(IVTV_CMD_AO_STOP, IVTV_REG_AO); | ||
104 | |||
105 | IVTV_DEBUG_INFO("pinging (?) APU\n"); | ||
106 | write_reg(IVTV_CMD_APU_PING, IVTV_REG_APU); | ||
107 | |||
108 | IVTV_DEBUG_INFO("Stopping VPU\n"); | ||
109 | if (!itv->has_cx23415) | ||
110 | write_reg(IVTV_CMD_VPU_STOP16, IVTV_REG_VPU); | ||
111 | else | ||
112 | write_reg(IVTV_CMD_VPU_STOP15, IVTV_REG_VPU); | ||
113 | |||
114 | IVTV_DEBUG_INFO("Resetting Hw Blocks\n"); | ||
115 | write_reg(IVTV_CMD_HW_BLOCKS_RST, IVTV_REG_HW_BLOCKS); | ||
116 | |||
117 | IVTV_DEBUG_INFO("Stopping SPU\n"); | ||
118 | write_reg(IVTV_CMD_SPU_STOP, IVTV_REG_SPU); | ||
119 | |||
120 | ivtv_msleep_timeout(10, 0); | ||
121 | |||
122 | IVTV_DEBUG_INFO("init Encoder SDRAM pre-charge\n"); | ||
123 | write_reg(IVTV_CMD_SDRAM_PRECHARGE_INIT, IVTV_REG_ENC_SDRAM_PRECHARGE); | ||
124 | |||
125 | IVTV_DEBUG_INFO("init Encoder SDRAM refresh to 1us\n"); | ||
126 | write_reg(IVTV_CMD_SDRAM_REFRESH_INIT, IVTV_REG_ENC_SDRAM_REFRESH); | ||
127 | |||
128 | if (itv->has_cx23415) { | ||
129 | IVTV_DEBUG_INFO("init Decoder SDRAM pre-charge\n"); | ||
130 | write_reg(IVTV_CMD_SDRAM_PRECHARGE_INIT, IVTV_REG_DEC_SDRAM_PRECHARGE); | ||
131 | |||
132 | IVTV_DEBUG_INFO("init Decoder SDRAM refresh to 1us\n"); | ||
133 | write_reg(IVTV_CMD_SDRAM_REFRESH_INIT, IVTV_REG_DEC_SDRAM_REFRESH); | ||
134 | } | ||
135 | |||
136 | IVTV_DEBUG_INFO("Sleeping for %dms\n", IVTV_SDRAM_SLEEPTIME); | ||
137 | ivtv_msleep_timeout(IVTV_SDRAM_SLEEPTIME, 0); | ||
138 | } | ||
139 | |||
140 | void ivtv_firmware_versions(struct ivtv *itv) | ||
141 | { | ||
142 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
143 | |||
144 | /* Encoder */ | ||
145 | ivtv_vapi_result(itv, data, CX2341X_ENC_GET_VERSION, 0); | ||
146 | IVTV_INFO("Encoder revision: 0x%08x\n", data[0]); | ||
147 | |||
148 | if (data[0] != 0x02060039) | ||
149 | IVTV_WARN("Recommended firmware version is 0x02060039.\n"); | ||
150 | |||
151 | if (itv->has_cx23415) { | ||
152 | /* Decoder */ | ||
153 | ivtv_vapi_result(itv, data, CX2341X_DEC_GET_VERSION, 0); | ||
154 | IVTV_INFO("Decoder revision: 0x%08x\n", data[0]); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | static int ivtv_firmware_copy(struct ivtv *itv) | ||
159 | { | ||
160 | IVTV_DEBUG_INFO("Loading encoder image\n"); | ||
161 | if (load_fw_direct(CX2341X_FIRM_ENC_FILENAME, | ||
162 | itv->enc_mem, itv, IVTV_FW_ENC_SIZE) != IVTV_FW_ENC_SIZE) { | ||
163 | IVTV_DEBUG_WARN("failed loading encoder firmware\n"); | ||
164 | return -3; | ||
165 | } | ||
166 | if (!itv->has_cx23415) | ||
167 | return 0; | ||
168 | |||
169 | IVTV_DEBUG_INFO("Loading decoder image\n"); | ||
170 | if (load_fw_direct(CX2341X_FIRM_DEC_FILENAME, | ||
171 | itv->dec_mem, itv, IVTV_FW_DEC_SIZE) != IVTV_FW_DEC_SIZE) { | ||
172 | IVTV_DEBUG_WARN("failed loading decoder firmware\n"); | ||
173 | return -1; | ||
174 | } | ||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | static volatile struct ivtv_mailbox __iomem *ivtv_search_mailbox(const volatile u8 __iomem *mem, u32 size) | ||
179 | { | ||
180 | int i; | ||
181 | |||
182 | /* mailbox is preceded by a 16 byte 'magic cookie' starting at a 256-byte | ||
183 | address boundary */ | ||
184 | for (i = 0; i < size; i += 0x100) { | ||
185 | if (readl(mem + i) == 0x12345678 && | ||
186 | readl(mem + i + 4) == 0x34567812 && | ||
187 | readl(mem + i + 8) == 0x56781234 && | ||
188 | readl(mem + i + 12) == 0x78123456) { | ||
189 | return (volatile struct ivtv_mailbox __iomem *)(mem + i + 16); | ||
190 | } | ||
191 | } | ||
192 | return NULL; | ||
193 | } | ||
194 | |||
195 | int ivtv_firmware_init(struct ivtv *itv) | ||
196 | { | ||
197 | int err; | ||
198 | |||
199 | ivtv_halt_firmware(itv); | ||
200 | |||
201 | /* load firmware */ | ||
202 | err = ivtv_firmware_copy(itv); | ||
203 | if (err) { | ||
204 | IVTV_DEBUG_WARN("Error %d loading firmware\n", err); | ||
205 | return err; | ||
206 | } | ||
207 | |||
208 | /* start firmware */ | ||
209 | write_reg(read_reg(IVTV_REG_SPU) & IVTV_MASK_SPU_ENABLE, IVTV_REG_SPU); | ||
210 | ivtv_msleep_timeout(100, 0); | ||
211 | if (itv->has_cx23415) | ||
212 | write_reg(read_reg(IVTV_REG_VPU) & IVTV_MASK_VPU_ENABLE15, IVTV_REG_VPU); | ||
213 | else | ||
214 | write_reg(read_reg(IVTV_REG_VPU) & IVTV_MASK_VPU_ENABLE16, IVTV_REG_VPU); | ||
215 | ivtv_msleep_timeout(100, 0); | ||
216 | |||
217 | /* find mailboxes and ping firmware */ | ||
218 | itv->enc_mbox.mbox = ivtv_search_mailbox(itv->enc_mem, IVTV_ENCODER_SIZE); | ||
219 | if (itv->enc_mbox.mbox == NULL) | ||
220 | IVTV_ERR("Encoder mailbox not found\n"); | ||
221 | else if (ivtv_vapi(itv, CX2341X_ENC_PING_FW, 0)) { | ||
222 | IVTV_ERR("Encoder firmware dead!\n"); | ||
223 | itv->enc_mbox.mbox = NULL; | ||
224 | } | ||
225 | if (itv->enc_mbox.mbox == NULL) | ||
226 | return -ENODEV; | ||
227 | |||
228 | if (!itv->has_cx23415) | ||
229 | return 0; | ||
230 | |||
231 | itv->dec_mbox.mbox = ivtv_search_mailbox(itv->dec_mem, IVTV_DECODER_SIZE); | ||
232 | if (itv->dec_mbox.mbox == NULL) { | ||
233 | IVTV_ERR("Decoder mailbox not found\n"); | ||
234 | } else if (itv->has_cx23415 && ivtv_vapi(itv, CX2341X_DEC_PING_FW, 0)) { | ||
235 | IVTV_ERR("Decoder firmware dead!\n"); | ||
236 | itv->dec_mbox.mbox = NULL; | ||
237 | } else { | ||
238 | /* Firmware okay, so check yuv output filter table */ | ||
239 | ivtv_yuv_filter_check(itv); | ||
240 | } | ||
241 | return itv->dec_mbox.mbox ? 0 : -ENODEV; | ||
242 | } | ||
243 | |||
244 | void ivtv_init_mpeg_decoder(struct ivtv *itv) | ||
245 | { | ||
246 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
247 | long readbytes; | ||
248 | volatile u8 __iomem *mem_offset; | ||
249 | |||
250 | data[0] = 0; | ||
251 | data[1] = itv->cxhdl.width; /* YUV source width */ | ||
252 | data[2] = itv->cxhdl.height; | ||
253 | data[3] = itv->cxhdl.audio_properties; /* Audio settings to use, | ||
254 | bitmap. see docs. */ | ||
255 | if (ivtv_api(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, data)) { | ||
256 | IVTV_ERR("ivtv_init_mpeg_decoder failed to set decoder source\n"); | ||
257 | return; | ||
258 | } | ||
259 | |||
260 | if (ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, 0, 1) != 0) { | ||
261 | IVTV_ERR("ivtv_init_mpeg_decoder failed to start playback\n"); | ||
262 | return; | ||
263 | } | ||
264 | ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 2, data); | ||
265 | mem_offset = itv->dec_mem + data[1]; | ||
266 | |||
267 | if ((readbytes = load_fw_direct(IVTV_DECODE_INIT_MPEG_FILENAME, | ||
268 | mem_offset, itv, IVTV_DECODE_INIT_MPEG_SIZE)) <= 0) { | ||
269 | IVTV_DEBUG_WARN("failed to read mpeg decoder initialisation file %s\n", | ||
270 | IVTV_DECODE_INIT_MPEG_FILENAME); | ||
271 | } else { | ||
272 | ivtv_vapi(itv, CX2341X_DEC_SCHED_DMA_FROM_HOST, 3, 0, readbytes, 0); | ||
273 | ivtv_msleep_timeout(100, 0); | ||
274 | } | ||
275 | ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 4, 0, 0, 0, 1); | ||
276 | } | ||
277 | |||
278 | /* Try to restart the card & restore previous settings */ | ||
279 | int ivtv_firmware_restart(struct ivtv *itv) | ||
280 | { | ||
281 | int rc = 0; | ||
282 | v4l2_std_id std; | ||
283 | |||
284 | if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) | ||
285 | /* Display test image during restart */ | ||
286 | ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing, | ||
287 | SAA7127_INPUT_TYPE_TEST_IMAGE, | ||
288 | itv->card->video_outputs[itv->active_output].video_output, | ||
289 | 0); | ||
290 | |||
291 | mutex_lock(&itv->udma.lock); | ||
292 | |||
293 | rc = ivtv_firmware_init(itv); | ||
294 | if (rc) { | ||
295 | mutex_unlock(&itv->udma.lock); | ||
296 | return rc; | ||
297 | } | ||
298 | |||
299 | /* Allow settings to reload */ | ||
300 | ivtv_mailbox_cache_invalidate(itv); | ||
301 | |||
302 | /* Restore encoder video standard */ | ||
303 | std = itv->std; | ||
304 | itv->std = 0; | ||
305 | ivtv_s_std_enc(itv, &std); | ||
306 | |||
307 | if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { | ||
308 | ivtv_init_mpeg_decoder(itv); | ||
309 | |||
310 | /* Restore decoder video standard */ | ||
311 | std = itv->std_out; | ||
312 | itv->std_out = 0; | ||
313 | ivtv_s_std_dec(itv, &std); | ||
314 | |||
315 | /* Restore framebuffer if active */ | ||
316 | if (itv->ivtvfb_restore) | ||
317 | itv->ivtvfb_restore(itv); | ||
318 | |||
319 | /* Restore alpha settings */ | ||
320 | ivtv_set_osd_alpha(itv); | ||
321 | |||
322 | /* Restore normal output */ | ||
323 | ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing, | ||
324 | SAA7127_INPUT_TYPE_NORMAL, | ||
325 | itv->card->video_outputs[itv->active_output].video_output, | ||
326 | 0); | ||
327 | } | ||
328 | |||
329 | mutex_unlock(&itv->udma.lock); | ||
330 | return rc; | ||
331 | } | ||
332 | |||
333 | /* Check firmware running state. The checks fall through | ||
334 | allowing multiple failures to be logged. */ | ||
335 | int ivtv_firmware_check(struct ivtv *itv, char *where) | ||
336 | { | ||
337 | int res = 0; | ||
338 | |||
339 | /* Check encoder is still running */ | ||
340 | if (ivtv_vapi(itv, CX2341X_ENC_PING_FW, 0) < 0) { | ||
341 | IVTV_WARN("Encoder has died : %s\n", where); | ||
342 | res = -1; | ||
343 | } | ||
344 | |||
345 | /* Also check audio. Only check if not in use & encoder is okay */ | ||
346 | if (!res && !atomic_read(&itv->capturing) && | ||
347 | (!atomic_read(&itv->decoding) || | ||
348 | (atomic_read(&itv->decoding) < 2 && test_bit(IVTV_F_I_DEC_YUV, | ||
349 | &itv->i_flags)))) { | ||
350 | |||
351 | if (ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12) < 0) { | ||
352 | IVTV_WARN("Audio has died (Encoder OK) : %s\n", where); | ||
353 | res = -2; | ||
354 | } | ||
355 | } | ||
356 | |||
357 | if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { | ||
358 | /* Second audio check. Skip if audio already failed */ | ||
359 | if (res != -2 && read_dec(0x100) != read_dec(0x104)) { | ||
360 | /* Wait & try again to be certain. */ | ||
361 | ivtv_msleep_timeout(14, 0); | ||
362 | if (read_dec(0x100) != read_dec(0x104)) { | ||
363 | IVTV_WARN("Audio has died (Decoder) : %s\n", | ||
364 | where); | ||
365 | res = -1; | ||
366 | } | ||
367 | } | ||
368 | |||
369 | /* Check decoder is still running */ | ||
370 | if (ivtv_vapi(itv, CX2341X_DEC_PING_FW, 0) < 0) { | ||
371 | IVTV_WARN("Decoder has died : %s\n", where); | ||
372 | res = -1; | ||
373 | } | ||
374 | } | ||
375 | |||
376 | /* If something failed & currently idle, try to reload */ | ||
377 | if (res && !atomic_read(&itv->capturing) && | ||
378 | !atomic_read(&itv->decoding)) { | ||
379 | IVTV_INFO("Detected in %s that firmware had failed - " | ||
380 | "Reloading\n", where); | ||
381 | res = ivtv_firmware_restart(itv); | ||
382 | /* | ||
383 | * Even if restarted ok, still signal a problem had occurred. | ||
384 | * The caller can come through this function again to check | ||
385 | * if things are really ok after the restart. | ||
386 | */ | ||
387 | if (!res) { | ||
388 | IVTV_INFO("Firmware restart okay\n"); | ||
389 | res = -EAGAIN; | ||
390 | } else { | ||
391 | IVTV_INFO("Firmware restart failed\n"); | ||
392 | } | ||
393 | } else if (res) { | ||
394 | res = -EIO; | ||
395 | } | ||
396 | |||
397 | return res; | ||
398 | } | ||
diff --git a/drivers/media/video/ivtv/ivtv-firmware.h b/drivers/media/video/ivtv/ivtv-firmware.h new file mode 100644 index 00000000000..52bb4e5598f --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-firmware.h | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | ivtv firmware functions. | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2004 Chris Kennedy <c@groovy.org> | ||
5 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #ifndef IVTV_FIRMWARE_H | ||
23 | #define IVTV_FIRMWARE_H | ||
24 | |||
25 | int ivtv_firmware_init(struct ivtv *itv); | ||
26 | void ivtv_firmware_versions(struct ivtv *itv); | ||
27 | void ivtv_halt_firmware(struct ivtv *itv); | ||
28 | void ivtv_init_mpeg_decoder(struct ivtv *itv); | ||
29 | int ivtv_firmware_check(struct ivtv *itv, char *where); | ||
30 | |||
31 | #endif | ||
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c new file mode 100644 index 00000000000..8f0d0778905 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-gpio.c | |||
@@ -0,0 +1,374 @@ | |||
1 | /* | ||
2 | gpio functions. | ||
3 | Merging GPIO support into driver: | ||
4 | Copyright (C) 2004 Chris Kennedy <c@groovy.org> | ||
5 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include "ivtv-driver.h" | ||
23 | #include "ivtv-cards.h" | ||
24 | #include "ivtv-gpio.h" | ||
25 | #include "tuner-xc2028.h" | ||
26 | #include <media/tuner.h> | ||
27 | #include <media/v4l2-ctrls.h> | ||
28 | |||
29 | /* | ||
30 | * GPIO assignment of Yuan MPG600/MPG160 | ||
31 | * | ||
32 | * bit 15 14 13 12 | 11 10 9 8 | 7 6 5 4 | 3 2 1 0 | ||
33 | * OUTPUT IN1 IN0 AM3 AM2 AM1 AM0 | ||
34 | * INPUT DM1 DM0 | ||
35 | * | ||
36 | * IN* : Input selection | ||
37 | * IN1 IN0 | ||
38 | * 1 1 N/A | ||
39 | * 1 0 Line | ||
40 | * 0 1 N/A | ||
41 | * 0 0 Tuner | ||
42 | * | ||
43 | * AM* : Audio Mode | ||
44 | * AM3 0: Normal 1: Mixed(Sub+Main channel) | ||
45 | * AM2 0: Subchannel 1: Main channel | ||
46 | * AM1 0: Stereo 1: Mono | ||
47 | * AM0 0: Normal 1: Mute | ||
48 | * | ||
49 | * DM* : Detected tuner audio Mode | ||
50 | * DM1 0: Stereo 1: Mono | ||
51 | * DM0 0: Multiplex 1: Normal | ||
52 | * | ||
53 | * GPIO Initial Settings | ||
54 | * MPG600 MPG160 | ||
55 | * DIR 0x3080 0x7080 | ||
56 | * OUTPUT 0x000C 0x400C | ||
57 | * | ||
58 | * Special thanks to Makoto Iguchi <iguchi@tahoo.org> and Mr. Anonymous | ||
59 | * for analyzing GPIO of MPG160. | ||
60 | * | ||
61 | ***************************************************************************** | ||
62 | * | ||
63 | * GPIO assignment of Avermedia M179 (per information direct from AVerMedia) | ||
64 | * | ||
65 | * bit 15 14 13 12 | 11 10 9 8 | 7 6 5 4 | 3 2 1 0 | ||
66 | * OUTPUT IN0 AM0 IN1 AM1 AM2 IN2 BR0 BR1 | ||
67 | * INPUT | ||
68 | * | ||
69 | * IN* : Input selection | ||
70 | * IN0 IN1 IN2 | ||
71 | * * 1 * Mute | ||
72 | * 0 0 0 Line-In | ||
73 | * 1 0 0 TV Tuner Audio | ||
74 | * 0 0 1 FM Audio | ||
75 | * 1 0 1 Mute | ||
76 | * | ||
77 | * AM* : Audio Mode | ||
78 | * AM0 AM1 AM2 | ||
79 | * 0 0 0 TV Tuner Audio: L_OUT=(L+R)/2, R_OUT=SAP | ||
80 | * 0 0 1 TV Tuner Audio: L_OUT=R_OUT=SAP (SAP) | ||
81 | * 0 1 0 TV Tuner Audio: L_OUT=L, R_OUT=R (stereo) | ||
82 | * 0 1 1 TV Tuner Audio: mute | ||
83 | * 1 * * TV Tuner Audio: L_OUT=R_OUT=(L+R)/2 (mono) | ||
84 | * | ||
85 | * BR* : Audio Sample Rate (BR stands for bitrate for some reason) | ||
86 | * BR0 BR1 | ||
87 | * 0 0 32 kHz | ||
88 | * 0 1 44.1 kHz | ||
89 | * 1 0 48 kHz | ||
90 | * | ||
91 | * DM* : Detected tuner audio Mode | ||
92 | * Unknown currently | ||
93 | * | ||
94 | * Special thanks to AVerMedia Technologies, Inc. and Jiun-Kuei Jung at | ||
95 | * AVerMedia for providing the GPIO information used to add support | ||
96 | * for the M179 cards. | ||
97 | */ | ||
98 | |||
99 | /********************* GPIO stuffs *********************/ | ||
100 | |||
101 | /* GPIO registers */ | ||
102 | #define IVTV_REG_GPIO_IN 0x9008 | ||
103 | #define IVTV_REG_GPIO_OUT 0x900c | ||
104 | #define IVTV_REG_GPIO_DIR 0x9020 | ||
105 | |||
106 | void ivtv_reset_ir_gpio(struct ivtv *itv) | ||
107 | { | ||
108 | int curdir, curout; | ||
109 | |||
110 | if (itv->card->type != IVTV_CARD_PVR_150) | ||
111 | return; | ||
112 | IVTV_DEBUG_INFO("Resetting PVR150 IR\n"); | ||
113 | curout = read_reg(IVTV_REG_GPIO_OUT); | ||
114 | curdir = read_reg(IVTV_REG_GPIO_DIR); | ||
115 | curdir |= 0x80; | ||
116 | write_reg(curdir, IVTV_REG_GPIO_DIR); | ||
117 | curout = (curout & ~0xF) | 1; | ||
118 | write_reg(curout, IVTV_REG_GPIO_OUT); | ||
119 | /* We could use something else for smaller time */ | ||
120 | schedule_timeout_interruptible(msecs_to_jiffies(1)); | ||
121 | curout |= 2; | ||
122 | write_reg(curout, IVTV_REG_GPIO_OUT); | ||
123 | curdir &= ~0x80; | ||
124 | write_reg(curdir, IVTV_REG_GPIO_DIR); | ||
125 | } | ||
126 | |||
127 | /* Xceive tuner reset function */ | ||
128 | int ivtv_reset_tuner_gpio(void *dev, int component, int cmd, int value) | ||
129 | { | ||
130 | struct i2c_algo_bit_data *algo = dev; | ||
131 | struct ivtv *itv = algo->data; | ||
132 | u32 curout; | ||
133 | |||
134 | if (cmd != XC2028_TUNER_RESET) | ||
135 | return 0; | ||
136 | IVTV_DEBUG_INFO("Resetting tuner\n"); | ||
137 | curout = read_reg(IVTV_REG_GPIO_OUT); | ||
138 | curout &= ~(1 << itv->card->xceive_pin); | ||
139 | write_reg(curout, IVTV_REG_GPIO_OUT); | ||
140 | schedule_timeout_interruptible(msecs_to_jiffies(1)); | ||
141 | |||
142 | curout |= 1 << itv->card->xceive_pin; | ||
143 | write_reg(curout, IVTV_REG_GPIO_OUT); | ||
144 | schedule_timeout_interruptible(msecs_to_jiffies(1)); | ||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | static inline struct ivtv *sd_to_ivtv(struct v4l2_subdev *sd) | ||
149 | { | ||
150 | return container_of(sd, struct ivtv, sd_gpio); | ||
151 | } | ||
152 | |||
153 | static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl) | ||
154 | { | ||
155 | return &container_of(ctrl->handler, struct ivtv, hdl_gpio)->sd_gpio; | ||
156 | } | ||
157 | |||
158 | static int subdev_s_clock_freq(struct v4l2_subdev *sd, u32 freq) | ||
159 | { | ||
160 | struct ivtv *itv = sd_to_ivtv(sd); | ||
161 | u16 mask, data; | ||
162 | |||
163 | mask = itv->card->gpio_audio_freq.mask; | ||
164 | switch (freq) { | ||
165 | case 32000: | ||
166 | data = itv->card->gpio_audio_freq.f32000; | ||
167 | break; | ||
168 | case 44100: | ||
169 | data = itv->card->gpio_audio_freq.f44100; | ||
170 | break; | ||
171 | case 48000: | ||
172 | default: | ||
173 | data = itv->card->gpio_audio_freq.f48000; | ||
174 | break; | ||
175 | } | ||
176 | if (mask) | ||
177 | write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT); | ||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | static int subdev_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) | ||
182 | { | ||
183 | struct ivtv *itv = sd_to_ivtv(sd); | ||
184 | u16 mask; | ||
185 | |||
186 | mask = itv->card->gpio_audio_detect.mask; | ||
187 | if (mask == 0 || (read_reg(IVTV_REG_GPIO_IN) & mask)) | ||
188 | vt->rxsubchans = V4L2_TUNER_SUB_STEREO | | ||
189 | V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; | ||
190 | else | ||
191 | vt->rxsubchans = V4L2_TUNER_SUB_MONO; | ||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static int subdev_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) | ||
196 | { | ||
197 | struct ivtv *itv = sd_to_ivtv(sd); | ||
198 | u16 mask, data; | ||
199 | |||
200 | mask = itv->card->gpio_audio_mode.mask; | ||
201 | switch (vt->audmode) { | ||
202 | case V4L2_TUNER_MODE_LANG1: | ||
203 | data = itv->card->gpio_audio_mode.lang1; | ||
204 | break; | ||
205 | case V4L2_TUNER_MODE_LANG2: | ||
206 | data = itv->card->gpio_audio_mode.lang2; | ||
207 | break; | ||
208 | case V4L2_TUNER_MODE_MONO: | ||
209 | data = itv->card->gpio_audio_mode.mono; | ||
210 | break; | ||
211 | case V4L2_TUNER_MODE_STEREO: | ||
212 | case V4L2_TUNER_MODE_LANG1_LANG2: | ||
213 | default: | ||
214 | data = itv->card->gpio_audio_mode.stereo; | ||
215 | break; | ||
216 | } | ||
217 | if (mask) | ||
218 | write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT); | ||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | static int subdev_s_radio(struct v4l2_subdev *sd) | ||
223 | { | ||
224 | struct ivtv *itv = sd_to_ivtv(sd); | ||
225 | u16 mask, data; | ||
226 | |||
227 | mask = itv->card->gpio_audio_input.mask; | ||
228 | data = itv->card->gpio_audio_input.radio; | ||
229 | if (mask) | ||
230 | write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT); | ||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static int subdev_s_audio_routing(struct v4l2_subdev *sd, | ||
235 | u32 input, u32 output, u32 config) | ||
236 | { | ||
237 | struct ivtv *itv = sd_to_ivtv(sd); | ||
238 | u16 mask, data; | ||
239 | |||
240 | if (input > 2) | ||
241 | return -EINVAL; | ||
242 | mask = itv->card->gpio_audio_input.mask; | ||
243 | switch (input) { | ||
244 | case 0: | ||
245 | data = itv->card->gpio_audio_input.tuner; | ||
246 | break; | ||
247 | case 1: | ||
248 | data = itv->card->gpio_audio_input.linein; | ||
249 | break; | ||
250 | case 2: | ||
251 | default: | ||
252 | data = itv->card->gpio_audio_input.radio; | ||
253 | break; | ||
254 | } | ||
255 | if (mask) | ||
256 | write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT); | ||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | static int subdev_s_ctrl(struct v4l2_ctrl *ctrl) | ||
261 | { | ||
262 | struct v4l2_subdev *sd = to_sd(ctrl); | ||
263 | struct ivtv *itv = sd_to_ivtv(sd); | ||
264 | u16 mask, data; | ||
265 | |||
266 | switch (ctrl->id) { | ||
267 | case V4L2_CID_AUDIO_MUTE: | ||
268 | mask = itv->card->gpio_audio_mute.mask; | ||
269 | data = ctrl->val ? itv->card->gpio_audio_mute.mute : 0; | ||
270 | if (mask) | ||
271 | write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | | ||
272 | (data & mask), IVTV_REG_GPIO_OUT); | ||
273 | return 0; | ||
274 | } | ||
275 | return -EINVAL; | ||
276 | } | ||
277 | |||
278 | |||
279 | static int subdev_log_status(struct v4l2_subdev *sd) | ||
280 | { | ||
281 | struct ivtv *itv = sd_to_ivtv(sd); | ||
282 | |||
283 | IVTV_INFO("GPIO status: DIR=0x%04x OUT=0x%04x IN=0x%04x\n", | ||
284 | read_reg(IVTV_REG_GPIO_DIR), read_reg(IVTV_REG_GPIO_OUT), | ||
285 | read_reg(IVTV_REG_GPIO_IN)); | ||
286 | v4l2_ctrl_handler_log_status(&itv->hdl_gpio, sd->name); | ||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | static int subdev_s_video_routing(struct v4l2_subdev *sd, | ||
291 | u32 input, u32 output, u32 config) | ||
292 | { | ||
293 | struct ivtv *itv = sd_to_ivtv(sd); | ||
294 | u16 mask, data; | ||
295 | |||
296 | if (input > 2) /* 0:Tuner 1:Composite 2:S-Video */ | ||
297 | return -EINVAL; | ||
298 | mask = itv->card->gpio_video_input.mask; | ||
299 | if (input == 0) | ||
300 | data = itv->card->gpio_video_input.tuner; | ||
301 | else if (input == 1) | ||
302 | data = itv->card->gpio_video_input.composite; | ||
303 | else | ||
304 | data = itv->card->gpio_video_input.svideo; | ||
305 | if (mask) | ||
306 | write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT); | ||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | static const struct v4l2_ctrl_ops gpio_ctrl_ops = { | ||
311 | .s_ctrl = subdev_s_ctrl, | ||
312 | }; | ||
313 | |||
314 | static const struct v4l2_subdev_core_ops subdev_core_ops = { | ||
315 | .log_status = subdev_log_status, | ||
316 | .g_ext_ctrls = v4l2_subdev_g_ext_ctrls, | ||
317 | .try_ext_ctrls = v4l2_subdev_try_ext_ctrls, | ||
318 | .s_ext_ctrls = v4l2_subdev_s_ext_ctrls, | ||
319 | .g_ctrl = v4l2_subdev_g_ctrl, | ||
320 | .s_ctrl = v4l2_subdev_s_ctrl, | ||
321 | .queryctrl = v4l2_subdev_queryctrl, | ||
322 | .querymenu = v4l2_subdev_querymenu, | ||
323 | }; | ||
324 | |||
325 | static const struct v4l2_subdev_tuner_ops subdev_tuner_ops = { | ||
326 | .s_radio = subdev_s_radio, | ||
327 | .g_tuner = subdev_g_tuner, | ||
328 | .s_tuner = subdev_s_tuner, | ||
329 | }; | ||
330 | |||
331 | static const struct v4l2_subdev_audio_ops subdev_audio_ops = { | ||
332 | .s_clock_freq = subdev_s_clock_freq, | ||
333 | .s_routing = subdev_s_audio_routing, | ||
334 | }; | ||
335 | |||
336 | static const struct v4l2_subdev_video_ops subdev_video_ops = { | ||
337 | .s_routing = subdev_s_video_routing, | ||
338 | }; | ||
339 | |||
340 | static const struct v4l2_subdev_ops subdev_ops = { | ||
341 | .core = &subdev_core_ops, | ||
342 | .tuner = &subdev_tuner_ops, | ||
343 | .audio = &subdev_audio_ops, | ||
344 | .video = &subdev_video_ops, | ||
345 | }; | ||
346 | |||
347 | int ivtv_gpio_init(struct ivtv *itv) | ||
348 | { | ||
349 | u16 pin = 0; | ||
350 | |||
351 | if (itv->card->xceive_pin) | ||
352 | pin = 1 << itv->card->xceive_pin; | ||
353 | |||
354 | if ((itv->card->gpio_init.direction | pin) == 0) | ||
355 | return 0; | ||
356 | |||
357 | IVTV_DEBUG_INFO("GPIO initial dir: %08x out: %08x\n", | ||
358 | read_reg(IVTV_REG_GPIO_DIR), read_reg(IVTV_REG_GPIO_OUT)); | ||
359 | |||
360 | /* init output data then direction */ | ||
361 | write_reg(itv->card->gpio_init.initial_value | pin, IVTV_REG_GPIO_OUT); | ||
362 | write_reg(itv->card->gpio_init.direction | pin, IVTV_REG_GPIO_DIR); | ||
363 | v4l2_subdev_init(&itv->sd_gpio, &subdev_ops); | ||
364 | snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->v4l2_dev.name); | ||
365 | itv->sd_gpio.grp_id = IVTV_HW_GPIO; | ||
366 | v4l2_ctrl_handler_init(&itv->hdl_gpio, 1); | ||
367 | v4l2_ctrl_new_std(&itv->hdl_gpio, &gpio_ctrl_ops, | ||
368 | V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); | ||
369 | if (itv->hdl_gpio.error) | ||
370 | return itv->hdl_gpio.error; | ||
371 | itv->sd_gpio.ctrl_handler = &itv->hdl_gpio; | ||
372 | v4l2_ctrl_handler_setup(&itv->hdl_gpio); | ||
373 | return v4l2_device_register_subdev(&itv->v4l2_dev, &itv->sd_gpio); | ||
374 | } | ||
diff --git a/drivers/media/video/ivtv/ivtv-gpio.h b/drivers/media/video/ivtv/ivtv-gpio.h new file mode 100644 index 00000000000..0b5d19c8ecb --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-gpio.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | gpio functions. | ||
3 | Copyright (C) 2004 Chris Kennedy <c@groovy.org> | ||
4 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #ifndef IVTV_GPIO_H | ||
22 | #define IVTV_GPIO_H | ||
23 | |||
24 | /* GPIO stuff */ | ||
25 | int ivtv_gpio_init(struct ivtv *itv); | ||
26 | void ivtv_reset_ir_gpio(struct ivtv *itv); | ||
27 | int ivtv_reset_tuner_gpio(void *dev, int component, int cmd, int value); | ||
28 | |||
29 | #endif | ||
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c new file mode 100644 index 00000000000..d47f41a0ef6 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-i2c.c | |||
@@ -0,0 +1,760 @@ | |||
1 | /* | ||
2 | I2C functions | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | This file includes an i2c implementation that was reverse engineered | ||
23 | from the Hauppauge windows driver. Older ivtv versions used i2c-algo-bit, | ||
24 | which whilst fine under most circumstances, had trouble with the Zilog | ||
25 | CPU on the PVR-150 which handles IR functions (occasional inability to | ||
26 | communicate with the chip until it was reset) and also with the i2c | ||
27 | bus being completely unreachable when multiple PVR cards were present. | ||
28 | |||
29 | The implementation is very similar to i2c-algo-bit, but there are enough | ||
30 | subtle differences that the two are hard to merge. The general strategy | ||
31 | employed by i2c-algo-bit is to use udelay() to implement the timing | ||
32 | when putting out bits on the scl/sda lines. The general strategy taken | ||
33 | here is to poll the lines for state changes (see ivtv_waitscl and | ||
34 | ivtv_waitsda). In addition there are small delays at various locations | ||
35 | which poll the SCL line 5 times (ivtv_scldelay). I would guess that | ||
36 | since this is memory mapped I/O that the length of those delays is tied | ||
37 | to the PCI bus clock. There is some extra code to do with recovery | ||
38 | and retries. Since it is not known what causes the actual i2c problems | ||
39 | in the first place, the only goal if one was to attempt to use | ||
40 | i2c-algo-bit would be to try to make it follow the same code path. | ||
41 | This would be a lot of work, and I'm also not convinced that it would | ||
42 | provide a generic benefit to i2c-algo-bit. Therefore consider this | ||
43 | an engineering solution -- not pretty, but it works. | ||
44 | |||
45 | Some more general comments about what we are doing: | ||
46 | |||
47 | The i2c bus is a 2 wire serial bus, with clock (SCL) and data (SDA) | ||
48 | lines. To communicate on the bus (as a master, we don't act as a slave), | ||
49 | we first initiate a start condition (ivtv_start). We then write the | ||
50 | address of the device that we want to communicate with, along with a flag | ||
51 | that indicates whether this is a read or a write. The slave then issues | ||
52 | an ACK signal (ivtv_ack), which tells us that it is ready for reading / | ||
53 | writing. We then proceed with reading or writing (ivtv_read/ivtv_write), | ||
54 | and finally issue a stop condition (ivtv_stop) to make the bus available | ||
55 | to other masters. | ||
56 | |||
57 | There is an additional form of transaction where a write may be | ||
58 | immediately followed by a read. In this case, there is no intervening | ||
59 | stop condition. (Only the msp3400 chip uses this method of data transfer). | ||
60 | */ | ||
61 | |||
62 | #include "ivtv-driver.h" | ||
63 | #include "ivtv-cards.h" | ||
64 | #include "ivtv-gpio.h" | ||
65 | #include "ivtv-i2c.h" | ||
66 | #include <media/cx25840.h> | ||
67 | |||
68 | /* i2c implementation for cx23415/6 chip, ivtv project. | ||
69 | * Author: Kevin Thayer (nufan_wfk at yahoo.com) | ||
70 | */ | ||
71 | /* i2c stuff */ | ||
72 | #define IVTV_REG_I2C_SETSCL_OFFSET 0x7000 | ||
73 | #define IVTV_REG_I2C_SETSDA_OFFSET 0x7004 | ||
74 | #define IVTV_REG_I2C_GETSCL_OFFSET 0x7008 | ||
75 | #define IVTV_REG_I2C_GETSDA_OFFSET 0x700c | ||
76 | |||
77 | #define IVTV_CS53L32A_I2C_ADDR 0x11 | ||
78 | #define IVTV_M52790_I2C_ADDR 0x48 | ||
79 | #define IVTV_CX25840_I2C_ADDR 0x44 | ||
80 | #define IVTV_SAA7115_I2C_ADDR 0x21 | ||
81 | #define IVTV_SAA7127_I2C_ADDR 0x44 | ||
82 | #define IVTV_SAA717x_I2C_ADDR 0x21 | ||
83 | #define IVTV_MSP3400_I2C_ADDR 0x40 | ||
84 | #define IVTV_HAUPPAUGE_I2C_ADDR 0x50 | ||
85 | #define IVTV_WM8739_I2C_ADDR 0x1a | ||
86 | #define IVTV_WM8775_I2C_ADDR 0x1b | ||
87 | #define IVTV_TEA5767_I2C_ADDR 0x60 | ||
88 | #define IVTV_UPD64031A_I2C_ADDR 0x12 | ||
89 | #define IVTV_UPD64083_I2C_ADDR 0x5c | ||
90 | #define IVTV_VP27SMPX_I2C_ADDR 0x5b | ||
91 | #define IVTV_M52790_I2C_ADDR 0x48 | ||
92 | #define IVTV_AVERMEDIA_IR_RX_I2C_ADDR 0x40 | ||
93 | #define IVTV_HAUP_EXT_IR_RX_I2C_ADDR 0x1a | ||
94 | #define IVTV_HAUP_INT_IR_RX_I2C_ADDR 0x18 | ||
95 | #define IVTV_Z8F0811_IR_TX_I2C_ADDR 0x70 | ||
96 | #define IVTV_Z8F0811_IR_RX_I2C_ADDR 0x71 | ||
97 | #define IVTV_ADAPTEC_IR_ADDR 0x6b | ||
98 | |||
99 | /* This array should match the IVTV_HW_ defines */ | ||
100 | static const u8 hw_addrs[] = { | ||
101 | IVTV_CX25840_I2C_ADDR, | ||
102 | IVTV_SAA7115_I2C_ADDR, | ||
103 | IVTV_SAA7127_I2C_ADDR, | ||
104 | IVTV_MSP3400_I2C_ADDR, | ||
105 | 0, | ||
106 | IVTV_WM8775_I2C_ADDR, | ||
107 | IVTV_CS53L32A_I2C_ADDR, | ||
108 | 0, | ||
109 | IVTV_SAA7115_I2C_ADDR, | ||
110 | IVTV_UPD64031A_I2C_ADDR, | ||
111 | IVTV_UPD64083_I2C_ADDR, | ||
112 | IVTV_SAA717x_I2C_ADDR, | ||
113 | IVTV_WM8739_I2C_ADDR, | ||
114 | IVTV_VP27SMPX_I2C_ADDR, | ||
115 | IVTV_M52790_I2C_ADDR, | ||
116 | 0, /* IVTV_HW_GPIO dummy driver ID */ | ||
117 | IVTV_AVERMEDIA_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_AVER */ | ||
118 | IVTV_HAUP_EXT_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_HAUP_EXT */ | ||
119 | IVTV_HAUP_INT_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_HAUP_INT */ | ||
120 | IVTV_Z8F0811_IR_TX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_TX_HAUP */ | ||
121 | IVTV_Z8F0811_IR_RX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_RX_HAUP */ | ||
122 | IVTV_ADAPTEC_IR_ADDR, /* IVTV_HW_I2C_IR_RX_ADAPTEC */ | ||
123 | }; | ||
124 | |||
125 | /* This array should match the IVTV_HW_ defines */ | ||
126 | static const char * const hw_devicenames[] = { | ||
127 | "cx25840", | ||
128 | "saa7115", | ||
129 | "saa7127_auto", /* saa7127 or saa7129 */ | ||
130 | "msp3400", | ||
131 | "tuner", | ||
132 | "wm8775", | ||
133 | "cs53l32a", | ||
134 | "tveeprom", | ||
135 | "saa7114", | ||
136 | "upd64031a", | ||
137 | "upd64083", | ||
138 | "saa717x", | ||
139 | "wm8739", | ||
140 | "vp27smpx", | ||
141 | "m52790", | ||
142 | "gpio", | ||
143 | "ir_video", /* IVTV_HW_I2C_IR_RX_AVER */ | ||
144 | "ir_video", /* IVTV_HW_I2C_IR_RX_HAUP_EXT */ | ||
145 | "ir_video", /* IVTV_HW_I2C_IR_RX_HAUP_INT */ | ||
146 | "ir_tx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_TX_HAUP */ | ||
147 | "ir_rx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_RX_HAUP */ | ||
148 | "ir_video", /* IVTV_HW_I2C_IR_RX_ADAPTEC */ | ||
149 | }; | ||
150 | |||
151 | static int get_key_adaptec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
152 | { | ||
153 | unsigned char keybuf[4]; | ||
154 | |||
155 | keybuf[0] = 0x00; | ||
156 | i2c_master_send(ir->c, keybuf, 1); | ||
157 | /* poll IR chip */ | ||
158 | if (i2c_master_recv(ir->c, keybuf, sizeof(keybuf)) != sizeof(keybuf)) { | ||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | /* key pressed ? */ | ||
163 | if (keybuf[2] == 0xff) | ||
164 | return 0; | ||
165 | |||
166 | /* remove repeat bit */ | ||
167 | keybuf[2] &= 0x7f; | ||
168 | keybuf[3] |= 0x80; | ||
169 | |||
170 | *ir_key = keybuf[3] | keybuf[2] << 8 | keybuf[1] << 16 |keybuf[0] << 24; | ||
171 | *ir_raw = *ir_key; | ||
172 | |||
173 | return 1; | ||
174 | } | ||
175 | |||
176 | static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr) | ||
177 | { | ||
178 | struct i2c_board_info info; | ||
179 | struct i2c_adapter *adap = &itv->i2c_adap; | ||
180 | struct IR_i2c_init_data *init_data = &itv->ir_i2c_init_data; | ||
181 | unsigned short addr_list[2] = { addr, I2C_CLIENT_END }; | ||
182 | |||
183 | /* Only allow one IR transmitter to be registered per board */ | ||
184 | if (hw & IVTV_HW_IR_TX_ANY) { | ||
185 | if (itv->hw_flags & IVTV_HW_IR_TX_ANY) | ||
186 | return -1; | ||
187 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
188 | strlcpy(info.type, type, I2C_NAME_SIZE); | ||
189 | return i2c_new_probed_device(adap, &info, addr_list, NULL) | ||
190 | == NULL ? -1 : 0; | ||
191 | } | ||
192 | |||
193 | /* Only allow one IR receiver to be registered per board */ | ||
194 | if (itv->hw_flags & IVTV_HW_IR_RX_ANY) | ||
195 | return -1; | ||
196 | |||
197 | /* Our default information for ir-kbd-i2c.c to use */ | ||
198 | switch (hw) { | ||
199 | case IVTV_HW_I2C_IR_RX_AVER: | ||
200 | init_data->ir_codes = RC_MAP_AVERMEDIA_CARDBUS; | ||
201 | init_data->internal_get_key_func = | ||
202 | IR_KBD_GET_KEY_AVERMEDIA_CARDBUS; | ||
203 | init_data->type = RC_TYPE_OTHER; | ||
204 | init_data->name = "AVerMedia AVerTV card"; | ||
205 | break; | ||
206 | case IVTV_HW_I2C_IR_RX_HAUP_EXT: | ||
207 | case IVTV_HW_I2C_IR_RX_HAUP_INT: | ||
208 | init_data->ir_codes = RC_MAP_HAUPPAUGE; | ||
209 | init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP; | ||
210 | init_data->type = RC_TYPE_RC5; | ||
211 | init_data->name = itv->card_name; | ||
212 | break; | ||
213 | case IVTV_HW_Z8F0811_IR_RX_HAUP: | ||
214 | /* Default to grey remote */ | ||
215 | init_data->ir_codes = RC_MAP_HAUPPAUGE; | ||
216 | init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; | ||
217 | init_data->type = RC_TYPE_RC5; | ||
218 | init_data->name = itv->card_name; | ||
219 | break; | ||
220 | case IVTV_HW_I2C_IR_RX_ADAPTEC: | ||
221 | init_data->get_key = get_key_adaptec; | ||
222 | init_data->name = itv->card_name; | ||
223 | /* FIXME: The protocol and RC_MAP needs to be corrected */ | ||
224 | init_data->ir_codes = RC_MAP_EMPTY; | ||
225 | init_data->type = RC_TYPE_UNKNOWN; | ||
226 | break; | ||
227 | } | ||
228 | |||
229 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
230 | info.platform_data = init_data; | ||
231 | strlcpy(info.type, type, I2C_NAME_SIZE); | ||
232 | |||
233 | return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ? | ||
234 | -1 : 0; | ||
235 | } | ||
236 | |||
237 | /* Instantiate the IR receiver device using probing -- undesirable */ | ||
238 | struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv) | ||
239 | { | ||
240 | struct i2c_board_info info; | ||
241 | /* | ||
242 | * The external IR receiver is at i2c address 0x34. | ||
243 | * The internal IR receiver is at i2c address 0x30. | ||
244 | * | ||
245 | * In theory, both can be fitted, and Hauppauge suggests an external | ||
246 | * overrides an internal. That's why we probe 0x1a (~0x34) first. CB | ||
247 | * | ||
248 | * Some of these addresses we probe may collide with other i2c address | ||
249 | * allocations, so this function must be called after all other i2c | ||
250 | * devices we care about are registered. | ||
251 | */ | ||
252 | const unsigned short addr_list[] = { | ||
253 | 0x1a, /* Hauppauge IR external - collides with WM8739 */ | ||
254 | 0x18, /* Hauppauge IR internal */ | ||
255 | I2C_CLIENT_END | ||
256 | }; | ||
257 | |||
258 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
259 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
260 | return i2c_new_probed_device(&itv->i2c_adap, &info, addr_list, NULL); | ||
261 | } | ||
262 | |||
263 | int ivtv_i2c_register(struct ivtv *itv, unsigned idx) | ||
264 | { | ||
265 | struct v4l2_subdev *sd; | ||
266 | struct i2c_adapter *adap = &itv->i2c_adap; | ||
267 | const char *type = hw_devicenames[idx]; | ||
268 | u32 hw = 1 << idx; | ||
269 | |||
270 | if (idx >= ARRAY_SIZE(hw_addrs)) | ||
271 | return -1; | ||
272 | if (hw == IVTV_HW_TUNER) { | ||
273 | /* special tuner handling */ | ||
274 | sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0, | ||
275 | itv->card_i2c->radio); | ||
276 | if (sd) | ||
277 | sd->grp_id = 1 << idx; | ||
278 | sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0, | ||
279 | itv->card_i2c->demod); | ||
280 | if (sd) | ||
281 | sd->grp_id = 1 << idx; | ||
282 | sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0, | ||
283 | itv->card_i2c->tv); | ||
284 | if (sd) | ||
285 | sd->grp_id = 1 << idx; | ||
286 | return sd ? 0 : -1; | ||
287 | } | ||
288 | |||
289 | if (hw & IVTV_HW_IR_ANY) | ||
290 | return ivtv_i2c_new_ir(itv, hw, type, hw_addrs[idx]); | ||
291 | |||
292 | /* Is it not an I2C device or one we do not wish to register? */ | ||
293 | if (!hw_addrs[idx]) | ||
294 | return -1; | ||
295 | |||
296 | /* It's an I2C device other than an analog tuner or IR chip */ | ||
297 | if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) { | ||
298 | sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, | ||
299 | adap, type, 0, I2C_ADDRS(hw_addrs[idx])); | ||
300 | } else if (hw == IVTV_HW_CX25840) { | ||
301 | struct cx25840_platform_data pdata; | ||
302 | struct i2c_board_info cx25840_info = { | ||
303 | .type = "cx25840", | ||
304 | .addr = hw_addrs[idx], | ||
305 | .platform_data = &pdata, | ||
306 | }; | ||
307 | |||
308 | pdata.pvr150_workaround = itv->pvr150_workaround; | ||
309 | sd = v4l2_i2c_new_subdev_board(&itv->v4l2_dev, adap, | ||
310 | &cx25840_info, NULL); | ||
311 | } else { | ||
312 | sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, | ||
313 | adap, type, hw_addrs[idx], NULL); | ||
314 | } | ||
315 | if (sd) | ||
316 | sd->grp_id = 1 << idx; | ||
317 | return sd ? 0 : -1; | ||
318 | } | ||
319 | |||
320 | struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw) | ||
321 | { | ||
322 | struct v4l2_subdev *result = NULL; | ||
323 | struct v4l2_subdev *sd; | ||
324 | |||
325 | spin_lock(&itv->v4l2_dev.lock); | ||
326 | v4l2_device_for_each_subdev(sd, &itv->v4l2_dev) { | ||
327 | if (sd->grp_id == hw) { | ||
328 | result = sd; | ||
329 | break; | ||
330 | } | ||
331 | } | ||
332 | spin_unlock(&itv->v4l2_dev.lock); | ||
333 | return result; | ||
334 | } | ||
335 | |||
336 | /* Set the serial clock line to the desired state */ | ||
337 | static void ivtv_setscl(struct ivtv *itv, int state) | ||
338 | { | ||
339 | /* write them out */ | ||
340 | /* write bits are inverted */ | ||
341 | write_reg(~state, IVTV_REG_I2C_SETSCL_OFFSET); | ||
342 | } | ||
343 | |||
344 | /* Set the serial data line to the desired state */ | ||
345 | static void ivtv_setsda(struct ivtv *itv, int state) | ||
346 | { | ||
347 | /* write them out */ | ||
348 | /* write bits are inverted */ | ||
349 | write_reg(~state & 1, IVTV_REG_I2C_SETSDA_OFFSET); | ||
350 | } | ||
351 | |||
352 | /* Read the serial clock line */ | ||
353 | static int ivtv_getscl(struct ivtv *itv) | ||
354 | { | ||
355 | return read_reg(IVTV_REG_I2C_GETSCL_OFFSET) & 1; | ||
356 | } | ||
357 | |||
358 | /* Read the serial data line */ | ||
359 | static int ivtv_getsda(struct ivtv *itv) | ||
360 | { | ||
361 | return read_reg(IVTV_REG_I2C_GETSDA_OFFSET) & 1; | ||
362 | } | ||
363 | |||
364 | /* Implement a short delay by polling the serial clock line */ | ||
365 | static void ivtv_scldelay(struct ivtv *itv) | ||
366 | { | ||
367 | int i; | ||
368 | |||
369 | for (i = 0; i < 5; ++i) | ||
370 | ivtv_getscl(itv); | ||
371 | } | ||
372 | |||
373 | /* Wait for the serial clock line to become set to a specific value */ | ||
374 | static int ivtv_waitscl(struct ivtv *itv, int val) | ||
375 | { | ||
376 | int i; | ||
377 | |||
378 | ivtv_scldelay(itv); | ||
379 | for (i = 0; i < 1000; ++i) { | ||
380 | if (ivtv_getscl(itv) == val) | ||
381 | return 1; | ||
382 | } | ||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | /* Wait for the serial data line to become set to a specific value */ | ||
387 | static int ivtv_waitsda(struct ivtv *itv, int val) | ||
388 | { | ||
389 | int i; | ||
390 | |||
391 | ivtv_scldelay(itv); | ||
392 | for (i = 0; i < 1000; ++i) { | ||
393 | if (ivtv_getsda(itv) == val) | ||
394 | return 1; | ||
395 | } | ||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | /* Wait for the slave to issue an ACK */ | ||
400 | static int ivtv_ack(struct ivtv *itv) | ||
401 | { | ||
402 | int ret = 0; | ||
403 | |||
404 | if (ivtv_getscl(itv) == 1) { | ||
405 | IVTV_DEBUG_HI_I2C("SCL was high starting an ack\n"); | ||
406 | ivtv_setscl(itv, 0); | ||
407 | if (!ivtv_waitscl(itv, 0)) { | ||
408 | IVTV_DEBUG_I2C("Could not set SCL low starting an ack\n"); | ||
409 | return -EREMOTEIO; | ||
410 | } | ||
411 | } | ||
412 | ivtv_setsda(itv, 1); | ||
413 | ivtv_scldelay(itv); | ||
414 | ivtv_setscl(itv, 1); | ||
415 | if (!ivtv_waitsda(itv, 0)) { | ||
416 | IVTV_DEBUG_I2C("Slave did not ack\n"); | ||
417 | ret = -EREMOTEIO; | ||
418 | } | ||
419 | ivtv_setscl(itv, 0); | ||
420 | if (!ivtv_waitscl(itv, 0)) { | ||
421 | IVTV_DEBUG_I2C("Failed to set SCL low after ACK\n"); | ||
422 | ret = -EREMOTEIO; | ||
423 | } | ||
424 | return ret; | ||
425 | } | ||
426 | |||
427 | /* Write a single byte to the i2c bus and wait for the slave to ACK */ | ||
428 | static int ivtv_sendbyte(struct ivtv *itv, unsigned char byte) | ||
429 | { | ||
430 | int i, bit; | ||
431 | |||
432 | IVTV_DEBUG_HI_I2C("write %x\n",byte); | ||
433 | for (i = 0; i < 8; ++i, byte<<=1) { | ||
434 | ivtv_setscl(itv, 0); | ||
435 | if (!ivtv_waitscl(itv, 0)) { | ||
436 | IVTV_DEBUG_I2C("Error setting SCL low\n"); | ||
437 | return -EREMOTEIO; | ||
438 | } | ||
439 | bit = (byte>>7)&1; | ||
440 | ivtv_setsda(itv, bit); | ||
441 | if (!ivtv_waitsda(itv, bit)) { | ||
442 | IVTV_DEBUG_I2C("Error setting SDA\n"); | ||
443 | return -EREMOTEIO; | ||
444 | } | ||
445 | ivtv_setscl(itv, 1); | ||
446 | if (!ivtv_waitscl(itv, 1)) { | ||
447 | IVTV_DEBUG_I2C("Slave not ready for bit\n"); | ||
448 | return -EREMOTEIO; | ||
449 | } | ||
450 | } | ||
451 | ivtv_setscl(itv, 0); | ||
452 | if (!ivtv_waitscl(itv, 0)) { | ||
453 | IVTV_DEBUG_I2C("Error setting SCL low\n"); | ||
454 | return -EREMOTEIO; | ||
455 | } | ||
456 | return ivtv_ack(itv); | ||
457 | } | ||
458 | |||
459 | /* Read a byte from the i2c bus and send a NACK if applicable (i.e. for the | ||
460 | final byte) */ | ||
461 | static int ivtv_readbyte(struct ivtv *itv, unsigned char *byte, int nack) | ||
462 | { | ||
463 | int i; | ||
464 | |||
465 | *byte = 0; | ||
466 | |||
467 | ivtv_setsda(itv, 1); | ||
468 | ivtv_scldelay(itv); | ||
469 | for (i = 0; i < 8; ++i) { | ||
470 | ivtv_setscl(itv, 0); | ||
471 | ivtv_scldelay(itv); | ||
472 | ivtv_setscl(itv, 1); | ||
473 | if (!ivtv_waitscl(itv, 1)) { | ||
474 | IVTV_DEBUG_I2C("Error setting SCL high\n"); | ||
475 | return -EREMOTEIO; | ||
476 | } | ||
477 | *byte = ((*byte)<<1)|ivtv_getsda(itv); | ||
478 | } | ||
479 | ivtv_setscl(itv, 0); | ||
480 | ivtv_scldelay(itv); | ||
481 | ivtv_setsda(itv, nack); | ||
482 | ivtv_scldelay(itv); | ||
483 | ivtv_setscl(itv, 1); | ||
484 | ivtv_scldelay(itv); | ||
485 | ivtv_setscl(itv, 0); | ||
486 | ivtv_scldelay(itv); | ||
487 | IVTV_DEBUG_HI_I2C("read %x\n",*byte); | ||
488 | return 0; | ||
489 | } | ||
490 | |||
491 | /* Issue a start condition on the i2c bus to alert slaves to prepare for | ||
492 | an address write */ | ||
493 | static int ivtv_start(struct ivtv *itv) | ||
494 | { | ||
495 | int sda; | ||
496 | |||
497 | sda = ivtv_getsda(itv); | ||
498 | if (sda != 1) { | ||
499 | IVTV_DEBUG_HI_I2C("SDA was low at start\n"); | ||
500 | ivtv_setsda(itv, 1); | ||
501 | if (!ivtv_waitsda(itv, 1)) { | ||
502 | IVTV_DEBUG_I2C("SDA stuck low\n"); | ||
503 | return -EREMOTEIO; | ||
504 | } | ||
505 | } | ||
506 | if (ivtv_getscl(itv) != 1) { | ||
507 | ivtv_setscl(itv, 1); | ||
508 | if (!ivtv_waitscl(itv, 1)) { | ||
509 | IVTV_DEBUG_I2C("SCL stuck low at start\n"); | ||
510 | return -EREMOTEIO; | ||
511 | } | ||
512 | } | ||
513 | ivtv_setsda(itv, 0); | ||
514 | ivtv_scldelay(itv); | ||
515 | return 0; | ||
516 | } | ||
517 | |||
518 | /* Issue a stop condition on the i2c bus to release it */ | ||
519 | static int ivtv_stop(struct ivtv *itv) | ||
520 | { | ||
521 | int i; | ||
522 | |||
523 | if (ivtv_getscl(itv) != 0) { | ||
524 | IVTV_DEBUG_HI_I2C("SCL not low when stopping\n"); | ||
525 | ivtv_setscl(itv, 0); | ||
526 | if (!ivtv_waitscl(itv, 0)) { | ||
527 | IVTV_DEBUG_I2C("SCL could not be set low\n"); | ||
528 | } | ||
529 | } | ||
530 | ivtv_setsda(itv, 0); | ||
531 | ivtv_scldelay(itv); | ||
532 | ivtv_setscl(itv, 1); | ||
533 | if (!ivtv_waitscl(itv, 1)) { | ||
534 | IVTV_DEBUG_I2C("SCL could not be set high\n"); | ||
535 | return -EREMOTEIO; | ||
536 | } | ||
537 | ivtv_scldelay(itv); | ||
538 | ivtv_setsda(itv, 1); | ||
539 | if (!ivtv_waitsda(itv, 1)) { | ||
540 | IVTV_DEBUG_I2C("resetting I2C\n"); | ||
541 | for (i = 0; i < 16; ++i) { | ||
542 | ivtv_setscl(itv, 0); | ||
543 | ivtv_scldelay(itv); | ||
544 | ivtv_setscl(itv, 1); | ||
545 | ivtv_scldelay(itv); | ||
546 | ivtv_setsda(itv, 1); | ||
547 | } | ||
548 | ivtv_waitsda(itv, 1); | ||
549 | return -EREMOTEIO; | ||
550 | } | ||
551 | return 0; | ||
552 | } | ||
553 | |||
554 | /* Write a message to the given i2c slave. do_stop may be 0 to prevent | ||
555 | issuing the i2c stop condition (when following with a read) */ | ||
556 | static int ivtv_write(struct ivtv *itv, unsigned char addr, unsigned char *data, u32 len, int do_stop) | ||
557 | { | ||
558 | int retry, ret = -EREMOTEIO; | ||
559 | u32 i; | ||
560 | |||
561 | for (retry = 0; ret != 0 && retry < 8; ++retry) { | ||
562 | ret = ivtv_start(itv); | ||
563 | |||
564 | if (ret == 0) { | ||
565 | ret = ivtv_sendbyte(itv, addr<<1); | ||
566 | for (i = 0; ret == 0 && i < len; ++i) | ||
567 | ret = ivtv_sendbyte(itv, data[i]); | ||
568 | } | ||
569 | if (ret != 0 || do_stop) { | ||
570 | ivtv_stop(itv); | ||
571 | } | ||
572 | } | ||
573 | if (ret) | ||
574 | IVTV_DEBUG_I2C("i2c write to %x failed\n", addr); | ||
575 | return ret; | ||
576 | } | ||
577 | |||
578 | /* Read data from the given i2c slave. A stop condition is always issued. */ | ||
579 | static int ivtv_read(struct ivtv *itv, unsigned char addr, unsigned char *data, u32 len) | ||
580 | { | ||
581 | int retry, ret = -EREMOTEIO; | ||
582 | u32 i; | ||
583 | |||
584 | for (retry = 0; ret != 0 && retry < 8; ++retry) { | ||
585 | ret = ivtv_start(itv); | ||
586 | if (ret == 0) | ||
587 | ret = ivtv_sendbyte(itv, (addr << 1) | 1); | ||
588 | for (i = 0; ret == 0 && i < len; ++i) { | ||
589 | ret = ivtv_readbyte(itv, &data[i], i == len - 1); | ||
590 | } | ||
591 | ivtv_stop(itv); | ||
592 | } | ||
593 | if (ret) | ||
594 | IVTV_DEBUG_I2C("i2c read from %x failed\n", addr); | ||
595 | return ret; | ||
596 | } | ||
597 | |||
598 | /* Kernel i2c transfer implementation. Takes a number of messages to be read | ||
599 | or written. If a read follows a write, this will occur without an | ||
600 | intervening stop condition */ | ||
601 | static int ivtv_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) | ||
602 | { | ||
603 | struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap); | ||
604 | struct ivtv *itv = to_ivtv(v4l2_dev); | ||
605 | int retval; | ||
606 | int i; | ||
607 | |||
608 | mutex_lock(&itv->i2c_bus_lock); | ||
609 | for (i = retval = 0; retval == 0 && i < num; i++) { | ||
610 | if (msgs[i].flags & I2C_M_RD) | ||
611 | retval = ivtv_read(itv, msgs[i].addr, msgs[i].buf, msgs[i].len); | ||
612 | else { | ||
613 | /* if followed by a read, don't stop */ | ||
614 | int stop = !(i + 1 < num && msgs[i + 1].flags == I2C_M_RD); | ||
615 | |||
616 | retval = ivtv_write(itv, msgs[i].addr, msgs[i].buf, msgs[i].len, stop); | ||
617 | } | ||
618 | } | ||
619 | mutex_unlock(&itv->i2c_bus_lock); | ||
620 | return retval ? retval : num; | ||
621 | } | ||
622 | |||
623 | /* Kernel i2c capabilities */ | ||
624 | static u32 ivtv_functionality(struct i2c_adapter *adap) | ||
625 | { | ||
626 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | ||
627 | } | ||
628 | |||
629 | static struct i2c_algorithm ivtv_algo = { | ||
630 | .master_xfer = ivtv_xfer, | ||
631 | .functionality = ivtv_functionality, | ||
632 | }; | ||
633 | |||
634 | /* template for our-bit banger */ | ||
635 | static struct i2c_adapter ivtv_i2c_adap_hw_template = { | ||
636 | .name = "ivtv i2c driver", | ||
637 | .algo = &ivtv_algo, | ||
638 | .algo_data = NULL, /* filled from template */ | ||
639 | .owner = THIS_MODULE, | ||
640 | }; | ||
641 | |||
642 | static void ivtv_setscl_old(void *data, int state) | ||
643 | { | ||
644 | struct ivtv *itv = (struct ivtv *)data; | ||
645 | |||
646 | if (state) | ||
647 | itv->i2c_state |= 0x01; | ||
648 | else | ||
649 | itv->i2c_state &= ~0x01; | ||
650 | |||
651 | /* write them out */ | ||
652 | /* write bits are inverted */ | ||
653 | write_reg(~itv->i2c_state, IVTV_REG_I2C_SETSCL_OFFSET); | ||
654 | } | ||
655 | |||
656 | static void ivtv_setsda_old(void *data, int state) | ||
657 | { | ||
658 | struct ivtv *itv = (struct ivtv *)data; | ||
659 | |||
660 | if (state) | ||
661 | itv->i2c_state |= 0x01; | ||
662 | else | ||
663 | itv->i2c_state &= ~0x01; | ||
664 | |||
665 | /* write them out */ | ||
666 | /* write bits are inverted */ | ||
667 | write_reg(~itv->i2c_state, IVTV_REG_I2C_SETSDA_OFFSET); | ||
668 | } | ||
669 | |||
670 | static int ivtv_getscl_old(void *data) | ||
671 | { | ||
672 | struct ivtv *itv = (struct ivtv *)data; | ||
673 | |||
674 | return read_reg(IVTV_REG_I2C_GETSCL_OFFSET) & 1; | ||
675 | } | ||
676 | |||
677 | static int ivtv_getsda_old(void *data) | ||
678 | { | ||
679 | struct ivtv *itv = (struct ivtv *)data; | ||
680 | |||
681 | return read_reg(IVTV_REG_I2C_GETSDA_OFFSET) & 1; | ||
682 | } | ||
683 | |||
684 | /* template for i2c-bit-algo */ | ||
685 | static struct i2c_adapter ivtv_i2c_adap_template = { | ||
686 | .name = "ivtv i2c driver", | ||
687 | .algo = NULL, /* set by i2c-algo-bit */ | ||
688 | .algo_data = NULL, /* filled from template */ | ||
689 | .owner = THIS_MODULE, | ||
690 | }; | ||
691 | |||
692 | #define IVTV_ALGO_BIT_TIMEOUT (2) /* seconds */ | ||
693 | |||
694 | static const struct i2c_algo_bit_data ivtv_i2c_algo_template = { | ||
695 | .setsda = ivtv_setsda_old, | ||
696 | .setscl = ivtv_setscl_old, | ||
697 | .getsda = ivtv_getsda_old, | ||
698 | .getscl = ivtv_getscl_old, | ||
699 | .udelay = IVTV_DEFAULT_I2C_CLOCK_PERIOD / 2, /* microseconds */ | ||
700 | .timeout = IVTV_ALGO_BIT_TIMEOUT * HZ, /* jiffies */ | ||
701 | }; | ||
702 | |||
703 | static struct i2c_client ivtv_i2c_client_template = { | ||
704 | .name = "ivtv internal", | ||
705 | }; | ||
706 | |||
707 | /* init + register i2c adapter */ | ||
708 | int init_ivtv_i2c(struct ivtv *itv) | ||
709 | { | ||
710 | int retval; | ||
711 | |||
712 | IVTV_DEBUG_I2C("i2c init\n"); | ||
713 | |||
714 | /* Sanity checks for the I2C hardware arrays. They must be the | ||
715 | * same size. | ||
716 | */ | ||
717 | if (ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs)) { | ||
718 | IVTV_ERR("Mismatched I2C hardware arrays\n"); | ||
719 | return -ENODEV; | ||
720 | } | ||
721 | if (itv->options.newi2c > 0) { | ||
722 | memcpy(&itv->i2c_adap, &ivtv_i2c_adap_hw_template, | ||
723 | sizeof(struct i2c_adapter)); | ||
724 | } else { | ||
725 | memcpy(&itv->i2c_adap, &ivtv_i2c_adap_template, | ||
726 | sizeof(struct i2c_adapter)); | ||
727 | memcpy(&itv->i2c_algo, &ivtv_i2c_algo_template, | ||
728 | sizeof(struct i2c_algo_bit_data)); | ||
729 | } | ||
730 | itv->i2c_algo.udelay = itv->options.i2c_clock_period / 2; | ||
731 | itv->i2c_algo.data = itv; | ||
732 | itv->i2c_adap.algo_data = &itv->i2c_algo; | ||
733 | |||
734 | sprintf(itv->i2c_adap.name + strlen(itv->i2c_adap.name), " #%d", | ||
735 | itv->instance); | ||
736 | i2c_set_adapdata(&itv->i2c_adap, &itv->v4l2_dev); | ||
737 | |||
738 | memcpy(&itv->i2c_client, &ivtv_i2c_client_template, | ||
739 | sizeof(struct i2c_client)); | ||
740 | itv->i2c_client.adapter = &itv->i2c_adap; | ||
741 | itv->i2c_adap.dev.parent = &itv->pdev->dev; | ||
742 | |||
743 | IVTV_DEBUG_I2C("setting scl and sda to 1\n"); | ||
744 | ivtv_setscl(itv, 1); | ||
745 | ivtv_setsda(itv, 1); | ||
746 | |||
747 | if (itv->options.newi2c > 0) | ||
748 | retval = i2c_add_adapter(&itv->i2c_adap); | ||
749 | else | ||
750 | retval = i2c_bit_add_bus(&itv->i2c_adap); | ||
751 | |||
752 | return retval; | ||
753 | } | ||
754 | |||
755 | void exit_ivtv_i2c(struct ivtv *itv) | ||
756 | { | ||
757 | IVTV_DEBUG_I2C("i2c exit\n"); | ||
758 | |||
759 | i2c_del_adapter(&itv->i2c_adap); | ||
760 | } | ||
diff --git a/drivers/media/video/ivtv/ivtv-i2c.h b/drivers/media/video/ivtv/ivtv-i2c.h new file mode 100644 index 00000000000..9332920ca4f --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-i2c.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | I2C functions | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #ifndef IVTV_I2C_H | ||
22 | #define IVTV_I2C_H | ||
23 | |||
24 | struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv); | ||
25 | int ivtv_i2c_register(struct ivtv *itv, unsigned idx); | ||
26 | struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw); | ||
27 | |||
28 | /* init + register i2c algo-bit adapter */ | ||
29 | int init_ivtv_i2c(struct ivtv *itv); | ||
30 | void exit_ivtv_i2c(struct ivtv *itv); | ||
31 | |||
32 | #endif | ||
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c new file mode 100644 index 00000000000..3e5c090af11 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
@@ -0,0 +1,1932 @@ | |||
1 | /* | ||
2 | ioctl system call | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include "ivtv-driver.h" | ||
22 | #include "ivtv-version.h" | ||
23 | #include "ivtv-mailbox.h" | ||
24 | #include "ivtv-i2c.h" | ||
25 | #include "ivtv-queue.h" | ||
26 | #include "ivtv-fileops.h" | ||
27 | #include "ivtv-vbi.h" | ||
28 | #include "ivtv-routing.h" | ||
29 | #include "ivtv-streams.h" | ||
30 | #include "ivtv-yuv.h" | ||
31 | #include "ivtv-ioctl.h" | ||
32 | #include "ivtv-gpio.h" | ||
33 | #include "ivtv-controls.h" | ||
34 | #include "ivtv-cards.h" | ||
35 | #include <media/saa7127.h> | ||
36 | #include <media/tveeprom.h> | ||
37 | #include <media/v4l2-chip-ident.h> | ||
38 | #include <media/v4l2-event.h> | ||
39 | #include <linux/dvb/audio.h> | ||
40 | |||
41 | u16 ivtv_service2vbi(int type) | ||
42 | { | ||
43 | switch (type) { | ||
44 | case V4L2_SLICED_TELETEXT_B: | ||
45 | return IVTV_SLICED_TYPE_TELETEXT_B; | ||
46 | case V4L2_SLICED_CAPTION_525: | ||
47 | return IVTV_SLICED_TYPE_CAPTION_525; | ||
48 | case V4L2_SLICED_WSS_625: | ||
49 | return IVTV_SLICED_TYPE_WSS_625; | ||
50 | case V4L2_SLICED_VPS: | ||
51 | return IVTV_SLICED_TYPE_VPS; | ||
52 | default: | ||
53 | return 0; | ||
54 | } | ||
55 | } | ||
56 | |||
57 | static int valid_service_line(int field, int line, int is_pal) | ||
58 | { | ||
59 | return (is_pal && line >= 6 && (line != 23 || field == 0)) || | ||
60 | (!is_pal && line >= 10 && line < 22); | ||
61 | } | ||
62 | |||
63 | static u16 select_service_from_set(int field, int line, u16 set, int is_pal) | ||
64 | { | ||
65 | u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525); | ||
66 | int i; | ||
67 | |||
68 | set = set & valid_set; | ||
69 | if (set == 0 || !valid_service_line(field, line, is_pal)) { | ||
70 | return 0; | ||
71 | } | ||
72 | if (!is_pal) { | ||
73 | if (line == 21 && (set & V4L2_SLICED_CAPTION_525)) | ||
74 | return V4L2_SLICED_CAPTION_525; | ||
75 | } | ||
76 | else { | ||
77 | if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS)) | ||
78 | return V4L2_SLICED_VPS; | ||
79 | if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625)) | ||
80 | return V4L2_SLICED_WSS_625; | ||
81 | if (line == 23) | ||
82 | return 0; | ||
83 | } | ||
84 | for (i = 0; i < 32; i++) { | ||
85 | if ((1 << i) & set) | ||
86 | return 1 << i; | ||
87 | } | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) | ||
92 | { | ||
93 | u16 set = fmt->service_set; | ||
94 | int f, l; | ||
95 | |||
96 | fmt->service_set = 0; | ||
97 | for (f = 0; f < 2; f++) { | ||
98 | for (l = 0; l < 24; l++) { | ||
99 | fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal); | ||
100 | } | ||
101 | } | ||
102 | } | ||
103 | |||
104 | static void check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) | ||
105 | { | ||
106 | int f, l; | ||
107 | |||
108 | for (f = 0; f < 2; f++) { | ||
109 | for (l = 0; l < 24; l++) { | ||
110 | fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal); | ||
111 | } | ||
112 | } | ||
113 | } | ||
114 | |||
115 | u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt) | ||
116 | { | ||
117 | int f, l; | ||
118 | u16 set = 0; | ||
119 | |||
120 | for (f = 0; f < 2; f++) { | ||
121 | for (l = 0; l < 24; l++) { | ||
122 | set |= fmt->service_lines[f][l]; | ||
123 | } | ||
124 | } | ||
125 | return set; | ||
126 | } | ||
127 | |||
128 | void ivtv_set_osd_alpha(struct ivtv *itv) | ||
129 | { | ||
130 | ivtv_vapi(itv, CX2341X_OSD_SET_GLOBAL_ALPHA, 3, | ||
131 | itv->osd_global_alpha_state, itv->osd_global_alpha, !itv->osd_local_alpha_state); | ||
132 | ivtv_vapi(itv, CX2341X_OSD_SET_CHROMA_KEY, 2, itv->osd_chroma_key_state, itv->osd_chroma_key); | ||
133 | } | ||
134 | |||
135 | int ivtv_set_speed(struct ivtv *itv, int speed) | ||
136 | { | ||
137 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
138 | struct ivtv_stream *s; | ||
139 | int single_step = (speed == 1 || speed == -1); | ||
140 | DEFINE_WAIT(wait); | ||
141 | |||
142 | if (speed == 0) speed = 1000; | ||
143 | |||
144 | /* No change? */ | ||
145 | if (speed == itv->speed && !single_step) | ||
146 | return 0; | ||
147 | |||
148 | s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG]; | ||
149 | |||
150 | if (single_step && (speed < 0) == (itv->speed < 0)) { | ||
151 | /* Single step video and no need to change direction */ | ||
152 | ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0); | ||
153 | itv->speed = speed; | ||
154 | return 0; | ||
155 | } | ||
156 | if (single_step) | ||
157 | /* Need to change direction */ | ||
158 | speed = speed < 0 ? -1000 : 1000; | ||
159 | |||
160 | data[0] = (speed > 1000 || speed < -1000) ? 0x80000000 : 0; | ||
161 | data[0] |= (speed > 1000 || speed < -1500) ? 0x40000000 : 0; | ||
162 | data[1] = (speed < 0); | ||
163 | data[2] = speed < 0 ? 3 : 7; | ||
164 | data[3] = v4l2_ctrl_g_ctrl(itv->cxhdl.video_b_frames); | ||
165 | data[4] = (speed == 1500 || speed == 500) ? itv->speed_mute_audio : 0; | ||
166 | data[5] = 0; | ||
167 | data[6] = 0; | ||
168 | |||
169 | if (speed == 1500 || speed == -1500) data[0] |= 1; | ||
170 | else if (speed == 2000 || speed == -2000) data[0] |= 2; | ||
171 | else if (speed > -1000 && speed < 0) data[0] |= (-1000 / speed); | ||
172 | else if (speed < 1000 && speed > 0) data[0] |= (1000 / speed); | ||
173 | |||
174 | /* If not decoding, just change speed setting */ | ||
175 | if (atomic_read(&itv->decoding) > 0) { | ||
176 | int got_sig = 0; | ||
177 | |||
178 | /* Stop all DMA and decoding activity */ | ||
179 | ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 0); | ||
180 | |||
181 | /* Wait for any DMA to finish */ | ||
182 | prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); | ||
183 | while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) { | ||
184 | got_sig = signal_pending(current); | ||
185 | if (got_sig) | ||
186 | break; | ||
187 | got_sig = 0; | ||
188 | schedule(); | ||
189 | } | ||
190 | finish_wait(&itv->dma_waitq, &wait); | ||
191 | if (got_sig) | ||
192 | return -EINTR; | ||
193 | |||
194 | /* Change Speed safely */ | ||
195 | ivtv_api(itv, CX2341X_DEC_SET_PLAYBACK_SPEED, 7, data); | ||
196 | IVTV_DEBUG_INFO("Setting Speed to 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", | ||
197 | data[0], data[1], data[2], data[3], data[4], data[5], data[6]); | ||
198 | } | ||
199 | if (single_step) { | ||
200 | speed = (speed < 0) ? -1 : 1; | ||
201 | ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0); | ||
202 | } | ||
203 | itv->speed = speed; | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static int ivtv_validate_speed(int cur_speed, int new_speed) | ||
208 | { | ||
209 | int fact = new_speed < 0 ? -1 : 1; | ||
210 | int s; | ||
211 | |||
212 | if (cur_speed == 0) | ||
213 | cur_speed = 1000; | ||
214 | if (new_speed < 0) | ||
215 | new_speed = -new_speed; | ||
216 | if (cur_speed < 0) | ||
217 | cur_speed = -cur_speed; | ||
218 | |||
219 | if (cur_speed <= new_speed) { | ||
220 | if (new_speed > 1500) | ||
221 | return fact * 2000; | ||
222 | if (new_speed > 1000) | ||
223 | return fact * 1500; | ||
224 | } | ||
225 | else { | ||
226 | if (new_speed >= 2000) | ||
227 | return fact * 2000; | ||
228 | if (new_speed >= 1500) | ||
229 | return fact * 1500; | ||
230 | if (new_speed >= 1000) | ||
231 | return fact * 1000; | ||
232 | } | ||
233 | if (new_speed == 0) | ||
234 | return 1000; | ||
235 | if (new_speed == 1 || new_speed == 1000) | ||
236 | return fact * new_speed; | ||
237 | |||
238 | s = new_speed; | ||
239 | new_speed = 1000 / new_speed; | ||
240 | if (1000 / cur_speed == new_speed) | ||
241 | new_speed += (cur_speed < s) ? -1 : 1; | ||
242 | if (new_speed > 60) return 1000 / (fact * 60); | ||
243 | return 1000 / (fact * new_speed); | ||
244 | } | ||
245 | |||
246 | static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id, | ||
247 | struct video_command *vc, int try) | ||
248 | { | ||
249 | struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG]; | ||
250 | |||
251 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
252 | return -EINVAL; | ||
253 | |||
254 | switch (vc->cmd) { | ||
255 | case VIDEO_CMD_PLAY: { | ||
256 | vc->flags = 0; | ||
257 | vc->play.speed = ivtv_validate_speed(itv->speed, vc->play.speed); | ||
258 | if (vc->play.speed < 0) | ||
259 | vc->play.format = VIDEO_PLAY_FMT_GOP; | ||
260 | if (try) break; | ||
261 | |||
262 | if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG) | ||
263 | return -EBUSY; | ||
264 | if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) { | ||
265 | /* forces ivtv_set_speed to be called */ | ||
266 | itv->speed = 0; | ||
267 | } | ||
268 | return ivtv_start_decoding(id, vc->play.speed); | ||
269 | } | ||
270 | |||
271 | case VIDEO_CMD_STOP: | ||
272 | vc->flags &= VIDEO_CMD_STOP_IMMEDIATELY|VIDEO_CMD_STOP_TO_BLACK; | ||
273 | if (vc->flags & VIDEO_CMD_STOP_IMMEDIATELY) | ||
274 | vc->stop.pts = 0; | ||
275 | if (try) break; | ||
276 | if (atomic_read(&itv->decoding) == 0) | ||
277 | return 0; | ||
278 | if (itv->output_mode != OUT_MPG) | ||
279 | return -EBUSY; | ||
280 | |||
281 | itv->output_mode = OUT_NONE; | ||
282 | return ivtv_stop_v4l2_decode_stream(s, vc->flags, vc->stop.pts); | ||
283 | |||
284 | case VIDEO_CMD_FREEZE: | ||
285 | vc->flags &= VIDEO_CMD_FREEZE_TO_BLACK; | ||
286 | if (try) break; | ||
287 | if (itv->output_mode != OUT_MPG) | ||
288 | return -EBUSY; | ||
289 | if (atomic_read(&itv->decoding) > 0) { | ||
290 | ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, | ||
291 | (vc->flags & VIDEO_CMD_FREEZE_TO_BLACK) ? 1 : 0); | ||
292 | set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags); | ||
293 | } | ||
294 | break; | ||
295 | |||
296 | case VIDEO_CMD_CONTINUE: | ||
297 | vc->flags = 0; | ||
298 | if (try) break; | ||
299 | if (itv->output_mode != OUT_MPG) | ||
300 | return -EBUSY; | ||
301 | if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) { | ||
302 | int speed = itv->speed; | ||
303 | itv->speed = 0; | ||
304 | return ivtv_start_decoding(id, speed); | ||
305 | } | ||
306 | break; | ||
307 | |||
308 | default: | ||
309 | return -EINVAL; | ||
310 | } | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt) | ||
315 | { | ||
316 | struct ivtv *itv = fh2id(fh)->itv; | ||
317 | struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; | ||
318 | |||
319 | vbifmt->reserved[0] = 0; | ||
320 | vbifmt->reserved[1] = 0; | ||
321 | if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT)) | ||
322 | return -EINVAL; | ||
323 | vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; | ||
324 | if (itv->is_60hz) { | ||
325 | vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525; | ||
326 | vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525; | ||
327 | } else { | ||
328 | vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625; | ||
329 | vbifmt->service_lines[0][16] = V4L2_SLICED_VPS; | ||
330 | } | ||
331 | vbifmt->service_set = ivtv_get_service_set(vbifmt); | ||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) | ||
336 | { | ||
337 | struct ivtv_open_id *id = fh2id(fh); | ||
338 | struct ivtv *itv = id->itv; | ||
339 | struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; | ||
340 | |||
341 | pixfmt->width = itv->cxhdl.width; | ||
342 | pixfmt->height = itv->cxhdl.height; | ||
343 | pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
344 | pixfmt->field = V4L2_FIELD_INTERLACED; | ||
345 | pixfmt->priv = 0; | ||
346 | if (id->type == IVTV_ENC_STREAM_TYPE_YUV) { | ||
347 | pixfmt->pixelformat = V4L2_PIX_FMT_HM12; | ||
348 | /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */ | ||
349 | pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2; | ||
350 | pixfmt->bytesperline = 720; | ||
351 | } else { | ||
352 | pixfmt->pixelformat = V4L2_PIX_FMT_MPEG; | ||
353 | pixfmt->sizeimage = 128 * 1024; | ||
354 | pixfmt->bytesperline = 0; | ||
355 | } | ||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) | ||
360 | { | ||
361 | struct ivtv *itv = fh2id(fh)->itv; | ||
362 | struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi; | ||
363 | |||
364 | vbifmt->sampling_rate = 27000000; | ||
365 | vbifmt->offset = 248; | ||
366 | vbifmt->samples_per_line = itv->vbi.raw_decoder_line_size - 4; | ||
367 | vbifmt->sample_format = V4L2_PIX_FMT_GREY; | ||
368 | vbifmt->start[0] = itv->vbi.start[0]; | ||
369 | vbifmt->start[1] = itv->vbi.start[1]; | ||
370 | vbifmt->count[0] = vbifmt->count[1] = itv->vbi.count; | ||
371 | vbifmt->flags = 0; | ||
372 | vbifmt->reserved[0] = 0; | ||
373 | vbifmt->reserved[1] = 0; | ||
374 | return 0; | ||
375 | } | ||
376 | |||
377 | static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) | ||
378 | { | ||
379 | struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; | ||
380 | struct ivtv_open_id *id = fh2id(fh); | ||
381 | struct ivtv *itv = id->itv; | ||
382 | |||
383 | vbifmt->reserved[0] = 0; | ||
384 | vbifmt->reserved[1] = 0; | ||
385 | vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; | ||
386 | |||
387 | if (id->type == IVTV_DEC_STREAM_TYPE_VBI) { | ||
388 | vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 : | ||
389 | V4L2_SLICED_VBI_525; | ||
390 | ivtv_expand_service_set(vbifmt, itv->is_50hz); | ||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | v4l2_subdev_call(itv->sd_video, vbi, g_sliced_fmt, vbifmt); | ||
395 | vbifmt->service_set = ivtv_get_service_set(vbifmt); | ||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) | ||
400 | { | ||
401 | struct ivtv_open_id *id = fh2id(fh); | ||
402 | struct ivtv *itv = id->itv; | ||
403 | struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; | ||
404 | |||
405 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
406 | return -EINVAL; | ||
407 | pixfmt->width = itv->main_rect.width; | ||
408 | pixfmt->height = itv->main_rect.height; | ||
409 | pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
410 | pixfmt->field = V4L2_FIELD_INTERLACED; | ||
411 | pixfmt->priv = 0; | ||
412 | if (id->type == IVTV_DEC_STREAM_TYPE_YUV) { | ||
413 | switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) { | ||
414 | case IVTV_YUV_MODE_INTERLACED: | ||
415 | pixfmt->field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ? | ||
416 | V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB; | ||
417 | break; | ||
418 | case IVTV_YUV_MODE_PROGRESSIVE: | ||
419 | pixfmt->field = V4L2_FIELD_NONE; | ||
420 | break; | ||
421 | default: | ||
422 | pixfmt->field = V4L2_FIELD_ANY; | ||
423 | break; | ||
424 | } | ||
425 | pixfmt->pixelformat = V4L2_PIX_FMT_HM12; | ||
426 | pixfmt->bytesperline = 720; | ||
427 | pixfmt->width = itv->yuv_info.v4l2_src_w; | ||
428 | pixfmt->height = itv->yuv_info.v4l2_src_h; | ||
429 | /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ | ||
430 | pixfmt->sizeimage = | ||
431 | 1080 * ((pixfmt->height + 31) & ~31); | ||
432 | } else { | ||
433 | pixfmt->pixelformat = V4L2_PIX_FMT_MPEG; | ||
434 | pixfmt->sizeimage = 128 * 1024; | ||
435 | pixfmt->bytesperline = 0; | ||
436 | } | ||
437 | return 0; | ||
438 | } | ||
439 | |||
440 | static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) | ||
441 | { | ||
442 | struct ivtv *itv = fh2id(fh)->itv; | ||
443 | struct v4l2_window *winfmt = &fmt->fmt.win; | ||
444 | |||
445 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
446 | return -EINVAL; | ||
447 | winfmt->chromakey = itv->osd_chroma_key; | ||
448 | winfmt->global_alpha = itv->osd_global_alpha; | ||
449 | winfmt->field = V4L2_FIELD_INTERLACED; | ||
450 | winfmt->clips = NULL; | ||
451 | winfmt->clipcount = 0; | ||
452 | winfmt->bitmap = NULL; | ||
453 | winfmt->w.top = winfmt->w.left = 0; | ||
454 | winfmt->w.width = itv->osd_rect.width; | ||
455 | winfmt->w.height = itv->osd_rect.height; | ||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt) | ||
460 | { | ||
461 | return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt); | ||
462 | } | ||
463 | |||
464 | static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) | ||
465 | { | ||
466 | struct ivtv_open_id *id = fh2id(fh); | ||
467 | struct ivtv *itv = id->itv; | ||
468 | int w = fmt->fmt.pix.width; | ||
469 | int h = fmt->fmt.pix.height; | ||
470 | int min_h = 2; | ||
471 | |||
472 | w = min(w, 720); | ||
473 | w = max(w, 2); | ||
474 | if (id->type == IVTV_ENC_STREAM_TYPE_YUV) { | ||
475 | /* YUV height must be a multiple of 32 */ | ||
476 | h &= ~0x1f; | ||
477 | min_h = 32; | ||
478 | } | ||
479 | h = min(h, itv->is_50hz ? 576 : 480); | ||
480 | h = max(h, min_h); | ||
481 | ivtv_g_fmt_vid_cap(file, fh, fmt); | ||
482 | fmt->fmt.pix.width = w; | ||
483 | fmt->fmt.pix.height = h; | ||
484 | return 0; | ||
485 | } | ||
486 | |||
487 | static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) | ||
488 | { | ||
489 | return ivtv_g_fmt_vbi_cap(file, fh, fmt); | ||
490 | } | ||
491 | |||
492 | static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) | ||
493 | { | ||
494 | struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; | ||
495 | struct ivtv_open_id *id = fh2id(fh); | ||
496 | struct ivtv *itv = id->itv; | ||
497 | |||
498 | if (id->type == IVTV_DEC_STREAM_TYPE_VBI) | ||
499 | return ivtv_g_fmt_sliced_vbi_cap(file, fh, fmt); | ||
500 | |||
501 | /* set sliced VBI capture format */ | ||
502 | vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; | ||
503 | vbifmt->reserved[0] = 0; | ||
504 | vbifmt->reserved[1] = 0; | ||
505 | |||
506 | if (vbifmt->service_set) | ||
507 | ivtv_expand_service_set(vbifmt, itv->is_50hz); | ||
508 | check_service_set(vbifmt, itv->is_50hz); | ||
509 | vbifmt->service_set = ivtv_get_service_set(vbifmt); | ||
510 | return 0; | ||
511 | } | ||
512 | |||
513 | static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) | ||
514 | { | ||
515 | struct ivtv_open_id *id = fh2id(fh); | ||
516 | s32 w = fmt->fmt.pix.width; | ||
517 | s32 h = fmt->fmt.pix.height; | ||
518 | int field = fmt->fmt.pix.field; | ||
519 | int ret = ivtv_g_fmt_vid_out(file, fh, fmt); | ||
520 | |||
521 | w = min(w, 720); | ||
522 | w = max(w, 2); | ||
523 | /* Why can the height be 576 even when the output is NTSC? | ||
524 | |||
525 | Internally the buffers of the PVR350 are always set to 720x576. The | ||
526 | decoded video frame will always be placed in the top left corner of | ||
527 | this buffer. For any video which is not 720x576, the buffer will | ||
528 | then be cropped to remove the unused right and lower areas, with | ||
529 | the remaining image being scaled by the hardware to fit the display | ||
530 | area. The video can be scaled both up and down, so a 720x480 video | ||
531 | can be displayed full-screen on PAL and a 720x576 video can be | ||
532 | displayed without cropping on NTSC. | ||
533 | |||
534 | Note that the scaling only occurs on the video stream, the osd | ||
535 | resolution is locked to the broadcast standard and not scaled. | ||
536 | |||
537 | Thanks to Ian Armstrong for this explanation. */ | ||
538 | h = min(h, 576); | ||
539 | h = max(h, 2); | ||
540 | if (id->type == IVTV_DEC_STREAM_TYPE_YUV) | ||
541 | fmt->fmt.pix.field = field; | ||
542 | fmt->fmt.pix.width = w; | ||
543 | fmt->fmt.pix.height = h; | ||
544 | return ret; | ||
545 | } | ||
546 | |||
547 | static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) | ||
548 | { | ||
549 | struct ivtv *itv = fh2id(fh)->itv; | ||
550 | u32 chromakey = fmt->fmt.win.chromakey; | ||
551 | u8 global_alpha = fmt->fmt.win.global_alpha; | ||
552 | |||
553 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
554 | return -EINVAL; | ||
555 | ivtv_g_fmt_vid_out_overlay(file, fh, fmt); | ||
556 | fmt->fmt.win.chromakey = chromakey; | ||
557 | fmt->fmt.win.global_alpha = global_alpha; | ||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt) | ||
562 | { | ||
563 | return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt); | ||
564 | } | ||
565 | |||
566 | static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) | ||
567 | { | ||
568 | struct ivtv_open_id *id = fh2id(fh); | ||
569 | struct ivtv *itv = id->itv; | ||
570 | struct v4l2_mbus_framefmt mbus_fmt; | ||
571 | int ret = ivtv_try_fmt_vid_cap(file, fh, fmt); | ||
572 | int w = fmt->fmt.pix.width; | ||
573 | int h = fmt->fmt.pix.height; | ||
574 | |||
575 | if (ret) | ||
576 | return ret; | ||
577 | |||
578 | if (itv->cxhdl.width == w && itv->cxhdl.height == h) | ||
579 | return 0; | ||
580 | |||
581 | if (atomic_read(&itv->capturing) > 0) | ||
582 | return -EBUSY; | ||
583 | |||
584 | itv->cxhdl.width = w; | ||
585 | itv->cxhdl.height = h; | ||
586 | if (v4l2_ctrl_g_ctrl(itv->cxhdl.video_encoding) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) | ||
587 | fmt->fmt.pix.width /= 2; | ||
588 | mbus_fmt.width = fmt->fmt.pix.width; | ||
589 | mbus_fmt.height = h; | ||
590 | mbus_fmt.code = V4L2_MBUS_FMT_FIXED; | ||
591 | v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &mbus_fmt); | ||
592 | return ivtv_g_fmt_vid_cap(file, fh, fmt); | ||
593 | } | ||
594 | |||
595 | static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) | ||
596 | { | ||
597 | struct ivtv *itv = fh2id(fh)->itv; | ||
598 | |||
599 | if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0) | ||
600 | return -EBUSY; | ||
601 | itv->vbi.sliced_in->service_set = 0; | ||
602 | itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
603 | v4l2_subdev_call(itv->sd_video, vbi, s_raw_fmt, &fmt->fmt.vbi); | ||
604 | return ivtv_g_fmt_vbi_cap(file, fh, fmt); | ||
605 | } | ||
606 | |||
607 | static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) | ||
608 | { | ||
609 | struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; | ||
610 | struct ivtv_open_id *id = fh2id(fh); | ||
611 | struct ivtv *itv = id->itv; | ||
612 | int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt); | ||
613 | |||
614 | if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI) | ||
615 | return ret; | ||
616 | |||
617 | check_service_set(vbifmt, itv->is_50hz); | ||
618 | if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0) | ||
619 | return -EBUSY; | ||
620 | itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; | ||
621 | v4l2_subdev_call(itv->sd_video, vbi, s_sliced_fmt, vbifmt); | ||
622 | memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in)); | ||
623 | return 0; | ||
624 | } | ||
625 | |||
626 | static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) | ||
627 | { | ||
628 | struct ivtv_open_id *id = fh2id(fh); | ||
629 | struct ivtv *itv = id->itv; | ||
630 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
631 | int ret = ivtv_try_fmt_vid_out(file, fh, fmt); | ||
632 | |||
633 | if (ret) | ||
634 | return ret; | ||
635 | |||
636 | if (id->type != IVTV_DEC_STREAM_TYPE_YUV) | ||
637 | return 0; | ||
638 | |||
639 | /* Return now if we already have some frame data */ | ||
640 | if (yi->stream_size) | ||
641 | return -EBUSY; | ||
642 | |||
643 | yi->v4l2_src_w = fmt->fmt.pix.width; | ||
644 | yi->v4l2_src_h = fmt->fmt.pix.height; | ||
645 | |||
646 | switch (fmt->fmt.pix.field) { | ||
647 | case V4L2_FIELD_NONE: | ||
648 | yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE; | ||
649 | break; | ||
650 | case V4L2_FIELD_ANY: | ||
651 | yi->lace_mode = IVTV_YUV_MODE_AUTO; | ||
652 | break; | ||
653 | case V4L2_FIELD_INTERLACED_BT: | ||
654 | yi->lace_mode = | ||
655 | IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD; | ||
656 | break; | ||
657 | case V4L2_FIELD_INTERLACED_TB: | ||
658 | default: | ||
659 | yi->lace_mode = IVTV_YUV_MODE_INTERLACED; | ||
660 | break; | ||
661 | } | ||
662 | yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1; | ||
663 | |||
664 | if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) | ||
665 | itv->dma_data_req_size = | ||
666 | 1080 * ((yi->v4l2_src_h + 31) & ~31); | ||
667 | |||
668 | return 0; | ||
669 | } | ||
670 | |||
671 | static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) | ||
672 | { | ||
673 | struct ivtv *itv = fh2id(fh)->itv; | ||
674 | int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt); | ||
675 | |||
676 | if (ret == 0) { | ||
677 | itv->osd_chroma_key = fmt->fmt.win.chromakey; | ||
678 | itv->osd_global_alpha = fmt->fmt.win.global_alpha; | ||
679 | ivtv_set_osd_alpha(itv); | ||
680 | } | ||
681 | return ret; | ||
682 | } | ||
683 | |||
684 | static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip) | ||
685 | { | ||
686 | struct ivtv *itv = fh2id(fh)->itv; | ||
687 | |||
688 | chip->ident = V4L2_IDENT_NONE; | ||
689 | chip->revision = 0; | ||
690 | if (chip->match.type == V4L2_CHIP_MATCH_HOST) { | ||
691 | if (v4l2_chip_match_host(&chip->match)) | ||
692 | chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416; | ||
693 | return 0; | ||
694 | } | ||
695 | if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER && | ||
696 | chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) | ||
697 | return -EINVAL; | ||
698 | /* TODO: is this correct? */ | ||
699 | return ivtv_call_all_err(itv, core, g_chip_ident, chip); | ||
700 | } | ||
701 | |||
702 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
703 | static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg) | ||
704 | { | ||
705 | struct v4l2_dbg_register *regs = arg; | ||
706 | volatile u8 __iomem *reg_start; | ||
707 | |||
708 | if (!capable(CAP_SYS_ADMIN)) | ||
709 | return -EPERM; | ||
710 | if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE) | ||
711 | reg_start = itv->reg_mem - IVTV_REG_OFFSET; | ||
712 | else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET && | ||
713 | regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE) | ||
714 | reg_start = itv->dec_mem - IVTV_DECODER_OFFSET; | ||
715 | else if (regs->reg < IVTV_ENCODER_SIZE) | ||
716 | reg_start = itv->enc_mem; | ||
717 | else | ||
718 | return -EINVAL; | ||
719 | |||
720 | regs->size = 4; | ||
721 | if (cmd == VIDIOC_DBG_G_REGISTER) | ||
722 | regs->val = readl(regs->reg + reg_start); | ||
723 | else | ||
724 | writel(regs->val, regs->reg + reg_start); | ||
725 | return 0; | ||
726 | } | ||
727 | |||
728 | static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) | ||
729 | { | ||
730 | struct ivtv *itv = fh2id(fh)->itv; | ||
731 | |||
732 | if (v4l2_chip_match_host(®->match)) | ||
733 | return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg); | ||
734 | /* TODO: subdev errors should not be ignored, this should become a | ||
735 | subdev helper function. */ | ||
736 | ivtv_call_all(itv, core, g_register, reg); | ||
737 | return 0; | ||
738 | } | ||
739 | |||
740 | static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) | ||
741 | { | ||
742 | struct ivtv *itv = fh2id(fh)->itv; | ||
743 | |||
744 | if (v4l2_chip_match_host(®->match)) | ||
745 | return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg); | ||
746 | /* TODO: subdev errors should not be ignored, this should become a | ||
747 | subdev helper function. */ | ||
748 | ivtv_call_all(itv, core, s_register, reg); | ||
749 | return 0; | ||
750 | } | ||
751 | #endif | ||
752 | |||
753 | static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap) | ||
754 | { | ||
755 | struct ivtv *itv = fh2id(fh)->itv; | ||
756 | |||
757 | strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); | ||
758 | strlcpy(vcap->card, itv->card_name, sizeof(vcap->card)); | ||
759 | snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev)); | ||
760 | vcap->capabilities = itv->v4l2_cap; /* capabilities */ | ||
761 | return 0; | ||
762 | } | ||
763 | |||
764 | static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin) | ||
765 | { | ||
766 | struct ivtv *itv = fh2id(fh)->itv; | ||
767 | |||
768 | return ivtv_get_audio_input(itv, vin->index, vin); | ||
769 | } | ||
770 | |||
771 | static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin) | ||
772 | { | ||
773 | struct ivtv *itv = fh2id(fh)->itv; | ||
774 | |||
775 | vin->index = itv->audio_input; | ||
776 | return ivtv_get_audio_input(itv, vin->index, vin); | ||
777 | } | ||
778 | |||
779 | static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout) | ||
780 | { | ||
781 | struct ivtv *itv = fh2id(fh)->itv; | ||
782 | |||
783 | if (vout->index >= itv->nof_audio_inputs) | ||
784 | return -EINVAL; | ||
785 | |||
786 | itv->audio_input = vout->index; | ||
787 | ivtv_audio_set_io(itv); | ||
788 | |||
789 | return 0; | ||
790 | } | ||
791 | |||
792 | static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin) | ||
793 | { | ||
794 | struct ivtv *itv = fh2id(fh)->itv; | ||
795 | |||
796 | /* set it to defaults from our table */ | ||
797 | return ivtv_get_audio_output(itv, vin->index, vin); | ||
798 | } | ||
799 | |||
800 | static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin) | ||
801 | { | ||
802 | struct ivtv *itv = fh2id(fh)->itv; | ||
803 | |||
804 | vin->index = 0; | ||
805 | return ivtv_get_audio_output(itv, vin->index, vin); | ||
806 | } | ||
807 | |||
808 | static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout) | ||
809 | { | ||
810 | struct ivtv *itv = fh2id(fh)->itv; | ||
811 | |||
812 | return ivtv_get_audio_output(itv, vout->index, vout); | ||
813 | } | ||
814 | |||
815 | static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin) | ||
816 | { | ||
817 | struct ivtv *itv = fh2id(fh)->itv; | ||
818 | |||
819 | /* set it to defaults from our table */ | ||
820 | return ivtv_get_input(itv, vin->index, vin); | ||
821 | } | ||
822 | |||
823 | static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout) | ||
824 | { | ||
825 | struct ivtv *itv = fh2id(fh)->itv; | ||
826 | |||
827 | return ivtv_get_output(itv, vout->index, vout); | ||
828 | } | ||
829 | |||
830 | static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap) | ||
831 | { | ||
832 | struct ivtv_open_id *id = fh2id(fh); | ||
833 | struct ivtv *itv = id->itv; | ||
834 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
835 | int streamtype; | ||
836 | |||
837 | streamtype = id->type; | ||
838 | |||
839 | if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) | ||
840 | return -EINVAL; | ||
841 | cropcap->bounds.top = cropcap->bounds.left = 0; | ||
842 | cropcap->bounds.width = 720; | ||
843 | if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
844 | cropcap->bounds.height = itv->is_50hz ? 576 : 480; | ||
845 | cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10; | ||
846 | cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11; | ||
847 | } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { | ||
848 | if (yi->track_osd) { | ||
849 | cropcap->bounds.width = yi->osd_full_w; | ||
850 | cropcap->bounds.height = yi->osd_full_h; | ||
851 | } else { | ||
852 | cropcap->bounds.width = 720; | ||
853 | cropcap->bounds.height = | ||
854 | itv->is_out_50hz ? 576 : 480; | ||
855 | } | ||
856 | cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; | ||
857 | cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; | ||
858 | } else { | ||
859 | cropcap->bounds.height = itv->is_out_50hz ? 576 : 480; | ||
860 | cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; | ||
861 | cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; | ||
862 | } | ||
863 | cropcap->defrect = cropcap->bounds; | ||
864 | return 0; | ||
865 | } | ||
866 | |||
867 | static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop) | ||
868 | { | ||
869 | struct ivtv_open_id *id = fh2id(fh); | ||
870 | struct ivtv *itv = id->itv; | ||
871 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
872 | int streamtype; | ||
873 | |||
874 | streamtype = id->type; | ||
875 | |||
876 | if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && | ||
877 | (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { | ||
878 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { | ||
879 | yi->main_rect = crop->c; | ||
880 | return 0; | ||
881 | } else { | ||
882 | if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, | ||
883 | crop->c.width, crop->c.height, crop->c.left, crop->c.top)) { | ||
884 | itv->main_rect = crop->c; | ||
885 | return 0; | ||
886 | } | ||
887 | } | ||
888 | return -EINVAL; | ||
889 | } | ||
890 | return -EINVAL; | ||
891 | } | ||
892 | |||
893 | static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) | ||
894 | { | ||
895 | struct ivtv_open_id *id = fh2id(fh); | ||
896 | struct ivtv *itv = id->itv; | ||
897 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
898 | int streamtype; | ||
899 | |||
900 | streamtype = id->type; | ||
901 | |||
902 | if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && | ||
903 | (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { | ||
904 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) | ||
905 | crop->c = yi->main_rect; | ||
906 | else | ||
907 | crop->c = itv->main_rect; | ||
908 | return 0; | ||
909 | } | ||
910 | return -EINVAL; | ||
911 | } | ||
912 | |||
913 | static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt) | ||
914 | { | ||
915 | static struct v4l2_fmtdesc formats[] = { | ||
916 | { 0, 0, 0, | ||
917 | "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12, | ||
918 | { 0, 0, 0, 0 } | ||
919 | }, | ||
920 | { 1, 0, V4L2_FMT_FLAG_COMPRESSED, | ||
921 | "MPEG", V4L2_PIX_FMT_MPEG, | ||
922 | { 0, 0, 0, 0 } | ||
923 | } | ||
924 | }; | ||
925 | enum v4l2_buf_type type = fmt->type; | ||
926 | |||
927 | if (fmt->index > 1) | ||
928 | return -EINVAL; | ||
929 | |||
930 | *fmt = formats[fmt->index]; | ||
931 | fmt->type = type; | ||
932 | return 0; | ||
933 | } | ||
934 | |||
935 | static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt) | ||
936 | { | ||
937 | struct ivtv *itv = fh2id(fh)->itv; | ||
938 | |||
939 | static struct v4l2_fmtdesc formats[] = { | ||
940 | { 0, 0, 0, | ||
941 | "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12, | ||
942 | { 0, 0, 0, 0 } | ||
943 | }, | ||
944 | { 1, 0, V4L2_FMT_FLAG_COMPRESSED, | ||
945 | "MPEG", V4L2_PIX_FMT_MPEG, | ||
946 | { 0, 0, 0, 0 } | ||
947 | } | ||
948 | }; | ||
949 | enum v4l2_buf_type type = fmt->type; | ||
950 | |||
951 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
952 | return -EINVAL; | ||
953 | |||
954 | if (fmt->index > 1) | ||
955 | return -EINVAL; | ||
956 | |||
957 | *fmt = formats[fmt->index]; | ||
958 | fmt->type = type; | ||
959 | |||
960 | return 0; | ||
961 | } | ||
962 | |||
963 | static int ivtv_g_input(struct file *file, void *fh, unsigned int *i) | ||
964 | { | ||
965 | struct ivtv *itv = fh2id(fh)->itv; | ||
966 | |||
967 | *i = itv->active_input; | ||
968 | |||
969 | return 0; | ||
970 | } | ||
971 | |||
972 | int ivtv_s_input(struct file *file, void *fh, unsigned int inp) | ||
973 | { | ||
974 | struct ivtv *itv = fh2id(fh)->itv; | ||
975 | |||
976 | if (inp < 0 || inp >= itv->nof_inputs) | ||
977 | return -EINVAL; | ||
978 | |||
979 | if (inp == itv->active_input) { | ||
980 | IVTV_DEBUG_INFO("Input unchanged\n"); | ||
981 | return 0; | ||
982 | } | ||
983 | |||
984 | if (atomic_read(&itv->capturing) > 0) { | ||
985 | return -EBUSY; | ||
986 | } | ||
987 | |||
988 | IVTV_DEBUG_INFO("Changing input from %d to %d\n", | ||
989 | itv->active_input, inp); | ||
990 | |||
991 | itv->active_input = inp; | ||
992 | /* Set the audio input to whatever is appropriate for the | ||
993 | input type. */ | ||
994 | itv->audio_input = itv->card->video_inputs[inp].audio_index; | ||
995 | |||
996 | /* prevent others from messing with the streams until | ||
997 | we're finished changing inputs. */ | ||
998 | ivtv_mute(itv); | ||
999 | ivtv_video_set_io(itv); | ||
1000 | ivtv_audio_set_io(itv); | ||
1001 | ivtv_unmute(itv); | ||
1002 | |||
1003 | return 0; | ||
1004 | } | ||
1005 | |||
1006 | static int ivtv_g_output(struct file *file, void *fh, unsigned int *i) | ||
1007 | { | ||
1008 | struct ivtv *itv = fh2id(fh)->itv; | ||
1009 | |||
1010 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
1011 | return -EINVAL; | ||
1012 | |||
1013 | *i = itv->active_output; | ||
1014 | |||
1015 | return 0; | ||
1016 | } | ||
1017 | |||
1018 | static int ivtv_s_output(struct file *file, void *fh, unsigned int outp) | ||
1019 | { | ||
1020 | struct ivtv *itv = fh2id(fh)->itv; | ||
1021 | |||
1022 | if (outp >= itv->card->nof_outputs) | ||
1023 | return -EINVAL; | ||
1024 | |||
1025 | if (outp == itv->active_output) { | ||
1026 | IVTV_DEBUG_INFO("Output unchanged\n"); | ||
1027 | return 0; | ||
1028 | } | ||
1029 | IVTV_DEBUG_INFO("Changing output from %d to %d\n", | ||
1030 | itv->active_output, outp); | ||
1031 | |||
1032 | itv->active_output = outp; | ||
1033 | ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing, | ||
1034 | SAA7127_INPUT_TYPE_NORMAL, | ||
1035 | itv->card->video_outputs[outp].video_output, 0); | ||
1036 | |||
1037 | return 0; | ||
1038 | } | ||
1039 | |||
1040 | static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) | ||
1041 | { | ||
1042 | struct ivtv *itv = fh2id(fh)->itv; | ||
1043 | |||
1044 | if (vf->tuner != 0) | ||
1045 | return -EINVAL; | ||
1046 | |||
1047 | ivtv_call_all(itv, tuner, g_frequency, vf); | ||
1048 | return 0; | ||
1049 | } | ||
1050 | |||
1051 | int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) | ||
1052 | { | ||
1053 | struct ivtv *itv = fh2id(fh)->itv; | ||
1054 | |||
1055 | if (vf->tuner != 0) | ||
1056 | return -EINVAL; | ||
1057 | |||
1058 | ivtv_mute(itv); | ||
1059 | IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency); | ||
1060 | ivtv_call_all(itv, tuner, s_frequency, vf); | ||
1061 | ivtv_unmute(itv); | ||
1062 | return 0; | ||
1063 | } | ||
1064 | |||
1065 | static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std) | ||
1066 | { | ||
1067 | struct ivtv *itv = fh2id(fh)->itv; | ||
1068 | |||
1069 | *std = itv->std; | ||
1070 | return 0; | ||
1071 | } | ||
1072 | |||
1073 | void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std) | ||
1074 | { | ||
1075 | itv->std = *std; | ||
1076 | itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0; | ||
1077 | itv->is_50hz = !itv->is_60hz; | ||
1078 | cx2341x_handler_set_50hz(&itv->cxhdl, itv->is_50hz); | ||
1079 | itv->cxhdl.width = 720; | ||
1080 | itv->cxhdl.height = itv->is_50hz ? 576 : 480; | ||
1081 | itv->vbi.count = itv->is_50hz ? 18 : 12; | ||
1082 | itv->vbi.start[0] = itv->is_50hz ? 6 : 10; | ||
1083 | itv->vbi.start[1] = itv->is_50hz ? 318 : 273; | ||
1084 | |||
1085 | if (itv->hw_flags & IVTV_HW_CX25840) | ||
1086 | itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284; | ||
1087 | |||
1088 | /* Tuner */ | ||
1089 | ivtv_call_all(itv, core, s_std, itv->std); | ||
1090 | } | ||
1091 | |||
1092 | void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std) | ||
1093 | { | ||
1094 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
1095 | DEFINE_WAIT(wait); | ||
1096 | int f; | ||
1097 | |||
1098 | /* set display standard */ | ||
1099 | itv->std_out = *std; | ||
1100 | itv->is_out_60hz = (*std & V4L2_STD_525_60) ? 1 : 0; | ||
1101 | itv->is_out_50hz = !itv->is_out_60hz; | ||
1102 | ivtv_call_all(itv, video, s_std_output, itv->std_out); | ||
1103 | |||
1104 | /* | ||
1105 | * The next firmware call is time sensitive. Time it to | ||
1106 | * avoid risk of a hard lock, by trying to ensure the call | ||
1107 | * happens within the first 100 lines of the top field. | ||
1108 | * Make 4 attempts to sync to the decoder before giving up. | ||
1109 | */ | ||
1110 | for (f = 0; f < 4; f++) { | ||
1111 | prepare_to_wait(&itv->vsync_waitq, &wait, | ||
1112 | TASK_UNINTERRUPTIBLE); | ||
1113 | if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100) | ||
1114 | break; | ||
1115 | schedule_timeout(msecs_to_jiffies(25)); | ||
1116 | } | ||
1117 | finish_wait(&itv->vsync_waitq, &wait); | ||
1118 | |||
1119 | if (f == 4) | ||
1120 | IVTV_WARN("Mode change failed to sync to decoder\n"); | ||
1121 | |||
1122 | ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz); | ||
1123 | itv->main_rect.left = 0; | ||
1124 | itv->main_rect.top = 0; | ||
1125 | itv->main_rect.width = 720; | ||
1126 | itv->main_rect.height = itv->is_out_50hz ? 576 : 480; | ||
1127 | ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, | ||
1128 | 720, itv->main_rect.height, 0, 0); | ||
1129 | yi->main_rect = itv->main_rect; | ||
1130 | if (!itv->osd_info) { | ||
1131 | yi->osd_full_w = 720; | ||
1132 | yi->osd_full_h = itv->is_out_50hz ? 576 : 480; | ||
1133 | } | ||
1134 | } | ||
1135 | |||
1136 | int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std) | ||
1137 | { | ||
1138 | struct ivtv *itv = fh2id(fh)->itv; | ||
1139 | |||
1140 | if ((*std & V4L2_STD_ALL) == 0) | ||
1141 | return -EINVAL; | ||
1142 | |||
1143 | if (*std == itv->std) | ||
1144 | return 0; | ||
1145 | |||
1146 | if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) || | ||
1147 | atomic_read(&itv->capturing) > 0 || | ||
1148 | atomic_read(&itv->decoding) > 0) { | ||
1149 | /* Switching standard would mess with already running | ||
1150 | streams, prevent that by returning EBUSY. */ | ||
1151 | return -EBUSY; | ||
1152 | } | ||
1153 | |||
1154 | IVTV_DEBUG_INFO("Switching standard to %llx.\n", | ||
1155 | (unsigned long long)itv->std); | ||
1156 | |||
1157 | ivtv_s_std_enc(itv, std); | ||
1158 | if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) | ||
1159 | ivtv_s_std_dec(itv, std); | ||
1160 | |||
1161 | return 0; | ||
1162 | } | ||
1163 | |||
1164 | static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) | ||
1165 | { | ||
1166 | struct ivtv_open_id *id = fh2id(fh); | ||
1167 | struct ivtv *itv = id->itv; | ||
1168 | |||
1169 | if (vt->index != 0) | ||
1170 | return -EINVAL; | ||
1171 | |||
1172 | ivtv_call_all(itv, tuner, s_tuner, vt); | ||
1173 | |||
1174 | return 0; | ||
1175 | } | ||
1176 | |||
1177 | static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) | ||
1178 | { | ||
1179 | struct ivtv *itv = fh2id(fh)->itv; | ||
1180 | |||
1181 | if (vt->index != 0) | ||
1182 | return -EINVAL; | ||
1183 | |||
1184 | ivtv_call_all(itv, tuner, g_tuner, vt); | ||
1185 | |||
1186 | if (vt->type == V4L2_TUNER_RADIO) | ||
1187 | strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name)); | ||
1188 | else | ||
1189 | strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name)); | ||
1190 | return 0; | ||
1191 | } | ||
1192 | |||
1193 | static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap) | ||
1194 | { | ||
1195 | struct ivtv *itv = fh2id(fh)->itv; | ||
1196 | int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525; | ||
1197 | int f, l; | ||
1198 | |||
1199 | if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { | ||
1200 | for (f = 0; f < 2; f++) { | ||
1201 | for (l = 0; l < 24; l++) { | ||
1202 | if (valid_service_line(f, l, itv->is_50hz)) | ||
1203 | cap->service_lines[f][l] = set; | ||
1204 | } | ||
1205 | } | ||
1206 | return 0; | ||
1207 | } | ||
1208 | if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) { | ||
1209 | if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT)) | ||
1210 | return -EINVAL; | ||
1211 | if (itv->is_60hz) { | ||
1212 | cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525; | ||
1213 | cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525; | ||
1214 | } else { | ||
1215 | cap->service_lines[0][23] = V4L2_SLICED_WSS_625; | ||
1216 | cap->service_lines[0][16] = V4L2_SLICED_VPS; | ||
1217 | } | ||
1218 | return 0; | ||
1219 | } | ||
1220 | return -EINVAL; | ||
1221 | } | ||
1222 | |||
1223 | static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx) | ||
1224 | { | ||
1225 | struct ivtv *itv = fh2id(fh)->itv; | ||
1226 | struct v4l2_enc_idx_entry *e = idx->entry; | ||
1227 | int entries; | ||
1228 | int i; | ||
1229 | |||
1230 | entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) % | ||
1231 | IVTV_MAX_PGM_INDEX; | ||
1232 | if (entries > V4L2_ENC_IDX_ENTRIES) | ||
1233 | entries = V4L2_ENC_IDX_ENTRIES; | ||
1234 | idx->entries = 0; | ||
1235 | for (i = 0; i < entries; i++) { | ||
1236 | *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX]; | ||
1237 | if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) { | ||
1238 | idx->entries++; | ||
1239 | e++; | ||
1240 | } | ||
1241 | } | ||
1242 | itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX; | ||
1243 | return 0; | ||
1244 | } | ||
1245 | |||
1246 | static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc) | ||
1247 | { | ||
1248 | struct ivtv_open_id *id = fh2id(fh); | ||
1249 | struct ivtv *itv = id->itv; | ||
1250 | |||
1251 | |||
1252 | switch (enc->cmd) { | ||
1253 | case V4L2_ENC_CMD_START: | ||
1254 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); | ||
1255 | enc->flags = 0; | ||
1256 | return ivtv_start_capture(id); | ||
1257 | |||
1258 | case V4L2_ENC_CMD_STOP: | ||
1259 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n"); | ||
1260 | enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; | ||
1261 | ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END); | ||
1262 | return 0; | ||
1263 | |||
1264 | case V4L2_ENC_CMD_PAUSE: | ||
1265 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n"); | ||
1266 | enc->flags = 0; | ||
1267 | |||
1268 | if (!atomic_read(&itv->capturing)) | ||
1269 | return -EPERM; | ||
1270 | if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags)) | ||
1271 | return 0; | ||
1272 | |||
1273 | ivtv_mute(itv); | ||
1274 | ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0); | ||
1275 | break; | ||
1276 | |||
1277 | case V4L2_ENC_CMD_RESUME: | ||
1278 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n"); | ||
1279 | enc->flags = 0; | ||
1280 | |||
1281 | if (!atomic_read(&itv->capturing)) | ||
1282 | return -EPERM; | ||
1283 | |||
1284 | if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags)) | ||
1285 | return 0; | ||
1286 | |||
1287 | ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1); | ||
1288 | ivtv_unmute(itv); | ||
1289 | break; | ||
1290 | default: | ||
1291 | IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd); | ||
1292 | return -EINVAL; | ||
1293 | } | ||
1294 | |||
1295 | return 0; | ||
1296 | } | ||
1297 | |||
1298 | static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc) | ||
1299 | { | ||
1300 | struct ivtv *itv = fh2id(fh)->itv; | ||
1301 | |||
1302 | switch (enc->cmd) { | ||
1303 | case V4L2_ENC_CMD_START: | ||
1304 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); | ||
1305 | enc->flags = 0; | ||
1306 | return 0; | ||
1307 | |||
1308 | case V4L2_ENC_CMD_STOP: | ||
1309 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n"); | ||
1310 | enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; | ||
1311 | return 0; | ||
1312 | |||
1313 | case V4L2_ENC_CMD_PAUSE: | ||
1314 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n"); | ||
1315 | enc->flags = 0; | ||
1316 | return 0; | ||
1317 | |||
1318 | case V4L2_ENC_CMD_RESUME: | ||
1319 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n"); | ||
1320 | enc->flags = 0; | ||
1321 | return 0; | ||
1322 | default: | ||
1323 | IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd); | ||
1324 | return -EINVAL; | ||
1325 | } | ||
1326 | } | ||
1327 | |||
1328 | static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) | ||
1329 | { | ||
1330 | struct ivtv *itv = fh2id(fh)->itv; | ||
1331 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
1332 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
1333 | |||
1334 | int pixfmt; | ||
1335 | static u32 pixel_format[16] = { | ||
1336 | V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */ | ||
1337 | V4L2_PIX_FMT_RGB565, | ||
1338 | V4L2_PIX_FMT_RGB555, | ||
1339 | V4L2_PIX_FMT_RGB444, | ||
1340 | V4L2_PIX_FMT_RGB32, | ||
1341 | 0, | ||
1342 | 0, | ||
1343 | 0, | ||
1344 | V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */ | ||
1345 | V4L2_PIX_FMT_YUV565, | ||
1346 | V4L2_PIX_FMT_YUV555, | ||
1347 | V4L2_PIX_FMT_YUV444, | ||
1348 | V4L2_PIX_FMT_YUV32, | ||
1349 | 0, | ||
1350 | 0, | ||
1351 | 0, | ||
1352 | }; | ||
1353 | |||
1354 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) | ||
1355 | return -EINVAL; | ||
1356 | if (!itv->osd_video_pbase) | ||
1357 | return -EINVAL; | ||
1358 | |||
1359 | fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | | ||
1360 | V4L2_FBUF_CAP_GLOBAL_ALPHA; | ||
1361 | |||
1362 | ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0); | ||
1363 | data[0] |= (read_reg(0x2a00) >> 7) & 0x40; | ||
1364 | pixfmt = (data[0] >> 3) & 0xf; | ||
1365 | |||
1366 | fb->fmt.pixelformat = pixel_format[pixfmt]; | ||
1367 | fb->fmt.width = itv->osd_rect.width; | ||
1368 | fb->fmt.height = itv->osd_rect.height; | ||
1369 | fb->fmt.field = V4L2_FIELD_INTERLACED; | ||
1370 | fb->fmt.bytesperline = fb->fmt.width; | ||
1371 | fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
1372 | fb->fmt.field = V4L2_FIELD_INTERLACED; | ||
1373 | fb->fmt.priv = 0; | ||
1374 | if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8) | ||
1375 | fb->fmt.bytesperline *= 2; | ||
1376 | if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 || | ||
1377 | fb->fmt.pixelformat == V4L2_PIX_FMT_YUV32) | ||
1378 | fb->fmt.bytesperline *= 2; | ||
1379 | fb->fmt.sizeimage = fb->fmt.bytesperline * fb->fmt.height; | ||
1380 | fb->base = (void *)itv->osd_video_pbase; | ||
1381 | fb->flags = 0; | ||
1382 | |||
1383 | if (itv->osd_chroma_key_state) | ||
1384 | fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY; | ||
1385 | |||
1386 | if (itv->osd_global_alpha_state) | ||
1387 | fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; | ||
1388 | |||
1389 | if (yi->track_osd) | ||
1390 | fb->flags |= V4L2_FBUF_FLAG_OVERLAY; | ||
1391 | |||
1392 | pixfmt &= 7; | ||
1393 | |||
1394 | /* no local alpha for RGB565 or unknown formats */ | ||
1395 | if (pixfmt == 1 || pixfmt > 4) | ||
1396 | return 0; | ||
1397 | |||
1398 | /* 16-bit formats have inverted local alpha */ | ||
1399 | if (pixfmt == 2 || pixfmt == 3) | ||
1400 | fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA; | ||
1401 | else | ||
1402 | fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA; | ||
1403 | |||
1404 | if (itv->osd_local_alpha_state) { | ||
1405 | /* 16-bit formats have inverted local alpha */ | ||
1406 | if (pixfmt == 2 || pixfmt == 3) | ||
1407 | fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA; | ||
1408 | else | ||
1409 | fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; | ||
1410 | } | ||
1411 | |||
1412 | return 0; | ||
1413 | } | ||
1414 | |||
1415 | static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) | ||
1416 | { | ||
1417 | struct ivtv_open_id *id = fh2id(fh); | ||
1418 | struct ivtv *itv = id->itv; | ||
1419 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
1420 | |||
1421 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) | ||
1422 | return -EINVAL; | ||
1423 | if (!itv->osd_video_pbase) | ||
1424 | return -EINVAL; | ||
1425 | |||
1426 | itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; | ||
1427 | itv->osd_local_alpha_state = | ||
1428 | (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0; | ||
1429 | itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; | ||
1430 | ivtv_set_osd_alpha(itv); | ||
1431 | yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0; | ||
1432 | return ivtv_g_fbuf(file, fh, fb); | ||
1433 | } | ||
1434 | |||
1435 | static int ivtv_overlay(struct file *file, void *fh, unsigned int on) | ||
1436 | { | ||
1437 | struct ivtv_open_id *id = fh2id(fh); | ||
1438 | struct ivtv *itv = id->itv; | ||
1439 | |||
1440 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) | ||
1441 | return -EINVAL; | ||
1442 | |||
1443 | ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0); | ||
1444 | |||
1445 | return 0; | ||
1446 | } | ||
1447 | |||
1448 | static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscription *sub) | ||
1449 | { | ||
1450 | switch (sub->type) { | ||
1451 | case V4L2_EVENT_VSYNC: | ||
1452 | case V4L2_EVENT_EOS: | ||
1453 | case V4L2_EVENT_CTRL: | ||
1454 | return v4l2_event_subscribe(fh, sub, 0); | ||
1455 | default: | ||
1456 | return -EINVAL; | ||
1457 | } | ||
1458 | } | ||
1459 | |||
1460 | static int ivtv_log_status(struct file *file, void *fh) | ||
1461 | { | ||
1462 | struct ivtv *itv = fh2id(fh)->itv; | ||
1463 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
1464 | |||
1465 | int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT; | ||
1466 | struct v4l2_input vidin; | ||
1467 | struct v4l2_audio audin; | ||
1468 | int i; | ||
1469 | |||
1470 | IVTV_INFO("================= START STATUS CARD #%d =================\n", | ||
1471 | itv->instance); | ||
1472 | IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name); | ||
1473 | if (itv->hw_flags & IVTV_HW_TVEEPROM) { | ||
1474 | struct tveeprom tv; | ||
1475 | |||
1476 | ivtv_read_eeprom(itv, &tv); | ||
1477 | } | ||
1478 | ivtv_call_all(itv, core, log_status); | ||
1479 | ivtv_get_input(itv, itv->active_input, &vidin); | ||
1480 | ivtv_get_audio_input(itv, itv->audio_input, &audin); | ||
1481 | IVTV_INFO("Video Input: %s\n", vidin.name); | ||
1482 | IVTV_INFO("Audio Input: %s%s\n", audin.name, | ||
1483 | (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : ""); | ||
1484 | if (has_output) { | ||
1485 | struct v4l2_output vidout; | ||
1486 | struct v4l2_audioout audout; | ||
1487 | int mode = itv->output_mode; | ||
1488 | static const char * const output_modes[5] = { | ||
1489 | "None", | ||
1490 | "MPEG Streaming", | ||
1491 | "YUV Streaming", | ||
1492 | "YUV Frames", | ||
1493 | "Passthrough", | ||
1494 | }; | ||
1495 | static const char * const audio_modes[5] = { | ||
1496 | "Stereo", | ||
1497 | "Left", | ||
1498 | "Right", | ||
1499 | "Mono", | ||
1500 | "Swapped" | ||
1501 | }; | ||
1502 | static const char * const alpha_mode[4] = { | ||
1503 | "None", | ||
1504 | "Global", | ||
1505 | "Local", | ||
1506 | "Global and Local" | ||
1507 | }; | ||
1508 | static const char * const pixel_format[16] = { | ||
1509 | "ARGB Indexed", | ||
1510 | "RGB 5:6:5", | ||
1511 | "ARGB 1:5:5:5", | ||
1512 | "ARGB 1:4:4:4", | ||
1513 | "ARGB 8:8:8:8", | ||
1514 | "5", | ||
1515 | "6", | ||
1516 | "7", | ||
1517 | "AYUV Indexed", | ||
1518 | "YUV 5:6:5", | ||
1519 | "AYUV 1:5:5:5", | ||
1520 | "AYUV 1:4:4:4", | ||
1521 | "AYUV 8:8:8:8", | ||
1522 | "13", | ||
1523 | "14", | ||
1524 | "15", | ||
1525 | }; | ||
1526 | |||
1527 | ivtv_get_output(itv, itv->active_output, &vidout); | ||
1528 | ivtv_get_audio_output(itv, 0, &audout); | ||
1529 | IVTV_INFO("Video Output: %s\n", vidout.name); | ||
1530 | IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name, | ||
1531 | audio_modes[itv->audio_stereo_mode], | ||
1532 | audio_modes[itv->audio_bilingual_mode]); | ||
1533 | if (mode < 0 || mode > OUT_PASSTHROUGH) | ||
1534 | mode = OUT_NONE; | ||
1535 | IVTV_INFO("Output Mode: %s\n", output_modes[mode]); | ||
1536 | ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0); | ||
1537 | data[0] |= (read_reg(0x2a00) >> 7) & 0x40; | ||
1538 | IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n", | ||
1539 | data[0] & 1 ? "On" : "Off", | ||
1540 | alpha_mode[(data[0] >> 1) & 0x3], | ||
1541 | pixel_format[(data[0] >> 3) & 0xf]); | ||
1542 | } | ||
1543 | IVTV_INFO("Tuner: %s\n", | ||
1544 | test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV"); | ||
1545 | v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.name); | ||
1546 | IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags); | ||
1547 | for (i = 0; i < IVTV_MAX_STREAMS; i++) { | ||
1548 | struct ivtv_stream *s = &itv->streams[i]; | ||
1549 | |||
1550 | if (s->vdev == NULL || s->buffers == 0) | ||
1551 | continue; | ||
1552 | IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, | ||
1553 | (s->buffers - s->q_free.buffers) * 100 / s->buffers, | ||
1554 | (s->buffers * s->buf_size) / 1024, s->buffers); | ||
1555 | } | ||
1556 | |||
1557 | IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n", | ||
1558 | (long long)itv->mpg_data_received, | ||
1559 | (long long)itv->vbi_data_inserted); | ||
1560 | IVTV_INFO("================== END STATUS CARD #%d ==================\n", | ||
1561 | itv->instance); | ||
1562 | |||
1563 | return 0; | ||
1564 | } | ||
1565 | |||
1566 | static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) | ||
1567 | { | ||
1568 | struct ivtv_open_id *id = fh2id(filp->private_data); | ||
1569 | struct ivtv *itv = id->itv; | ||
1570 | int nonblocking = filp->f_flags & O_NONBLOCK; | ||
1571 | struct ivtv_stream *s = &itv->streams[id->type]; | ||
1572 | unsigned long iarg = (unsigned long)arg; | ||
1573 | |||
1574 | switch (cmd) { | ||
1575 | case IVTV_IOC_DMA_FRAME: { | ||
1576 | struct ivtv_dma_frame *args = arg; | ||
1577 | |||
1578 | IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n"); | ||
1579 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
1580 | return -EINVAL; | ||
1581 | if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) | ||
1582 | return -EINVAL; | ||
1583 | if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL) | ||
1584 | return 0; | ||
1585 | if (ivtv_start_decoding(id, id->type)) { | ||
1586 | return -EBUSY; | ||
1587 | } | ||
1588 | if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) { | ||
1589 | ivtv_release_stream(s); | ||
1590 | return -EBUSY; | ||
1591 | } | ||
1592 | /* Mark that this file handle started the UDMA_YUV mode */ | ||
1593 | id->yuv_frames = 1; | ||
1594 | if (args->y_source == NULL) | ||
1595 | return 0; | ||
1596 | return ivtv_yuv_prep_frame(itv, args); | ||
1597 | } | ||
1598 | |||
1599 | case VIDEO_GET_PTS: { | ||
1600 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
1601 | u64 *pts = arg; | ||
1602 | |||
1603 | IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n"); | ||
1604 | if (s->type < IVTV_DEC_STREAM_TYPE_MPG) { | ||
1605 | *pts = s->dma_pts; | ||
1606 | break; | ||
1607 | } | ||
1608 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
1609 | return -EINVAL; | ||
1610 | |||
1611 | if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) { | ||
1612 | *pts = (u64) ((u64)itv->last_dec_timing[2] << 32) | | ||
1613 | (u64)itv->last_dec_timing[1]; | ||
1614 | break; | ||
1615 | } | ||
1616 | *pts = 0; | ||
1617 | if (atomic_read(&itv->decoding)) { | ||
1618 | if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) { | ||
1619 | IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n"); | ||
1620 | return -EIO; | ||
1621 | } | ||
1622 | memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing)); | ||
1623 | set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags); | ||
1624 | *pts = (u64) ((u64) data[2] << 32) | (u64) data[1]; | ||
1625 | /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/ | ||
1626 | } | ||
1627 | break; | ||
1628 | } | ||
1629 | |||
1630 | case VIDEO_GET_FRAME_COUNT: { | ||
1631 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
1632 | u64 *frame = arg; | ||
1633 | |||
1634 | IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n"); | ||
1635 | if (s->type < IVTV_DEC_STREAM_TYPE_MPG) { | ||
1636 | *frame = 0; | ||
1637 | break; | ||
1638 | } | ||
1639 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
1640 | return -EINVAL; | ||
1641 | |||
1642 | if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) { | ||
1643 | *frame = itv->last_dec_timing[0]; | ||
1644 | break; | ||
1645 | } | ||
1646 | *frame = 0; | ||
1647 | if (atomic_read(&itv->decoding)) { | ||
1648 | if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) { | ||
1649 | IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n"); | ||
1650 | return -EIO; | ||
1651 | } | ||
1652 | memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing)); | ||
1653 | set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags); | ||
1654 | *frame = data[0]; | ||
1655 | } | ||
1656 | break; | ||
1657 | } | ||
1658 | |||
1659 | case VIDEO_PLAY: { | ||
1660 | struct video_command vc; | ||
1661 | |||
1662 | IVTV_DEBUG_IOCTL("VIDEO_PLAY\n"); | ||
1663 | memset(&vc, 0, sizeof(vc)); | ||
1664 | vc.cmd = VIDEO_CMD_PLAY; | ||
1665 | return ivtv_video_command(itv, id, &vc, 0); | ||
1666 | } | ||
1667 | |||
1668 | case VIDEO_STOP: { | ||
1669 | struct video_command vc; | ||
1670 | |||
1671 | IVTV_DEBUG_IOCTL("VIDEO_STOP\n"); | ||
1672 | memset(&vc, 0, sizeof(vc)); | ||
1673 | vc.cmd = VIDEO_CMD_STOP; | ||
1674 | vc.flags = VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY; | ||
1675 | return ivtv_video_command(itv, id, &vc, 0); | ||
1676 | } | ||
1677 | |||
1678 | case VIDEO_FREEZE: { | ||
1679 | struct video_command vc; | ||
1680 | |||
1681 | IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n"); | ||
1682 | memset(&vc, 0, sizeof(vc)); | ||
1683 | vc.cmd = VIDEO_CMD_FREEZE; | ||
1684 | return ivtv_video_command(itv, id, &vc, 0); | ||
1685 | } | ||
1686 | |||
1687 | case VIDEO_CONTINUE: { | ||
1688 | struct video_command vc; | ||
1689 | |||
1690 | IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n"); | ||
1691 | memset(&vc, 0, sizeof(vc)); | ||
1692 | vc.cmd = VIDEO_CMD_CONTINUE; | ||
1693 | return ivtv_video_command(itv, id, &vc, 0); | ||
1694 | } | ||
1695 | |||
1696 | case VIDEO_COMMAND: | ||
1697 | case VIDEO_TRY_COMMAND: { | ||
1698 | struct video_command *vc = arg; | ||
1699 | int try = (cmd == VIDEO_TRY_COMMAND); | ||
1700 | |||
1701 | if (try) | ||
1702 | IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", vc->cmd); | ||
1703 | else | ||
1704 | IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", vc->cmd); | ||
1705 | return ivtv_video_command(itv, id, vc, try); | ||
1706 | } | ||
1707 | |||
1708 | case VIDEO_GET_EVENT: { | ||
1709 | struct video_event *ev = arg; | ||
1710 | DEFINE_WAIT(wait); | ||
1711 | |||
1712 | IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n"); | ||
1713 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
1714 | return -EINVAL; | ||
1715 | memset(ev, 0, sizeof(*ev)); | ||
1716 | set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags); | ||
1717 | |||
1718 | while (1) { | ||
1719 | if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags)) | ||
1720 | ev->type = VIDEO_EVENT_DECODER_STOPPED; | ||
1721 | else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) { | ||
1722 | ev->type = VIDEO_EVENT_VSYNC; | ||
1723 | ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ? | ||
1724 | VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN; | ||
1725 | if (itv->output_mode == OUT_UDMA_YUV && | ||
1726 | (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) == | ||
1727 | IVTV_YUV_MODE_PROGRESSIVE) { | ||
1728 | ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE; | ||
1729 | } | ||
1730 | } | ||
1731 | if (ev->type) | ||
1732 | return 0; | ||
1733 | if (nonblocking) | ||
1734 | return -EAGAIN; | ||
1735 | /* Wait for event. Note that serialize_lock is locked, | ||
1736 | so to allow other processes to access the driver while | ||
1737 | we are waiting unlock first and later lock again. */ | ||
1738 | mutex_unlock(&itv->serialize_lock); | ||
1739 | prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE); | ||
1740 | if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) && | ||
1741 | !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) | ||
1742 | schedule(); | ||
1743 | finish_wait(&itv->event_waitq, &wait); | ||
1744 | mutex_lock(&itv->serialize_lock); | ||
1745 | if (signal_pending(current)) { | ||
1746 | /* return if a signal was received */ | ||
1747 | IVTV_DEBUG_INFO("User stopped wait for event\n"); | ||
1748 | return -EINTR; | ||
1749 | } | ||
1750 | } | ||
1751 | break; | ||
1752 | } | ||
1753 | |||
1754 | case VIDEO_SELECT_SOURCE: | ||
1755 | IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n"); | ||
1756 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
1757 | return -EINVAL; | ||
1758 | return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX); | ||
1759 | |||
1760 | case AUDIO_SET_MUTE: | ||
1761 | IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n"); | ||
1762 | itv->speed_mute_audio = iarg; | ||
1763 | return 0; | ||
1764 | |||
1765 | case AUDIO_CHANNEL_SELECT: | ||
1766 | IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n"); | ||
1767 | if (iarg > AUDIO_STEREO_SWAPPED) | ||
1768 | return -EINVAL; | ||
1769 | itv->audio_stereo_mode = iarg; | ||
1770 | ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); | ||
1771 | return 0; | ||
1772 | |||
1773 | case AUDIO_BILINGUAL_CHANNEL_SELECT: | ||
1774 | IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n"); | ||
1775 | if (iarg > AUDIO_STEREO_SWAPPED) | ||
1776 | return -EINVAL; | ||
1777 | itv->audio_bilingual_mode = iarg; | ||
1778 | ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); | ||
1779 | return 0; | ||
1780 | |||
1781 | default: | ||
1782 | return -EINVAL; | ||
1783 | } | ||
1784 | return 0; | ||
1785 | } | ||
1786 | |||
1787 | static long ivtv_default(struct file *file, void *fh, bool valid_prio, | ||
1788 | int cmd, void *arg) | ||
1789 | { | ||
1790 | struct ivtv *itv = fh2id(fh)->itv; | ||
1791 | |||
1792 | if (!valid_prio) { | ||
1793 | switch (cmd) { | ||
1794 | case VIDEO_PLAY: | ||
1795 | case VIDEO_STOP: | ||
1796 | case VIDEO_FREEZE: | ||
1797 | case VIDEO_CONTINUE: | ||
1798 | case VIDEO_COMMAND: | ||
1799 | case VIDEO_SELECT_SOURCE: | ||
1800 | case AUDIO_SET_MUTE: | ||
1801 | case AUDIO_CHANNEL_SELECT: | ||
1802 | case AUDIO_BILINGUAL_CHANNEL_SELECT: | ||
1803 | return -EBUSY; | ||
1804 | } | ||
1805 | } | ||
1806 | |||
1807 | switch (cmd) { | ||
1808 | case VIDIOC_INT_RESET: { | ||
1809 | u32 val = *(u32 *)arg; | ||
1810 | |||
1811 | if ((val == 0 && itv->options.newi2c) || (val & 0x01)) | ||
1812 | ivtv_reset_ir_gpio(itv); | ||
1813 | if (val & 0x02) | ||
1814 | v4l2_subdev_call(itv->sd_video, core, reset, 0); | ||
1815 | break; | ||
1816 | } | ||
1817 | |||
1818 | case IVTV_IOC_DMA_FRAME: | ||
1819 | case VIDEO_GET_PTS: | ||
1820 | case VIDEO_GET_FRAME_COUNT: | ||
1821 | case VIDEO_GET_EVENT: | ||
1822 | case VIDEO_PLAY: | ||
1823 | case VIDEO_STOP: | ||
1824 | case VIDEO_FREEZE: | ||
1825 | case VIDEO_CONTINUE: | ||
1826 | case VIDEO_COMMAND: | ||
1827 | case VIDEO_TRY_COMMAND: | ||
1828 | case VIDEO_SELECT_SOURCE: | ||
1829 | case AUDIO_SET_MUTE: | ||
1830 | case AUDIO_CHANNEL_SELECT: | ||
1831 | case AUDIO_BILINGUAL_CHANNEL_SELECT: | ||
1832 | return ivtv_decoder_ioctls(file, cmd, (void *)arg); | ||
1833 | |||
1834 | default: | ||
1835 | return -EINVAL; | ||
1836 | } | ||
1837 | return 0; | ||
1838 | } | ||
1839 | |||
1840 | static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp, | ||
1841 | unsigned int cmd, unsigned long arg) | ||
1842 | { | ||
1843 | struct video_device *vfd = video_devdata(filp); | ||
1844 | long ret; | ||
1845 | |||
1846 | if (ivtv_debug & IVTV_DBGFLG_IOCTL) | ||
1847 | vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; | ||
1848 | ret = video_ioctl2(filp, cmd, arg); | ||
1849 | vfd->debug = 0; | ||
1850 | return ret; | ||
1851 | } | ||
1852 | |||
1853 | long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | ||
1854 | { | ||
1855 | struct ivtv_open_id *id = fh2id(filp->private_data); | ||
1856 | struct ivtv *itv = id->itv; | ||
1857 | long res; | ||
1858 | |||
1859 | /* DQEVENT can block, so this should not run with the serialize lock */ | ||
1860 | if (cmd == VIDIOC_DQEVENT) | ||
1861 | return ivtv_serialized_ioctl(itv, filp, cmd, arg); | ||
1862 | mutex_lock(&itv->serialize_lock); | ||
1863 | res = ivtv_serialized_ioctl(itv, filp, cmd, arg); | ||
1864 | mutex_unlock(&itv->serialize_lock); | ||
1865 | return res; | ||
1866 | } | ||
1867 | |||
1868 | static const struct v4l2_ioctl_ops ivtv_ioctl_ops = { | ||
1869 | .vidioc_querycap = ivtv_querycap, | ||
1870 | .vidioc_s_audio = ivtv_s_audio, | ||
1871 | .vidioc_g_audio = ivtv_g_audio, | ||
1872 | .vidioc_enumaudio = ivtv_enumaudio, | ||
1873 | .vidioc_s_audout = ivtv_s_audout, | ||
1874 | .vidioc_g_audout = ivtv_g_audout, | ||
1875 | .vidioc_enum_input = ivtv_enum_input, | ||
1876 | .vidioc_enum_output = ivtv_enum_output, | ||
1877 | .vidioc_enumaudout = ivtv_enumaudout, | ||
1878 | .vidioc_cropcap = ivtv_cropcap, | ||
1879 | .vidioc_s_crop = ivtv_s_crop, | ||
1880 | .vidioc_g_crop = ivtv_g_crop, | ||
1881 | .vidioc_g_input = ivtv_g_input, | ||
1882 | .vidioc_s_input = ivtv_s_input, | ||
1883 | .vidioc_g_output = ivtv_g_output, | ||
1884 | .vidioc_s_output = ivtv_s_output, | ||
1885 | .vidioc_g_frequency = ivtv_g_frequency, | ||
1886 | .vidioc_s_frequency = ivtv_s_frequency, | ||
1887 | .vidioc_s_tuner = ivtv_s_tuner, | ||
1888 | .vidioc_g_tuner = ivtv_g_tuner, | ||
1889 | .vidioc_g_enc_index = ivtv_g_enc_index, | ||
1890 | .vidioc_g_fbuf = ivtv_g_fbuf, | ||
1891 | .vidioc_s_fbuf = ivtv_s_fbuf, | ||
1892 | .vidioc_g_std = ivtv_g_std, | ||
1893 | .vidioc_s_std = ivtv_s_std, | ||
1894 | .vidioc_overlay = ivtv_overlay, | ||
1895 | .vidioc_log_status = ivtv_log_status, | ||
1896 | .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap, | ||
1897 | .vidioc_encoder_cmd = ivtv_encoder_cmd, | ||
1898 | .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd, | ||
1899 | .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out, | ||
1900 | .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap, | ||
1901 | .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap, | ||
1902 | .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap, | ||
1903 | .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out, | ||
1904 | .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay, | ||
1905 | .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out, | ||
1906 | .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap, | ||
1907 | .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap, | ||
1908 | .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap, | ||
1909 | .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out, | ||
1910 | .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay, | ||
1911 | .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out, | ||
1912 | .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap, | ||
1913 | .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap, | ||
1914 | .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap, | ||
1915 | .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out, | ||
1916 | .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay, | ||
1917 | .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out, | ||
1918 | .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap, | ||
1919 | .vidioc_g_chip_ident = ivtv_g_chip_ident, | ||
1920 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1921 | .vidioc_g_register = ivtv_g_register, | ||
1922 | .vidioc_s_register = ivtv_s_register, | ||
1923 | #endif | ||
1924 | .vidioc_default = ivtv_default, | ||
1925 | .vidioc_subscribe_event = ivtv_subscribe_event, | ||
1926 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | ||
1927 | }; | ||
1928 | |||
1929 | void ivtv_set_funcs(struct video_device *vdev) | ||
1930 | { | ||
1931 | vdev->ioctl_ops = &ivtv_ioctl_ops; | ||
1932 | } | ||
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.h b/drivers/media/video/ivtv/ivtv-ioctl.h new file mode 100644 index 00000000000..89185caeafa --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-ioctl.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | ioctl system call | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #ifndef IVTV_IOCTL_H | ||
22 | #define IVTV_IOCTL_H | ||
23 | |||
24 | u16 ivtv_service2vbi(int type); | ||
25 | void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal); | ||
26 | u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt); | ||
27 | void ivtv_set_osd_alpha(struct ivtv *itv); | ||
28 | int ivtv_set_speed(struct ivtv *itv, int speed); | ||
29 | void ivtv_set_funcs(struct video_device *vdev); | ||
30 | void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std); | ||
31 | void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std); | ||
32 | int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf); | ||
33 | int ivtv_s_input(struct file *file, void *fh, unsigned int inp); | ||
34 | long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); | ||
35 | |||
36 | #endif | ||
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c new file mode 100644 index 00000000000..9c29e964d40 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-irq.c | |||
@@ -0,0 +1,1038 @@ | |||
1 | /* interrupt handling | ||
2 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
3 | Copyright (C) 2004 Chris Kennedy <c@groovy.org> | ||
4 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include "ivtv-driver.h" | ||
22 | #include "ivtv-queue.h" | ||
23 | #include "ivtv-udma.h" | ||
24 | #include "ivtv-irq.h" | ||
25 | #include "ivtv-mailbox.h" | ||
26 | #include "ivtv-vbi.h" | ||
27 | #include "ivtv-yuv.h" | ||
28 | #include <media/v4l2-event.h> | ||
29 | |||
30 | #define DMA_MAGIC_COOKIE 0x000001fe | ||
31 | |||
32 | static void ivtv_dma_dec_start(struct ivtv_stream *s); | ||
33 | |||
34 | static const int ivtv_stream_map[] = { | ||
35 | IVTV_ENC_STREAM_TYPE_MPG, | ||
36 | IVTV_ENC_STREAM_TYPE_YUV, | ||
37 | IVTV_ENC_STREAM_TYPE_PCM, | ||
38 | IVTV_ENC_STREAM_TYPE_VBI, | ||
39 | }; | ||
40 | |||
41 | |||
42 | static void ivtv_pio_work_handler(struct ivtv *itv) | ||
43 | { | ||
44 | struct ivtv_stream *s = &itv->streams[itv->cur_pio_stream]; | ||
45 | struct ivtv_buffer *buf; | ||
46 | int i = 0; | ||
47 | |||
48 | IVTV_DEBUG_HI_DMA("ivtv_pio_work_handler\n"); | ||
49 | if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS || | ||
50 | s->vdev == NULL || !ivtv_use_pio(s)) { | ||
51 | itv->cur_pio_stream = -1; | ||
52 | /* trigger PIO complete user interrupt */ | ||
53 | write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44); | ||
54 | return; | ||
55 | } | ||
56 | IVTV_DEBUG_HI_DMA("Process PIO %s\n", s->name); | ||
57 | list_for_each_entry(buf, &s->q_dma.list, list) { | ||
58 | u32 size = s->sg_processing[i].size & 0x3ffff; | ||
59 | |||
60 | /* Copy the data from the card to the buffer */ | ||
61 | if (s->type == IVTV_DEC_STREAM_TYPE_VBI) { | ||
62 | memcpy_fromio(buf->buf, itv->dec_mem + s->sg_processing[i].src - IVTV_DECODER_OFFSET, size); | ||
63 | } | ||
64 | else { | ||
65 | memcpy_fromio(buf->buf, itv->enc_mem + s->sg_processing[i].src, size); | ||
66 | } | ||
67 | i++; | ||
68 | if (i == s->sg_processing_size) | ||
69 | break; | ||
70 | } | ||
71 | write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44); | ||
72 | } | ||
73 | |||
74 | void ivtv_irq_work_handler(struct kthread_work *work) | ||
75 | { | ||
76 | struct ivtv *itv = container_of(work, struct ivtv, irq_work); | ||
77 | |||
78 | if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags)) | ||
79 | ivtv_pio_work_handler(itv); | ||
80 | |||
81 | if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags)) | ||
82 | ivtv_vbi_work_handler(itv); | ||
83 | |||
84 | if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags)) | ||
85 | ivtv_yuv_work_handler(itv); | ||
86 | } | ||
87 | |||
88 | /* Determine the required DMA size, setup enough buffers in the predma queue and | ||
89 | actually copy the data from the card to the buffers in case a PIO transfer is | ||
90 | required for this stream. | ||
91 | */ | ||
92 | static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MAX_DATA]) | ||
93 | { | ||
94 | struct ivtv *itv = s->itv; | ||
95 | struct ivtv_buffer *buf; | ||
96 | u32 bytes_needed = 0; | ||
97 | u32 offset, size; | ||
98 | u32 UVoffset = 0, UVsize = 0; | ||
99 | int skip_bufs = s->q_predma.buffers; | ||
100 | int idx = s->sg_pending_size; | ||
101 | int rc; | ||
102 | |||
103 | /* sanity checks */ | ||
104 | if (s->vdev == NULL) { | ||
105 | IVTV_DEBUG_WARN("Stream %s not started\n", s->name); | ||
106 | return -1; | ||
107 | } | ||
108 | if (!test_bit(IVTV_F_S_CLAIMED, &s->s_flags)) { | ||
109 | IVTV_DEBUG_WARN("Stream %s not open\n", s->name); | ||
110 | return -1; | ||
111 | } | ||
112 | |||
113 | /* determine offset, size and PTS for the various streams */ | ||
114 | switch (s->type) { | ||
115 | case IVTV_ENC_STREAM_TYPE_MPG: | ||
116 | offset = data[1]; | ||
117 | size = data[2]; | ||
118 | s->pending_pts = 0; | ||
119 | break; | ||
120 | |||
121 | case IVTV_ENC_STREAM_TYPE_YUV: | ||
122 | offset = data[1]; | ||
123 | size = data[2]; | ||
124 | UVoffset = data[3]; | ||
125 | UVsize = data[4]; | ||
126 | s->pending_pts = ((u64) data[5] << 32) | data[6]; | ||
127 | break; | ||
128 | |||
129 | case IVTV_ENC_STREAM_TYPE_PCM: | ||
130 | offset = data[1] + 12; | ||
131 | size = data[2] - 12; | ||
132 | s->pending_pts = read_dec(offset - 8) | | ||
133 | ((u64)(read_dec(offset - 12)) << 32); | ||
134 | if (itv->has_cx23415) | ||
135 | offset += IVTV_DECODER_OFFSET; | ||
136 | break; | ||
137 | |||
138 | case IVTV_ENC_STREAM_TYPE_VBI: | ||
139 | size = itv->vbi.enc_size * itv->vbi.fpi; | ||
140 | offset = read_enc(itv->vbi.enc_start - 4) + 12; | ||
141 | if (offset == 12) { | ||
142 | IVTV_DEBUG_INFO("VBI offset == 0\n"); | ||
143 | return -1; | ||
144 | } | ||
145 | s->pending_pts = read_enc(offset - 4) | ((u64)read_enc(offset - 8) << 32); | ||
146 | break; | ||
147 | |||
148 | case IVTV_DEC_STREAM_TYPE_VBI: | ||
149 | size = read_dec(itv->vbi.dec_start + 4) + 8; | ||
150 | offset = read_dec(itv->vbi.dec_start) + itv->vbi.dec_start; | ||
151 | s->pending_pts = 0; | ||
152 | offset += IVTV_DECODER_OFFSET; | ||
153 | break; | ||
154 | default: | ||
155 | /* shouldn't happen */ | ||
156 | return -1; | ||
157 | } | ||
158 | |||
159 | /* if this is the start of the DMA then fill in the magic cookie */ | ||
160 | if (s->sg_pending_size == 0 && ivtv_use_dma(s)) { | ||
161 | if (itv->has_cx23415 && (s->type == IVTV_ENC_STREAM_TYPE_PCM || | ||
162 | s->type == IVTV_DEC_STREAM_TYPE_VBI)) { | ||
163 | s->pending_backup = read_dec(offset - IVTV_DECODER_OFFSET); | ||
164 | write_dec_sync(cpu_to_le32(DMA_MAGIC_COOKIE), offset - IVTV_DECODER_OFFSET); | ||
165 | } | ||
166 | else { | ||
167 | s->pending_backup = read_enc(offset); | ||
168 | write_enc_sync(cpu_to_le32(DMA_MAGIC_COOKIE), offset); | ||
169 | } | ||
170 | s->pending_offset = offset; | ||
171 | } | ||
172 | |||
173 | bytes_needed = size; | ||
174 | if (s->type == IVTV_ENC_STREAM_TYPE_YUV) { | ||
175 | /* The size for the Y samples needs to be rounded upwards to a | ||
176 | multiple of the buf_size. The UV samples then start in the | ||
177 | next buffer. */ | ||
178 | bytes_needed = s->buf_size * ((bytes_needed + s->buf_size - 1) / s->buf_size); | ||
179 | bytes_needed += UVsize; | ||
180 | } | ||
181 | |||
182 | IVTV_DEBUG_HI_DMA("%s %s: 0x%08x bytes at 0x%08x\n", | ||
183 | ivtv_use_pio(s) ? "PIO" : "DMA", s->name, bytes_needed, offset); | ||
184 | |||
185 | rc = ivtv_queue_move(s, &s->q_free, &s->q_full, &s->q_predma, bytes_needed); | ||
186 | if (rc < 0) { /* Insufficient buffers */ | ||
187 | IVTV_DEBUG_WARN("Cannot obtain %d bytes for %s data transfer\n", | ||
188 | bytes_needed, s->name); | ||
189 | return -1; | ||
190 | } | ||
191 | if (rc && !s->buffers_stolen && test_bit(IVTV_F_S_APPL_IO, &s->s_flags)) { | ||
192 | IVTV_WARN("All %s stream buffers are full. Dropping data.\n", s->name); | ||
193 | IVTV_WARN("Cause: the application is not reading fast enough.\n"); | ||
194 | } | ||
195 | s->buffers_stolen = rc; | ||
196 | |||
197 | /* got the buffers, now fill in sg_pending */ | ||
198 | buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list); | ||
199 | memset(buf->buf, 0, 128); | ||
200 | list_for_each_entry(buf, &s->q_predma.list, list) { | ||
201 | if (skip_bufs-- > 0) | ||
202 | continue; | ||
203 | s->sg_pending[idx].dst = buf->dma_handle; | ||
204 | s->sg_pending[idx].src = offset; | ||
205 | s->sg_pending[idx].size = s->buf_size; | ||
206 | buf->bytesused = min(size, s->buf_size); | ||
207 | buf->dma_xfer_cnt = s->dma_xfer_cnt; | ||
208 | |||
209 | s->q_predma.bytesused += buf->bytesused; | ||
210 | size -= buf->bytesused; | ||
211 | offset += s->buf_size; | ||
212 | |||
213 | /* Sync SG buffers */ | ||
214 | ivtv_buf_sync_for_device(s, buf); | ||
215 | |||
216 | if (size == 0) { /* YUV */ | ||
217 | /* process the UV section */ | ||
218 | offset = UVoffset; | ||
219 | size = UVsize; | ||
220 | } | ||
221 | idx++; | ||
222 | } | ||
223 | s->sg_pending_size = idx; | ||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | static void dma_post(struct ivtv_stream *s) | ||
228 | { | ||
229 | struct ivtv *itv = s->itv; | ||
230 | struct ivtv_buffer *buf = NULL; | ||
231 | struct list_head *p; | ||
232 | u32 offset; | ||
233 | __le32 *u32buf; | ||
234 | int x = 0; | ||
235 | |||
236 | IVTV_DEBUG_HI_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA", | ||
237 | s->name, s->dma_offset); | ||
238 | list_for_each(p, &s->q_dma.list) { | ||
239 | buf = list_entry(p, struct ivtv_buffer, list); | ||
240 | u32buf = (__le32 *)buf->buf; | ||
241 | |||
242 | /* Sync Buffer */ | ||
243 | ivtv_buf_sync_for_cpu(s, buf); | ||
244 | |||
245 | if (x == 0 && ivtv_use_dma(s)) { | ||
246 | offset = s->dma_last_offset; | ||
247 | if (u32buf[offset / 4] != DMA_MAGIC_COOKIE) | ||
248 | { | ||
249 | for (offset = 0; offset < 64; offset++) { | ||
250 | if (u32buf[offset] == DMA_MAGIC_COOKIE) { | ||
251 | break; | ||
252 | } | ||
253 | } | ||
254 | offset *= 4; | ||
255 | if (offset == 256) { | ||
256 | IVTV_DEBUG_WARN("%s: Couldn't find start of buffer within the first 256 bytes\n", s->name); | ||
257 | offset = s->dma_last_offset; | ||
258 | } | ||
259 | if (s->dma_last_offset != offset) | ||
260 | IVTV_DEBUG_WARN("%s: offset %d -> %d\n", s->name, s->dma_last_offset, offset); | ||
261 | s->dma_last_offset = offset; | ||
262 | } | ||
263 | if (itv->has_cx23415 && (s->type == IVTV_ENC_STREAM_TYPE_PCM || | ||
264 | s->type == IVTV_DEC_STREAM_TYPE_VBI)) { | ||
265 | write_dec_sync(0, s->dma_offset - IVTV_DECODER_OFFSET); | ||
266 | } | ||
267 | else { | ||
268 | write_enc_sync(0, s->dma_offset); | ||
269 | } | ||
270 | if (offset) { | ||
271 | buf->bytesused -= offset; | ||
272 | memcpy(buf->buf, buf->buf + offset, buf->bytesused + offset); | ||
273 | } | ||
274 | *u32buf = cpu_to_le32(s->dma_backup); | ||
275 | } | ||
276 | x++; | ||
277 | /* flag byteswap ABCD -> DCBA for MPG & VBI data outside irq */ | ||
278 | if (s->type == IVTV_ENC_STREAM_TYPE_MPG || | ||
279 | s->type == IVTV_ENC_STREAM_TYPE_VBI) | ||
280 | buf->b_flags |= IVTV_F_B_NEED_BUF_SWAP; | ||
281 | } | ||
282 | if (buf) | ||
283 | buf->bytesused += s->dma_last_offset; | ||
284 | if (buf && s->type == IVTV_DEC_STREAM_TYPE_VBI) { | ||
285 | list_for_each_entry(buf, &s->q_dma.list, list) { | ||
286 | /* Parse and Groom VBI Data */ | ||
287 | s->q_dma.bytesused -= buf->bytesused; | ||
288 | ivtv_process_vbi_data(itv, buf, 0, s->type); | ||
289 | s->q_dma.bytesused += buf->bytesused; | ||
290 | } | ||
291 | if (s->id == -1) { | ||
292 | ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0); | ||
293 | return; | ||
294 | } | ||
295 | } | ||
296 | ivtv_queue_move(s, &s->q_dma, NULL, &s->q_full, s->q_dma.bytesused); | ||
297 | if (s->id != -1) | ||
298 | wake_up(&s->waitq); | ||
299 | } | ||
300 | |||
301 | void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock) | ||
302 | { | ||
303 | struct ivtv *itv = s->itv; | ||
304 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
305 | u8 frame = yi->draw_frame; | ||
306 | struct yuv_frame_info *f = &yi->new_frame_info[frame]; | ||
307 | struct ivtv_buffer *buf; | ||
308 | u32 y_size = 720 * ((f->src_h + 31) & ~31); | ||
309 | u32 uv_offset = offset + IVTV_YUV_BUFFER_UV_OFFSET; | ||
310 | int y_done = 0; | ||
311 | int bytes_written = 0; | ||
312 | unsigned long flags = 0; | ||
313 | int idx = 0; | ||
314 | |||
315 | IVTV_DEBUG_HI_DMA("DEC PREPARE DMA %s: %08x %08x\n", s->name, s->q_predma.bytesused, offset); | ||
316 | |||
317 | /* Insert buffer block for YUV if needed */ | ||
318 | if (s->type == IVTV_DEC_STREAM_TYPE_YUV && f->offset_y) { | ||
319 | if (yi->blanking_dmaptr) { | ||
320 | s->sg_pending[idx].src = yi->blanking_dmaptr; | ||
321 | s->sg_pending[idx].dst = offset; | ||
322 | s->sg_pending[idx].size = 720 * 16; | ||
323 | } | ||
324 | offset += 720 * 16; | ||
325 | idx++; | ||
326 | } | ||
327 | |||
328 | list_for_each_entry(buf, &s->q_predma.list, list) { | ||
329 | /* YUV UV Offset from Y Buffer */ | ||
330 | if (s->type == IVTV_DEC_STREAM_TYPE_YUV && !y_done && | ||
331 | (bytes_written + buf->bytesused) >= y_size) { | ||
332 | s->sg_pending[idx].src = buf->dma_handle; | ||
333 | s->sg_pending[idx].dst = offset; | ||
334 | s->sg_pending[idx].size = y_size - bytes_written; | ||
335 | offset = uv_offset; | ||
336 | if (s->sg_pending[idx].size != buf->bytesused) { | ||
337 | idx++; | ||
338 | s->sg_pending[idx].src = | ||
339 | buf->dma_handle + s->sg_pending[idx - 1].size; | ||
340 | s->sg_pending[idx].dst = offset; | ||
341 | s->sg_pending[idx].size = | ||
342 | buf->bytesused - s->sg_pending[idx - 1].size; | ||
343 | offset += s->sg_pending[idx].size; | ||
344 | } | ||
345 | y_done = 1; | ||
346 | } else { | ||
347 | s->sg_pending[idx].src = buf->dma_handle; | ||
348 | s->sg_pending[idx].dst = offset; | ||
349 | s->sg_pending[idx].size = buf->bytesused; | ||
350 | offset += buf->bytesused; | ||
351 | } | ||
352 | bytes_written += buf->bytesused; | ||
353 | |||
354 | /* Sync SG buffers */ | ||
355 | ivtv_buf_sync_for_device(s, buf); | ||
356 | idx++; | ||
357 | } | ||
358 | s->sg_pending_size = idx; | ||
359 | |||
360 | /* Sync Hardware SG List of buffers */ | ||
361 | ivtv_stream_sync_for_device(s); | ||
362 | if (lock) | ||
363 | spin_lock_irqsave(&itv->dma_reg_lock, flags); | ||
364 | if (!test_bit(IVTV_F_I_DMA, &itv->i_flags)) { | ||
365 | ivtv_dma_dec_start(s); | ||
366 | } | ||
367 | else { | ||
368 | set_bit(IVTV_F_S_DMA_PENDING, &s->s_flags); | ||
369 | } | ||
370 | if (lock) | ||
371 | spin_unlock_irqrestore(&itv->dma_reg_lock, flags); | ||
372 | } | ||
373 | |||
374 | static void ivtv_dma_enc_start_xfer(struct ivtv_stream *s) | ||
375 | { | ||
376 | struct ivtv *itv = s->itv; | ||
377 | |||
378 | s->sg_dma->src = cpu_to_le32(s->sg_processing[s->sg_processed].src); | ||
379 | s->sg_dma->dst = cpu_to_le32(s->sg_processing[s->sg_processed].dst); | ||
380 | s->sg_dma->size = cpu_to_le32(s->sg_processing[s->sg_processed].size | 0x80000000); | ||
381 | s->sg_processed++; | ||
382 | /* Sync Hardware SG List of buffers */ | ||
383 | ivtv_stream_sync_for_device(s); | ||
384 | write_reg(s->sg_handle, IVTV_REG_ENCDMAADDR); | ||
385 | write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER); | ||
386 | itv->dma_timer.expires = jiffies + msecs_to_jiffies(300); | ||
387 | add_timer(&itv->dma_timer); | ||
388 | } | ||
389 | |||
390 | static void ivtv_dma_dec_start_xfer(struct ivtv_stream *s) | ||
391 | { | ||
392 | struct ivtv *itv = s->itv; | ||
393 | |||
394 | s->sg_dma->src = cpu_to_le32(s->sg_processing[s->sg_processed].src); | ||
395 | s->sg_dma->dst = cpu_to_le32(s->sg_processing[s->sg_processed].dst); | ||
396 | s->sg_dma->size = cpu_to_le32(s->sg_processing[s->sg_processed].size | 0x80000000); | ||
397 | s->sg_processed++; | ||
398 | /* Sync Hardware SG List of buffers */ | ||
399 | ivtv_stream_sync_for_device(s); | ||
400 | write_reg(s->sg_handle, IVTV_REG_DECDMAADDR); | ||
401 | write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER); | ||
402 | itv->dma_timer.expires = jiffies + msecs_to_jiffies(300); | ||
403 | add_timer(&itv->dma_timer); | ||
404 | } | ||
405 | |||
406 | /* start the encoder DMA */ | ||
407 | static void ivtv_dma_enc_start(struct ivtv_stream *s) | ||
408 | { | ||
409 | struct ivtv *itv = s->itv; | ||
410 | struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; | ||
411 | int i; | ||
412 | |||
413 | IVTV_DEBUG_HI_DMA("start %s for %s\n", ivtv_use_dma(s) ? "DMA" : "PIO", s->name); | ||
414 | |||
415 | if (s->q_predma.bytesused) | ||
416 | ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused); | ||
417 | |||
418 | if (ivtv_use_dma(s)) | ||
419 | s->sg_pending[s->sg_pending_size - 1].size += 256; | ||
420 | |||
421 | /* If this is an MPEG stream, and VBI data is also pending, then append the | ||
422 | VBI DMA to the MPEG DMA and transfer both sets of data at once. | ||
423 | |||
424 | VBI DMA is a second class citizen compared to MPEG and mixing them together | ||
425 | will confuse the firmware (the end of a VBI DMA is seen as the end of a | ||
426 | MPEG DMA, thus effectively dropping an MPEG frame). So instead we make | ||
427 | sure we only use the MPEG DMA to transfer the VBI DMA if both are in | ||
428 | use. This way no conflicts occur. */ | ||
429 | clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags); | ||
430 | if (s->type == IVTV_ENC_STREAM_TYPE_MPG && s_vbi->sg_pending_size && | ||
431 | s->sg_pending_size + s_vbi->sg_pending_size <= s->buffers) { | ||
432 | ivtv_queue_move(s_vbi, &s_vbi->q_predma, NULL, &s_vbi->q_dma, s_vbi->q_predma.bytesused); | ||
433 | if (ivtv_use_dma(s_vbi)) | ||
434 | s_vbi->sg_pending[s_vbi->sg_pending_size - 1].size += 256; | ||
435 | for (i = 0; i < s_vbi->sg_pending_size; i++) { | ||
436 | s->sg_pending[s->sg_pending_size++] = s_vbi->sg_pending[i]; | ||
437 | } | ||
438 | s_vbi->dma_offset = s_vbi->pending_offset; | ||
439 | s_vbi->sg_pending_size = 0; | ||
440 | s_vbi->dma_xfer_cnt++; | ||
441 | set_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags); | ||
442 | IVTV_DEBUG_HI_DMA("include DMA for %s\n", s_vbi->name); | ||
443 | } | ||
444 | |||
445 | s->dma_xfer_cnt++; | ||
446 | memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_host_element) * s->sg_pending_size); | ||
447 | s->sg_processing_size = s->sg_pending_size; | ||
448 | s->sg_pending_size = 0; | ||
449 | s->sg_processed = 0; | ||
450 | s->dma_offset = s->pending_offset; | ||
451 | s->dma_backup = s->pending_backup; | ||
452 | s->dma_pts = s->pending_pts; | ||
453 | |||
454 | if (ivtv_use_pio(s)) { | ||
455 | set_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags); | ||
456 | set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags); | ||
457 | set_bit(IVTV_F_I_PIO, &itv->i_flags); | ||
458 | itv->cur_pio_stream = s->type; | ||
459 | } | ||
460 | else { | ||
461 | itv->dma_retries = 0; | ||
462 | ivtv_dma_enc_start_xfer(s); | ||
463 | set_bit(IVTV_F_I_DMA, &itv->i_flags); | ||
464 | itv->cur_dma_stream = s->type; | ||
465 | } | ||
466 | } | ||
467 | |||
468 | static void ivtv_dma_dec_start(struct ivtv_stream *s) | ||
469 | { | ||
470 | struct ivtv *itv = s->itv; | ||
471 | |||
472 | if (s->q_predma.bytesused) | ||
473 | ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused); | ||
474 | s->dma_xfer_cnt++; | ||
475 | memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_host_element) * s->sg_pending_size); | ||
476 | s->sg_processing_size = s->sg_pending_size; | ||
477 | s->sg_pending_size = 0; | ||
478 | s->sg_processed = 0; | ||
479 | |||
480 | IVTV_DEBUG_HI_DMA("start DMA for %s\n", s->name); | ||
481 | itv->dma_retries = 0; | ||
482 | ivtv_dma_dec_start_xfer(s); | ||
483 | set_bit(IVTV_F_I_DMA, &itv->i_flags); | ||
484 | itv->cur_dma_stream = s->type; | ||
485 | } | ||
486 | |||
487 | static void ivtv_irq_dma_read(struct ivtv *itv) | ||
488 | { | ||
489 | struct ivtv_stream *s = NULL; | ||
490 | struct ivtv_buffer *buf; | ||
491 | int hw_stream_type = 0; | ||
492 | |||
493 | IVTV_DEBUG_HI_IRQ("DEC DMA READ\n"); | ||
494 | |||
495 | del_timer(&itv->dma_timer); | ||
496 | |||
497 | if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) && itv->cur_dma_stream < 0) | ||
498 | return; | ||
499 | |||
500 | if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags)) { | ||
501 | s = &itv->streams[itv->cur_dma_stream]; | ||
502 | ivtv_stream_sync_for_cpu(s); | ||
503 | |||
504 | if (read_reg(IVTV_REG_DMASTATUS) & 0x14) { | ||
505 | IVTV_DEBUG_WARN("DEC DMA ERROR %x (xfer %d of %d, retry %d)\n", | ||
506 | read_reg(IVTV_REG_DMASTATUS), | ||
507 | s->sg_processed, s->sg_processing_size, itv->dma_retries); | ||
508 | write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS); | ||
509 | if (itv->dma_retries == 3) { | ||
510 | /* Too many retries, give up on this frame */ | ||
511 | itv->dma_retries = 0; | ||
512 | s->sg_processed = s->sg_processing_size; | ||
513 | } | ||
514 | else { | ||
515 | /* Retry, starting with the first xfer segment. | ||
516 | Just retrying the current segment is not sufficient. */ | ||
517 | s->sg_processed = 0; | ||
518 | itv->dma_retries++; | ||
519 | } | ||
520 | } | ||
521 | if (s->sg_processed < s->sg_processing_size) { | ||
522 | /* DMA next buffer */ | ||
523 | ivtv_dma_dec_start_xfer(s); | ||
524 | return; | ||
525 | } | ||
526 | if (s->type == IVTV_DEC_STREAM_TYPE_YUV) | ||
527 | hw_stream_type = 2; | ||
528 | IVTV_DEBUG_HI_DMA("DEC DATA READ %s: %d\n", s->name, s->q_dma.bytesused); | ||
529 | |||
530 | /* For some reason must kick the firmware, like PIO mode, | ||
531 | I think this tells the firmware we are done and the size | ||
532 | of the xfer so it can calculate what we need next. | ||
533 | I think we can do this part ourselves but would have to | ||
534 | fully calculate xfer info ourselves and not use interrupts | ||
535 | */ | ||
536 | ivtv_vapi(itv, CX2341X_DEC_SCHED_DMA_FROM_HOST, 3, 0, s->q_dma.bytesused, | ||
537 | hw_stream_type); | ||
538 | |||
539 | /* Free last DMA call */ | ||
540 | while ((buf = ivtv_dequeue(s, &s->q_dma)) != NULL) { | ||
541 | ivtv_buf_sync_for_cpu(s, buf); | ||
542 | ivtv_enqueue(s, buf, &s->q_free); | ||
543 | } | ||
544 | wake_up(&s->waitq); | ||
545 | } | ||
546 | clear_bit(IVTV_F_I_UDMA, &itv->i_flags); | ||
547 | clear_bit(IVTV_F_I_DMA, &itv->i_flags); | ||
548 | itv->cur_dma_stream = -1; | ||
549 | wake_up(&itv->dma_waitq); | ||
550 | } | ||
551 | |||
552 | static void ivtv_irq_enc_dma_complete(struct ivtv *itv) | ||
553 | { | ||
554 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
555 | struct ivtv_stream *s; | ||
556 | |||
557 | ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data); | ||
558 | IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d (%d)\n", data[0], data[1], itv->cur_dma_stream); | ||
559 | |||
560 | del_timer(&itv->dma_timer); | ||
561 | |||
562 | if (itv->cur_dma_stream < 0) | ||
563 | return; | ||
564 | |||
565 | s = &itv->streams[itv->cur_dma_stream]; | ||
566 | ivtv_stream_sync_for_cpu(s); | ||
567 | |||
568 | if (data[0] & 0x18) { | ||
569 | IVTV_DEBUG_WARN("ENC DMA ERROR %x (offset %08x, xfer %d of %d, retry %d)\n", data[0], | ||
570 | s->dma_offset, s->sg_processed, s->sg_processing_size, itv->dma_retries); | ||
571 | write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS); | ||
572 | if (itv->dma_retries == 3) { | ||
573 | /* Too many retries, give up on this frame */ | ||
574 | itv->dma_retries = 0; | ||
575 | s->sg_processed = s->sg_processing_size; | ||
576 | } | ||
577 | else { | ||
578 | /* Retry, starting with the first xfer segment. | ||
579 | Just retrying the current segment is not sufficient. */ | ||
580 | s->sg_processed = 0; | ||
581 | itv->dma_retries++; | ||
582 | } | ||
583 | } | ||
584 | if (s->sg_processed < s->sg_processing_size) { | ||
585 | /* DMA next buffer */ | ||
586 | ivtv_dma_enc_start_xfer(s); | ||
587 | return; | ||
588 | } | ||
589 | clear_bit(IVTV_F_I_DMA, &itv->i_flags); | ||
590 | itv->cur_dma_stream = -1; | ||
591 | dma_post(s); | ||
592 | if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) { | ||
593 | s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; | ||
594 | dma_post(s); | ||
595 | } | ||
596 | s->sg_processing_size = 0; | ||
597 | s->sg_processed = 0; | ||
598 | wake_up(&itv->dma_waitq); | ||
599 | } | ||
600 | |||
601 | static void ivtv_irq_enc_pio_complete(struct ivtv *itv) | ||
602 | { | ||
603 | struct ivtv_stream *s; | ||
604 | |||
605 | if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS) { | ||
606 | itv->cur_pio_stream = -1; | ||
607 | return; | ||
608 | } | ||
609 | s = &itv->streams[itv->cur_pio_stream]; | ||
610 | IVTV_DEBUG_HI_IRQ("ENC PIO COMPLETE %s\n", s->name); | ||
611 | clear_bit(IVTV_F_I_PIO, &itv->i_flags); | ||
612 | itv->cur_pio_stream = -1; | ||
613 | dma_post(s); | ||
614 | if (s->type == IVTV_ENC_STREAM_TYPE_MPG) | ||
615 | ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 0); | ||
616 | else if (s->type == IVTV_ENC_STREAM_TYPE_YUV) | ||
617 | ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 1); | ||
618 | else if (s->type == IVTV_ENC_STREAM_TYPE_PCM) | ||
619 | ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 2); | ||
620 | clear_bit(IVTV_F_I_PIO, &itv->i_flags); | ||
621 | if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) { | ||
622 | s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; | ||
623 | dma_post(s); | ||
624 | } | ||
625 | wake_up(&itv->dma_waitq); | ||
626 | } | ||
627 | |||
628 | static void ivtv_irq_dma_err(struct ivtv *itv) | ||
629 | { | ||
630 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
631 | u32 status; | ||
632 | |||
633 | del_timer(&itv->dma_timer); | ||
634 | |||
635 | ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data); | ||
636 | status = read_reg(IVTV_REG_DMASTATUS); | ||
637 | IVTV_DEBUG_WARN("DMA ERROR %08x %08x %08x %d\n", data[0], data[1], | ||
638 | status, itv->cur_dma_stream); | ||
639 | /* | ||
640 | * We do *not* write back to the IVTV_REG_DMASTATUS register to | ||
641 | * clear the error status, if either the encoder write (0x02) or | ||
642 | * decoder read (0x01) bus master DMA operation do not indicate | ||
643 | * completed. We can race with the DMA engine, which may have | ||
644 | * transitioned to completed status *after* we read the register. | ||
645 | * Setting a IVTV_REG_DMASTATUS flag back to "busy" status, after the | ||
646 | * DMA engine has completed, will cause the DMA engine to stop working. | ||
647 | */ | ||
648 | status &= 0x3; | ||
649 | if (status == 0x3) | ||
650 | write_reg(status, IVTV_REG_DMASTATUS); | ||
651 | |||
652 | if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) && | ||
653 | itv->cur_dma_stream >= 0 && itv->cur_dma_stream < IVTV_MAX_STREAMS) { | ||
654 | struct ivtv_stream *s = &itv->streams[itv->cur_dma_stream]; | ||
655 | |||
656 | if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) { | ||
657 | /* retry */ | ||
658 | /* | ||
659 | * FIXME - handle cases of DMA error similar to | ||
660 | * encoder below, except conditioned on status & 0x1 | ||
661 | */ | ||
662 | ivtv_dma_dec_start(s); | ||
663 | return; | ||
664 | } else { | ||
665 | if ((status & 0x2) == 0) { | ||
666 | /* | ||
667 | * CX2341x Bus Master DMA write is ongoing. | ||
668 | * Reset the timer and let it complete. | ||
669 | */ | ||
670 | itv->dma_timer.expires = | ||
671 | jiffies + msecs_to_jiffies(600); | ||
672 | add_timer(&itv->dma_timer); | ||
673 | return; | ||
674 | } | ||
675 | |||
676 | if (itv->dma_retries < 3) { | ||
677 | /* | ||
678 | * CX2341x Bus Master DMA write has ended. | ||
679 | * Retry the write, starting with the first | ||
680 | * xfer segment. Just retrying the current | ||
681 | * segment is not sufficient. | ||
682 | */ | ||
683 | s->sg_processed = 0; | ||
684 | itv->dma_retries++; | ||
685 | ivtv_dma_enc_start_xfer(s); | ||
686 | return; | ||
687 | } | ||
688 | /* Too many retries, give up on this one */ | ||
689 | } | ||
690 | |||
691 | } | ||
692 | if (test_bit(IVTV_F_I_UDMA, &itv->i_flags)) { | ||
693 | ivtv_udma_start(itv); | ||
694 | return; | ||
695 | } | ||
696 | clear_bit(IVTV_F_I_UDMA, &itv->i_flags); | ||
697 | clear_bit(IVTV_F_I_DMA, &itv->i_flags); | ||
698 | itv->cur_dma_stream = -1; | ||
699 | wake_up(&itv->dma_waitq); | ||
700 | } | ||
701 | |||
702 | static void ivtv_irq_enc_start_cap(struct ivtv *itv) | ||
703 | { | ||
704 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
705 | struct ivtv_stream *s; | ||
706 | |||
707 | /* Get DMA destination and size arguments from card */ | ||
708 | ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA, 7, data); | ||
709 | IVTV_DEBUG_HI_IRQ("ENC START CAP %d: %08x %08x\n", data[0], data[1], data[2]); | ||
710 | |||
711 | if (data[0] > 2 || data[1] == 0 || data[2] == 0) { | ||
712 | IVTV_DEBUG_WARN("Unknown input: %08x %08x %08x\n", | ||
713 | data[0], data[1], data[2]); | ||
714 | return; | ||
715 | } | ||
716 | s = &itv->streams[ivtv_stream_map[data[0]]]; | ||
717 | if (!stream_enc_dma_append(s, data)) { | ||
718 | set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags); | ||
719 | } | ||
720 | } | ||
721 | |||
722 | static void ivtv_irq_enc_vbi_cap(struct ivtv *itv) | ||
723 | { | ||
724 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
725 | struct ivtv_stream *s; | ||
726 | |||
727 | IVTV_DEBUG_HI_IRQ("ENC START VBI CAP\n"); | ||
728 | s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; | ||
729 | |||
730 | if (!stream_enc_dma_append(s, data)) | ||
731 | set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags); | ||
732 | } | ||
733 | |||
734 | static void ivtv_irq_dec_vbi_reinsert(struct ivtv *itv) | ||
735 | { | ||
736 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
737 | struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI]; | ||
738 | |||
739 | IVTV_DEBUG_HI_IRQ("DEC VBI REINSERT\n"); | ||
740 | if (test_bit(IVTV_F_S_CLAIMED, &s->s_flags) && | ||
741 | !stream_enc_dma_append(s, data)) { | ||
742 | set_bit(IVTV_F_S_PIO_PENDING, &s->s_flags); | ||
743 | } | ||
744 | } | ||
745 | |||
746 | static void ivtv_irq_dec_data_req(struct ivtv *itv) | ||
747 | { | ||
748 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
749 | struct ivtv_stream *s; | ||
750 | |||
751 | /* YUV or MPG */ | ||
752 | |||
753 | if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) { | ||
754 | ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 2, data); | ||
755 | itv->dma_data_req_size = | ||
756 | 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31); | ||
757 | itv->dma_data_req_offset = data[1]; | ||
758 | if (atomic_read(&itv->yuv_info.next_dma_frame) >= 0) | ||
759 | ivtv_yuv_frame_complete(itv); | ||
760 | s = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV]; | ||
761 | } | ||
762 | else { | ||
763 | ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 3, data); | ||
764 | itv->dma_data_req_size = min_t(u32, data[2], 0x10000); | ||
765 | itv->dma_data_req_offset = data[1]; | ||
766 | s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG]; | ||
767 | } | ||
768 | IVTV_DEBUG_HI_IRQ("DEC DATA REQ %s: %d %08x %u\n", s->name, s->q_full.bytesused, | ||
769 | itv->dma_data_req_offset, itv->dma_data_req_size); | ||
770 | if (itv->dma_data_req_size == 0 || s->q_full.bytesused < itv->dma_data_req_size) { | ||
771 | set_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags); | ||
772 | } | ||
773 | else { | ||
774 | if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) | ||
775 | ivtv_yuv_setup_stream_frame(itv); | ||
776 | clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags); | ||
777 | ivtv_queue_move(s, &s->q_full, NULL, &s->q_predma, itv->dma_data_req_size); | ||
778 | ivtv_dma_stream_dec_prepare(s, itv->dma_data_req_offset + IVTV_DECODER_OFFSET, 0); | ||
779 | } | ||
780 | } | ||
781 | |||
782 | static void ivtv_irq_vsync(struct ivtv *itv) | ||
783 | { | ||
784 | /* The vsync interrupt is unusual in that it won't clear until | ||
785 | * the end of the first line for the current field, at which | ||
786 | * point it clears itself. This can result in repeated vsync | ||
787 | * interrupts, or a missed vsync. Read some of the registers | ||
788 | * to determine the line being displayed and ensure we handle | ||
789 | * one vsync per frame. | ||
790 | */ | ||
791 | unsigned int frame = read_reg(IVTV_REG_DEC_LINE_FIELD) & 1; | ||
792 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
793 | int last_dma_frame = atomic_read(&yi->next_dma_frame); | ||
794 | struct yuv_frame_info *f = &yi->new_frame_info[last_dma_frame]; | ||
795 | |||
796 | if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n"); | ||
797 | |||
798 | if (((frame ^ f->sync_field) == 0 && | ||
799 | ((itv->last_vsync_field & 1) ^ f->sync_field)) || | ||
800 | (frame != (itv->last_vsync_field & 1) && !f->interlaced)) { | ||
801 | int next_dma_frame = last_dma_frame; | ||
802 | |||
803 | if (!(f->interlaced && f->delay && yi->fields_lapsed < 1)) { | ||
804 | if (next_dma_frame >= 0 && next_dma_frame != atomic_read(&yi->next_fill_frame)) { | ||
805 | write_reg(yuv_offset[next_dma_frame] >> 4, 0x82c); | ||
806 | write_reg((yuv_offset[next_dma_frame] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x830); | ||
807 | write_reg(yuv_offset[next_dma_frame] >> 4, 0x834); | ||
808 | write_reg((yuv_offset[next_dma_frame] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x838); | ||
809 | next_dma_frame = (next_dma_frame + 1) % IVTV_YUV_BUFFERS; | ||
810 | atomic_set(&yi->next_dma_frame, next_dma_frame); | ||
811 | yi->fields_lapsed = -1; | ||
812 | yi->running = 1; | ||
813 | } | ||
814 | } | ||
815 | } | ||
816 | if (frame != (itv->last_vsync_field & 1)) { | ||
817 | static const struct v4l2_event evtop = { | ||
818 | .type = V4L2_EVENT_VSYNC, | ||
819 | .u.vsync.field = V4L2_FIELD_TOP, | ||
820 | }; | ||
821 | static const struct v4l2_event evbottom = { | ||
822 | .type = V4L2_EVENT_VSYNC, | ||
823 | .u.vsync.field = V4L2_FIELD_BOTTOM, | ||
824 | }; | ||
825 | struct ivtv_stream *s = ivtv_get_output_stream(itv); | ||
826 | |||
827 | itv->last_vsync_field += 1; | ||
828 | if (frame == 0) { | ||
829 | clear_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags); | ||
830 | clear_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags); | ||
831 | } | ||
832 | else { | ||
833 | set_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags); | ||
834 | } | ||
835 | if (test_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags)) { | ||
836 | set_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags); | ||
837 | wake_up(&itv->event_waitq); | ||
838 | if (s) | ||
839 | wake_up(&s->waitq); | ||
840 | } | ||
841 | if (s && s->vdev) | ||
842 | v4l2_event_queue(s->vdev, frame ? &evtop : &evbottom); | ||
843 | wake_up(&itv->vsync_waitq); | ||
844 | |||
845 | /* Send VBI to saa7127 */ | ||
846 | if (frame && (itv->output_mode == OUT_PASSTHROUGH || | ||
847 | test_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags) || | ||
848 | test_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags) || | ||
849 | test_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags))) { | ||
850 | set_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags); | ||
851 | set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags); | ||
852 | } | ||
853 | |||
854 | /* Check if we need to update the yuv registers */ | ||
855 | if (yi->running && (yi->yuv_forced_update || f->update)) { | ||
856 | if (!f->update) { | ||
857 | last_dma_frame = | ||
858 | (u8)(atomic_read(&yi->next_dma_frame) - | ||
859 | 1) % IVTV_YUV_BUFFERS; | ||
860 | f = &yi->new_frame_info[last_dma_frame]; | ||
861 | } | ||
862 | |||
863 | if (f->src_w) { | ||
864 | yi->update_frame = last_dma_frame; | ||
865 | f->update = 0; | ||
866 | yi->yuv_forced_update = 0; | ||
867 | set_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags); | ||
868 | set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags); | ||
869 | } | ||
870 | } | ||
871 | |||
872 | yi->fields_lapsed++; | ||
873 | } | ||
874 | } | ||
875 | |||
876 | #define IVTV_IRQ_DMA (IVTV_IRQ_DMA_READ | IVTV_IRQ_ENC_DMA_COMPLETE | IVTV_IRQ_DMA_ERR | IVTV_IRQ_ENC_START_CAP | IVTV_IRQ_ENC_VBI_CAP | IVTV_IRQ_DEC_DATA_REQ | IVTV_IRQ_DEC_VBI_RE_INSERT) | ||
877 | |||
878 | irqreturn_t ivtv_irq_handler(int irq, void *dev_id) | ||
879 | { | ||
880 | struct ivtv *itv = (struct ivtv *)dev_id; | ||
881 | u32 combo; | ||
882 | u32 stat; | ||
883 | int i; | ||
884 | u8 vsync_force = 0; | ||
885 | |||
886 | spin_lock(&itv->dma_reg_lock); | ||
887 | /* get contents of irq status register */ | ||
888 | stat = read_reg(IVTV_REG_IRQSTATUS); | ||
889 | |||
890 | combo = ~itv->irqmask & stat; | ||
891 | |||
892 | /* Clear out IRQ */ | ||
893 | if (combo) write_reg(combo, IVTV_REG_IRQSTATUS); | ||
894 | |||
895 | if (0 == combo) { | ||
896 | /* The vsync interrupt is unusual and clears itself. If we | ||
897 | * took too long, we may have missed it. Do some checks | ||
898 | */ | ||
899 | if (~itv->irqmask & IVTV_IRQ_DEC_VSYNC) { | ||
900 | /* vsync is enabled, see if we're in a new field */ | ||
901 | if ((itv->last_vsync_field & 1) != | ||
902 | (read_reg(IVTV_REG_DEC_LINE_FIELD) & 1)) { | ||
903 | /* New field, looks like we missed it */ | ||
904 | IVTV_DEBUG_YUV("VSync interrupt missed %d\n", | ||
905 | read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16); | ||
906 | vsync_force = 1; | ||
907 | } | ||
908 | } | ||
909 | |||
910 | if (!vsync_force) { | ||
911 | /* No Vsync expected, wasn't for us */ | ||
912 | spin_unlock(&itv->dma_reg_lock); | ||
913 | return IRQ_NONE; | ||
914 | } | ||
915 | } | ||
916 | |||
917 | /* Exclude interrupts noted below from the output, otherwise the log is flooded with | ||
918 | these messages */ | ||
919 | if (combo & ~0xff6d0400) | ||
920 | IVTV_DEBUG_HI_IRQ("======= valid IRQ bits: 0x%08x ======\n", combo); | ||
921 | |||
922 | if (combo & IVTV_IRQ_DEC_DMA_COMPLETE) { | ||
923 | IVTV_DEBUG_HI_IRQ("DEC DMA COMPLETE\n"); | ||
924 | } | ||
925 | |||
926 | if (combo & IVTV_IRQ_DMA_READ) { | ||
927 | ivtv_irq_dma_read(itv); | ||
928 | } | ||
929 | |||
930 | if (combo & IVTV_IRQ_ENC_DMA_COMPLETE) { | ||
931 | ivtv_irq_enc_dma_complete(itv); | ||
932 | } | ||
933 | |||
934 | if (combo & IVTV_IRQ_ENC_PIO_COMPLETE) { | ||
935 | ivtv_irq_enc_pio_complete(itv); | ||
936 | } | ||
937 | |||
938 | if (combo & IVTV_IRQ_DMA_ERR) { | ||
939 | ivtv_irq_dma_err(itv); | ||
940 | } | ||
941 | |||
942 | if (combo & IVTV_IRQ_ENC_START_CAP) { | ||
943 | ivtv_irq_enc_start_cap(itv); | ||
944 | } | ||
945 | |||
946 | if (combo & IVTV_IRQ_ENC_VBI_CAP) { | ||
947 | ivtv_irq_enc_vbi_cap(itv); | ||
948 | } | ||
949 | |||
950 | if (combo & IVTV_IRQ_DEC_VBI_RE_INSERT) { | ||
951 | ivtv_irq_dec_vbi_reinsert(itv); | ||
952 | } | ||
953 | |||
954 | if (combo & IVTV_IRQ_ENC_EOS) { | ||
955 | IVTV_DEBUG_IRQ("ENC EOS\n"); | ||
956 | set_bit(IVTV_F_I_EOS, &itv->i_flags); | ||
957 | wake_up(&itv->eos_waitq); | ||
958 | } | ||
959 | |||
960 | if (combo & IVTV_IRQ_DEC_DATA_REQ) { | ||
961 | ivtv_irq_dec_data_req(itv); | ||
962 | } | ||
963 | |||
964 | /* Decoder Vertical Sync - We can't rely on 'combo', so check if vsync enabled */ | ||
965 | if (~itv->irqmask & IVTV_IRQ_DEC_VSYNC) { | ||
966 | ivtv_irq_vsync(itv); | ||
967 | } | ||
968 | |||
969 | if (combo & IVTV_IRQ_ENC_VIM_RST) { | ||
970 | IVTV_DEBUG_IRQ("VIM RST\n"); | ||
971 | /*ivtv_vapi(itv, CX2341X_ENC_REFRESH_INPUT, 0); */ | ||
972 | } | ||
973 | |||
974 | if (combo & IVTV_IRQ_DEC_AUD_MODE_CHG) { | ||
975 | IVTV_DEBUG_INFO("Stereo mode changed\n"); | ||
976 | } | ||
977 | |||
978 | if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_DMA, &itv->i_flags)) { | ||
979 | itv->irq_rr_idx++; | ||
980 | for (i = 0; i < IVTV_MAX_STREAMS; i++) { | ||
981 | int idx = (i + itv->irq_rr_idx) % IVTV_MAX_STREAMS; | ||
982 | struct ivtv_stream *s = &itv->streams[idx]; | ||
983 | |||
984 | if (!test_and_clear_bit(IVTV_F_S_DMA_PENDING, &s->s_flags)) | ||
985 | continue; | ||
986 | if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) | ||
987 | ivtv_dma_dec_start(s); | ||
988 | else | ||
989 | ivtv_dma_enc_start(s); | ||
990 | break; | ||
991 | } | ||
992 | |||
993 | if (i == IVTV_MAX_STREAMS && | ||
994 | test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags)) | ||
995 | ivtv_udma_start(itv); | ||
996 | } | ||
997 | |||
998 | if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_PIO, &itv->i_flags)) { | ||
999 | itv->irq_rr_idx++; | ||
1000 | for (i = 0; i < IVTV_MAX_STREAMS; i++) { | ||
1001 | int idx = (i + itv->irq_rr_idx) % IVTV_MAX_STREAMS; | ||
1002 | struct ivtv_stream *s = &itv->streams[idx]; | ||
1003 | |||
1004 | if (!test_and_clear_bit(IVTV_F_S_PIO_PENDING, &s->s_flags)) | ||
1005 | continue; | ||
1006 | if (s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type < IVTV_DEC_STREAM_TYPE_MPG) | ||
1007 | ivtv_dma_enc_start(s); | ||
1008 | break; | ||
1009 | } | ||
1010 | } | ||
1011 | |||
1012 | if (test_and_clear_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags)) { | ||
1013 | queue_kthread_work(&itv->irq_worker, &itv->irq_work); | ||
1014 | } | ||
1015 | |||
1016 | spin_unlock(&itv->dma_reg_lock); | ||
1017 | |||
1018 | /* If we've just handled a 'forced' vsync, it's safest to say it | ||
1019 | * wasn't ours. Another device may have triggered it at just | ||
1020 | * the right time. | ||
1021 | */ | ||
1022 | return vsync_force ? IRQ_NONE : IRQ_HANDLED; | ||
1023 | } | ||
1024 | |||
1025 | void ivtv_unfinished_dma(unsigned long arg) | ||
1026 | { | ||
1027 | struct ivtv *itv = (struct ivtv *)arg; | ||
1028 | |||
1029 | if (!test_bit(IVTV_F_I_DMA, &itv->i_flags)) | ||
1030 | return; | ||
1031 | IVTV_ERR("DMA TIMEOUT %08x %d\n", read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream); | ||
1032 | |||
1033 | write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS); | ||
1034 | clear_bit(IVTV_F_I_UDMA, &itv->i_flags); | ||
1035 | clear_bit(IVTV_F_I_DMA, &itv->i_flags); | ||
1036 | itv->cur_dma_stream = -1; | ||
1037 | wake_up(&itv->dma_waitq); | ||
1038 | } | ||
diff --git a/drivers/media/video/ivtv/ivtv-irq.h b/drivers/media/video/ivtv/ivtv-irq.h new file mode 100644 index 00000000000..1e84433737c --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-irq.h | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | interrupt handling | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2004 Chris Kennedy <c@groovy.org> | ||
5 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #ifndef IVTV_IRQ_H | ||
23 | #define IVTV_IRQ_H | ||
24 | |||
25 | #define IVTV_IRQ_ENC_START_CAP (0x1 << 31) | ||
26 | #define IVTV_IRQ_ENC_EOS (0x1 << 30) | ||
27 | #define IVTV_IRQ_ENC_VBI_CAP (0x1 << 29) | ||
28 | #define IVTV_IRQ_ENC_VIM_RST (0x1 << 28) | ||
29 | #define IVTV_IRQ_ENC_DMA_COMPLETE (0x1 << 27) | ||
30 | #define IVTV_IRQ_ENC_PIO_COMPLETE (0x1 << 25) | ||
31 | #define IVTV_IRQ_DEC_AUD_MODE_CHG (0x1 << 24) | ||
32 | #define IVTV_IRQ_DEC_DATA_REQ (0x1 << 22) | ||
33 | #define IVTV_IRQ_DEC_DMA_COMPLETE (0x1 << 20) | ||
34 | #define IVTV_IRQ_DEC_VBI_RE_INSERT (0x1 << 19) | ||
35 | #define IVTV_IRQ_DMA_ERR (0x1 << 18) | ||
36 | #define IVTV_IRQ_DMA_WRITE (0x1 << 17) | ||
37 | #define IVTV_IRQ_DMA_READ (0x1 << 16) | ||
38 | #define IVTV_IRQ_DEC_VSYNC (0x1 << 10) | ||
39 | |||
40 | /* IRQ Masks */ | ||
41 | #define IVTV_IRQ_MASK_INIT (IVTV_IRQ_DMA_ERR|IVTV_IRQ_ENC_DMA_COMPLETE|\ | ||
42 | IVTV_IRQ_DMA_READ|IVTV_IRQ_ENC_PIO_COMPLETE) | ||
43 | |||
44 | #define IVTV_IRQ_MASK_CAPTURE (IVTV_IRQ_ENC_START_CAP | IVTV_IRQ_ENC_EOS) | ||
45 | #define IVTV_IRQ_MASK_DECODE (IVTV_IRQ_DEC_DATA_REQ|IVTV_IRQ_DEC_AUD_MODE_CHG) | ||
46 | |||
47 | irqreturn_t ivtv_irq_handler(int irq, void *dev_id); | ||
48 | |||
49 | void ivtv_irq_work_handler(struct kthread_work *work); | ||
50 | void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock); | ||
51 | void ivtv_unfinished_dma(unsigned long arg); | ||
52 | |||
53 | #endif | ||
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.c b/drivers/media/video/ivtv/ivtv-mailbox.c new file mode 100644 index 00000000000..e3ce9676378 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-mailbox.c | |||
@@ -0,0 +1,387 @@ | |||
1 | /* | ||
2 | mailbox functions | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2004 Chris Kennedy <c@groovy.org> | ||
5 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <stdarg.h> | ||
23 | |||
24 | #include "ivtv-driver.h" | ||
25 | #include "ivtv-mailbox.h" | ||
26 | |||
27 | /* Firmware mailbox flags*/ | ||
28 | #define IVTV_MBOX_FIRMWARE_DONE 0x00000004 | ||
29 | #define IVTV_MBOX_DRIVER_DONE 0x00000002 | ||
30 | #define IVTV_MBOX_DRIVER_BUSY 0x00000001 | ||
31 | #define IVTV_MBOX_FREE 0x00000000 | ||
32 | |||
33 | /* Firmware mailbox standard timeout */ | ||
34 | #define IVTV_API_STD_TIMEOUT 0x02000000 | ||
35 | |||
36 | #define API_CACHE (1 << 0) /* Allow the command to be stored in the cache */ | ||
37 | #define API_RESULT (1 << 1) /* Allow 1 second for this cmd to end */ | ||
38 | #define API_FAST_RESULT (3 << 1) /* Allow 0.1 second for this cmd to end */ | ||
39 | #define API_DMA (1 << 3) /* DMA mailbox, has special handling */ | ||
40 | #define API_HIGH_VOL (1 << 5) /* High volume command (i.e. called during encoding or decoding) */ | ||
41 | #define API_NO_WAIT_MB (1 << 4) /* Command may not wait for a free mailbox */ | ||
42 | #define API_NO_WAIT_RES (1 << 5) /* Command may not wait for the result */ | ||
43 | #define API_NO_POLL (1 << 6) /* Avoid pointless polling */ | ||
44 | |||
45 | struct ivtv_api_info { | ||
46 | int flags; /* Flags, see above */ | ||
47 | const char *name; /* The name of the command */ | ||
48 | }; | ||
49 | |||
50 | #define API_ENTRY(x, f) [x] = { (f), #x } | ||
51 | |||
52 | static const struct ivtv_api_info api_info[256] = { | ||
53 | /* MPEG encoder API */ | ||
54 | API_ENTRY(CX2341X_ENC_PING_FW, API_FAST_RESULT), | ||
55 | API_ENTRY(CX2341X_ENC_START_CAPTURE, API_RESULT | API_NO_POLL), | ||
56 | API_ENTRY(CX2341X_ENC_STOP_CAPTURE, API_RESULT), | ||
57 | API_ENTRY(CX2341X_ENC_SET_AUDIO_ID, API_CACHE), | ||
58 | API_ENTRY(CX2341X_ENC_SET_VIDEO_ID, API_CACHE), | ||
59 | API_ENTRY(CX2341X_ENC_SET_PCR_ID, API_CACHE), | ||
60 | API_ENTRY(CX2341X_ENC_SET_FRAME_RATE, API_CACHE), | ||
61 | API_ENTRY(CX2341X_ENC_SET_FRAME_SIZE, API_CACHE), | ||
62 | API_ENTRY(CX2341X_ENC_SET_BIT_RATE, API_CACHE), | ||
63 | API_ENTRY(CX2341X_ENC_SET_GOP_PROPERTIES, API_CACHE), | ||
64 | API_ENTRY(CX2341X_ENC_SET_ASPECT_RATIO, API_CACHE), | ||
65 | API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_MODE, API_CACHE), | ||
66 | API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_PROPS, API_CACHE), | ||
67 | API_ENTRY(CX2341X_ENC_SET_CORING_LEVELS, API_CACHE), | ||
68 | API_ENTRY(CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, API_CACHE), | ||
69 | API_ENTRY(CX2341X_ENC_SET_VBI_LINE, API_RESULT), | ||
70 | API_ENTRY(CX2341X_ENC_SET_STREAM_TYPE, API_CACHE), | ||
71 | API_ENTRY(CX2341X_ENC_SET_OUTPUT_PORT, API_CACHE), | ||
72 | API_ENTRY(CX2341X_ENC_SET_AUDIO_PROPERTIES, API_CACHE), | ||
73 | API_ENTRY(CX2341X_ENC_HALT_FW, API_FAST_RESULT), | ||
74 | API_ENTRY(CX2341X_ENC_GET_VERSION, API_FAST_RESULT), | ||
75 | API_ENTRY(CX2341X_ENC_SET_GOP_CLOSURE, API_CACHE), | ||
76 | API_ENTRY(CX2341X_ENC_GET_SEQ_END, API_RESULT), | ||
77 | API_ENTRY(CX2341X_ENC_SET_PGM_INDEX_INFO, API_FAST_RESULT), | ||
78 | API_ENTRY(CX2341X_ENC_SET_VBI_CONFIG, API_RESULT), | ||
79 | API_ENTRY(CX2341X_ENC_SET_DMA_BLOCK_SIZE, API_CACHE), | ||
80 | API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_10, API_FAST_RESULT), | ||
81 | API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_9, API_FAST_RESULT), | ||
82 | API_ENTRY(CX2341X_ENC_SCHED_DMA_TO_HOST, API_DMA | API_HIGH_VOL), | ||
83 | API_ENTRY(CX2341X_ENC_INITIALIZE_INPUT, API_RESULT), | ||
84 | API_ENTRY(CX2341X_ENC_SET_FRAME_DROP_RATE, API_CACHE), | ||
85 | API_ENTRY(CX2341X_ENC_PAUSE_ENCODER, API_RESULT), | ||
86 | API_ENTRY(CX2341X_ENC_REFRESH_INPUT, API_NO_WAIT_MB | API_HIGH_VOL), | ||
87 | API_ENTRY(CX2341X_ENC_SET_COPYRIGHT, API_CACHE), | ||
88 | API_ENTRY(CX2341X_ENC_SET_EVENT_NOTIFICATION, API_RESULT), | ||
89 | API_ENTRY(CX2341X_ENC_SET_NUM_VSYNC_LINES, API_CACHE), | ||
90 | API_ENTRY(CX2341X_ENC_SET_PLACEHOLDER, API_CACHE), | ||
91 | API_ENTRY(CX2341X_ENC_MUTE_VIDEO, API_RESULT), | ||
92 | API_ENTRY(CX2341X_ENC_MUTE_AUDIO, API_RESULT), | ||
93 | API_ENTRY(CX2341X_ENC_SET_VERT_CROP_LINE, API_FAST_RESULT), | ||
94 | API_ENTRY(CX2341X_ENC_MISC, API_FAST_RESULT), | ||
95 | /* Obsolete PULLDOWN API command */ | ||
96 | API_ENTRY(0xb1, API_CACHE), | ||
97 | |||
98 | /* MPEG decoder API */ | ||
99 | API_ENTRY(CX2341X_DEC_PING_FW, API_FAST_RESULT), | ||
100 | API_ENTRY(CX2341X_DEC_START_PLAYBACK, API_RESULT | API_NO_POLL), | ||
101 | API_ENTRY(CX2341X_DEC_STOP_PLAYBACK, API_RESULT), | ||
102 | API_ENTRY(CX2341X_DEC_SET_PLAYBACK_SPEED, API_RESULT), | ||
103 | API_ENTRY(CX2341X_DEC_STEP_VIDEO, API_RESULT), | ||
104 | API_ENTRY(CX2341X_DEC_SET_DMA_BLOCK_SIZE, API_CACHE), | ||
105 | API_ENTRY(CX2341X_DEC_GET_XFER_INFO, API_FAST_RESULT), | ||
106 | API_ENTRY(CX2341X_DEC_GET_DMA_STATUS, API_FAST_RESULT), | ||
107 | API_ENTRY(CX2341X_DEC_SCHED_DMA_FROM_HOST, API_DMA | API_HIGH_VOL), | ||
108 | API_ENTRY(CX2341X_DEC_PAUSE_PLAYBACK, API_RESULT), | ||
109 | API_ENTRY(CX2341X_DEC_HALT_FW, API_FAST_RESULT), | ||
110 | API_ENTRY(CX2341X_DEC_SET_STANDARD, API_CACHE), | ||
111 | API_ENTRY(CX2341X_DEC_GET_VERSION, API_FAST_RESULT), | ||
112 | API_ENTRY(CX2341X_DEC_SET_STREAM_INPUT, API_CACHE), | ||
113 | API_ENTRY(CX2341X_DEC_GET_TIMING_INFO, API_RESULT /*| API_NO_WAIT_RES*/), | ||
114 | API_ENTRY(CX2341X_DEC_SET_AUDIO_MODE, API_CACHE), | ||
115 | API_ENTRY(CX2341X_DEC_SET_EVENT_NOTIFICATION, API_RESULT), | ||
116 | API_ENTRY(CX2341X_DEC_SET_DISPLAY_BUFFERS, API_CACHE), | ||
117 | API_ENTRY(CX2341X_DEC_EXTRACT_VBI, API_RESULT), | ||
118 | API_ENTRY(CX2341X_DEC_SET_DECODER_SOURCE, API_FAST_RESULT), | ||
119 | API_ENTRY(CX2341X_DEC_SET_PREBUFFERING, API_CACHE), | ||
120 | |||
121 | /* OSD API */ | ||
122 | API_ENTRY(CX2341X_OSD_GET_FRAMEBUFFER, API_FAST_RESULT), | ||
123 | API_ENTRY(CX2341X_OSD_GET_PIXEL_FORMAT, API_FAST_RESULT), | ||
124 | API_ENTRY(CX2341X_OSD_SET_PIXEL_FORMAT, API_CACHE), | ||
125 | API_ENTRY(CX2341X_OSD_GET_STATE, API_FAST_RESULT), | ||
126 | API_ENTRY(CX2341X_OSD_SET_STATE, API_CACHE), | ||
127 | API_ENTRY(CX2341X_OSD_GET_OSD_COORDS, API_FAST_RESULT), | ||
128 | API_ENTRY(CX2341X_OSD_SET_OSD_COORDS, API_CACHE), | ||
129 | API_ENTRY(CX2341X_OSD_GET_SCREEN_COORDS, API_FAST_RESULT), | ||
130 | API_ENTRY(CX2341X_OSD_SET_SCREEN_COORDS, API_CACHE), | ||
131 | API_ENTRY(CX2341X_OSD_GET_GLOBAL_ALPHA, API_FAST_RESULT), | ||
132 | API_ENTRY(CX2341X_OSD_SET_GLOBAL_ALPHA, API_CACHE), | ||
133 | API_ENTRY(CX2341X_OSD_SET_BLEND_COORDS, API_CACHE), | ||
134 | API_ENTRY(CX2341X_OSD_GET_FLICKER_STATE, API_FAST_RESULT), | ||
135 | API_ENTRY(CX2341X_OSD_SET_FLICKER_STATE, API_CACHE), | ||
136 | API_ENTRY(CX2341X_OSD_BLT_COPY, API_RESULT), | ||
137 | API_ENTRY(CX2341X_OSD_BLT_FILL, API_RESULT), | ||
138 | API_ENTRY(CX2341X_OSD_BLT_TEXT, API_RESULT), | ||
139 | API_ENTRY(CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, API_CACHE), | ||
140 | API_ENTRY(CX2341X_OSD_SET_CHROMA_KEY, API_CACHE), | ||
141 | API_ENTRY(CX2341X_OSD_GET_ALPHA_CONTENT_INDEX, API_FAST_RESULT), | ||
142 | API_ENTRY(CX2341X_OSD_SET_ALPHA_CONTENT_INDEX, API_CACHE) | ||
143 | }; | ||
144 | |||
145 | static int try_mailbox(struct ivtv *itv, struct ivtv_mailbox_data *mbdata, int mb) | ||
146 | { | ||
147 | u32 flags = readl(&mbdata->mbox[mb].flags); | ||
148 | int is_free = flags == IVTV_MBOX_FREE || (flags & IVTV_MBOX_FIRMWARE_DONE); | ||
149 | |||
150 | /* if the mailbox is free, then try to claim it */ | ||
151 | if (is_free && !test_and_set_bit(mb, &mbdata->busy)) { | ||
152 | write_sync(IVTV_MBOX_DRIVER_BUSY, &mbdata->mbox[mb].flags); | ||
153 | return 1; | ||
154 | } | ||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | /* Try to find a free mailbox. Note mailbox 0 is reserved for DMA and so is not | ||
159 | attempted here. */ | ||
160 | static int get_mailbox(struct ivtv *itv, struct ivtv_mailbox_data *mbdata, int flags) | ||
161 | { | ||
162 | unsigned long then = jiffies; | ||
163 | int i, mb; | ||
164 | int max_mbox = mbdata->max_mbox; | ||
165 | int retries = 100; | ||
166 | |||
167 | /* All slow commands use the same mailbox, serializing them and also | ||
168 | leaving the other mailbox free for simple fast commands. */ | ||
169 | if ((flags & API_FAST_RESULT) == API_RESULT) | ||
170 | max_mbox = 1; | ||
171 | |||
172 | /* find free non-DMA mailbox */ | ||
173 | for (i = 0; i < retries; i++) { | ||
174 | for (mb = 1; mb <= max_mbox; mb++) | ||
175 | if (try_mailbox(itv, mbdata, mb)) | ||
176 | return mb; | ||
177 | |||
178 | /* Sleep before a retry, if not atomic */ | ||
179 | if (!(flags & API_NO_WAIT_MB)) { | ||
180 | if (time_after(jiffies, | ||
181 | then + msecs_to_jiffies(10*retries))) | ||
182 | break; | ||
183 | ivtv_msleep_timeout(10, 0); | ||
184 | } | ||
185 | } | ||
186 | return -ENODEV; | ||
187 | } | ||
188 | |||
189 | static void write_mailbox(volatile struct ivtv_mailbox __iomem *mbox, int cmd, int args, u32 data[]) | ||
190 | { | ||
191 | int i; | ||
192 | |||
193 | write_sync(cmd, &mbox->cmd); | ||
194 | write_sync(IVTV_API_STD_TIMEOUT, &mbox->timeout); | ||
195 | |||
196 | for (i = 0; i < CX2341X_MBOX_MAX_DATA; i++) | ||
197 | write_sync(data[i], &mbox->data[i]); | ||
198 | |||
199 | write_sync(IVTV_MBOX_DRIVER_DONE | IVTV_MBOX_DRIVER_BUSY, &mbox->flags); | ||
200 | } | ||
201 | |||
202 | static void clear_all_mailboxes(struct ivtv *itv, struct ivtv_mailbox_data *mbdata) | ||
203 | { | ||
204 | int i; | ||
205 | |||
206 | for (i = 0; i <= mbdata->max_mbox; i++) { | ||
207 | IVTV_DEBUG_WARN("Clearing mailbox %d: cmd 0x%08x flags 0x%08x\n", | ||
208 | i, readl(&mbdata->mbox[i].cmd), readl(&mbdata->mbox[i].flags)); | ||
209 | write_sync(0, &mbdata->mbox[i].flags); | ||
210 | clear_bit(i, &mbdata->busy); | ||
211 | } | ||
212 | } | ||
213 | |||
214 | static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) | ||
215 | { | ||
216 | struct ivtv_mailbox_data *mbdata = (cmd >= 128) ? &itv->enc_mbox : &itv->dec_mbox; | ||
217 | volatile struct ivtv_mailbox __iomem *mbox; | ||
218 | int api_timeout = msecs_to_jiffies(1000); | ||
219 | int flags, mb, i; | ||
220 | unsigned long then; | ||
221 | |||
222 | /* sanity checks */ | ||
223 | if (NULL == mbdata) { | ||
224 | IVTV_ERR("No mailbox allocated\n"); | ||
225 | return -ENODEV; | ||
226 | } | ||
227 | if (args < 0 || args > CX2341X_MBOX_MAX_DATA || | ||
228 | cmd < 0 || cmd > 255 || api_info[cmd].name == NULL) { | ||
229 | IVTV_ERR("Invalid MB call: cmd = 0x%02x, args = %d\n", cmd, args); | ||
230 | return -EINVAL; | ||
231 | } | ||
232 | |||
233 | if (api_info[cmd].flags & API_HIGH_VOL) { | ||
234 | IVTV_DEBUG_HI_MB("MB Call: %s\n", api_info[cmd].name); | ||
235 | } | ||
236 | else { | ||
237 | IVTV_DEBUG_MB("MB Call: %s\n", api_info[cmd].name); | ||
238 | } | ||
239 | |||
240 | /* clear possibly uninitialized part of data array */ | ||
241 | for (i = args; i < CX2341X_MBOX_MAX_DATA; i++) | ||
242 | data[i] = 0; | ||
243 | |||
244 | /* If this command was issued within the last 30 minutes and with identical | ||
245 | data, then just return 0 as there is no need to issue this command again. | ||
246 | Just an optimization to prevent unnecessary use of mailboxes. */ | ||
247 | if (itv->api_cache[cmd].last_jiffies && | ||
248 | time_before(jiffies, | ||
249 | itv->api_cache[cmd].last_jiffies + | ||
250 | msecs_to_jiffies(1800000)) && | ||
251 | !memcmp(data, itv->api_cache[cmd].data, sizeof(itv->api_cache[cmd].data))) { | ||
252 | itv->api_cache[cmd].last_jiffies = jiffies; | ||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | flags = api_info[cmd].flags; | ||
257 | |||
258 | if (flags & API_DMA) { | ||
259 | for (i = 0; i < 100; i++) { | ||
260 | mb = i % (mbdata->max_mbox + 1); | ||
261 | if (try_mailbox(itv, mbdata, mb)) { | ||
262 | write_mailbox(&mbdata->mbox[mb], cmd, args, data); | ||
263 | clear_bit(mb, &mbdata->busy); | ||
264 | return 0; | ||
265 | } | ||
266 | IVTV_DEBUG_WARN("%s: mailbox %d not free %08x\n", | ||
267 | api_info[cmd].name, mb, readl(&mbdata->mbox[mb].flags)); | ||
268 | } | ||
269 | IVTV_WARN("Could not find free DMA mailbox for %s\n", api_info[cmd].name); | ||
270 | clear_all_mailboxes(itv, mbdata); | ||
271 | return -EBUSY; | ||
272 | } | ||
273 | |||
274 | if ((flags & API_FAST_RESULT) == API_FAST_RESULT) | ||
275 | api_timeout = msecs_to_jiffies(100); | ||
276 | |||
277 | mb = get_mailbox(itv, mbdata, flags); | ||
278 | if (mb < 0) { | ||
279 | IVTV_DEBUG_WARN("No free mailbox found (%s)\n", api_info[cmd].name); | ||
280 | clear_all_mailboxes(itv, mbdata); | ||
281 | return -EBUSY; | ||
282 | } | ||
283 | mbox = &mbdata->mbox[mb]; | ||
284 | write_mailbox(mbox, cmd, args, data); | ||
285 | if (flags & API_CACHE) { | ||
286 | memcpy(itv->api_cache[cmd].data, data, sizeof(itv->api_cache[cmd].data)); | ||
287 | itv->api_cache[cmd].last_jiffies = jiffies; | ||
288 | } | ||
289 | if ((flags & API_RESULT) == 0) { | ||
290 | clear_bit(mb, &mbdata->busy); | ||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | /* Get results */ | ||
295 | then = jiffies; | ||
296 | |||
297 | if (!(flags & API_NO_POLL)) { | ||
298 | /* First try to poll, then switch to delays */ | ||
299 | for (i = 0; i < 100; i++) { | ||
300 | if (readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE) | ||
301 | break; | ||
302 | } | ||
303 | } | ||
304 | while (!(readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE)) { | ||
305 | if (time_after(jiffies, then + api_timeout)) { | ||
306 | IVTV_DEBUG_WARN("Could not get result (%s)\n", api_info[cmd].name); | ||
307 | /* reset the mailbox, but it is likely too late already */ | ||
308 | write_sync(0, &mbox->flags); | ||
309 | clear_bit(mb, &mbdata->busy); | ||
310 | return -EIO; | ||
311 | } | ||
312 | if (flags & API_NO_WAIT_RES) | ||
313 | mdelay(1); | ||
314 | else | ||
315 | ivtv_msleep_timeout(1, 0); | ||
316 | } | ||
317 | if (time_after(jiffies, then + msecs_to_jiffies(100))) | ||
318 | IVTV_DEBUG_WARN("%s took %u jiffies\n", | ||
319 | api_info[cmd].name, | ||
320 | jiffies_to_msecs(jiffies - then)); | ||
321 | |||
322 | for (i = 0; i < CX2341X_MBOX_MAX_DATA; i++) | ||
323 | data[i] = readl(&mbox->data[i]); | ||
324 | write_sync(0, &mbox->flags); | ||
325 | clear_bit(mb, &mbdata->busy); | ||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[]) | ||
330 | { | ||
331 | int res = ivtv_api_call(itv, cmd, args, data); | ||
332 | |||
333 | /* Allow a single retry, probably already too late though. | ||
334 | If there is no free mailbox then that is usually an indication | ||
335 | of a more serious problem. */ | ||
336 | return (res == -EBUSY) ? ivtv_api_call(itv, cmd, args, data) : res; | ||
337 | } | ||
338 | |||
339 | int ivtv_api_func(void *priv, u32 cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]) | ||
340 | { | ||
341 | return ivtv_api(priv, cmd, in, data); | ||
342 | } | ||
343 | |||
344 | int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...) | ||
345 | { | ||
346 | va_list ap; | ||
347 | int i; | ||
348 | |||
349 | va_start(ap, args); | ||
350 | for (i = 0; i < args; i++) { | ||
351 | data[i] = va_arg(ap, u32); | ||
352 | } | ||
353 | va_end(ap); | ||
354 | return ivtv_api(itv, cmd, args, data); | ||
355 | } | ||
356 | |||
357 | int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...) | ||
358 | { | ||
359 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
360 | va_list ap; | ||
361 | int i; | ||
362 | |||
363 | va_start(ap, args); | ||
364 | for (i = 0; i < args; i++) { | ||
365 | data[i] = va_arg(ap, u32); | ||
366 | } | ||
367 | va_end(ap); | ||
368 | return ivtv_api(itv, cmd, args, data); | ||
369 | } | ||
370 | |||
371 | /* This one is for stuff that can't sleep.. irq handlers, etc.. */ | ||
372 | void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb, | ||
373 | int argc, u32 data[]) | ||
374 | { | ||
375 | volatile u32 __iomem *p = mbdata->mbox[mb].data; | ||
376 | int i; | ||
377 | for (i = 0; i < argc; i++, p++) | ||
378 | data[i] = readl(p); | ||
379 | } | ||
380 | |||
381 | /* Wipe api cache */ | ||
382 | void ivtv_mailbox_cache_invalidate(struct ivtv *itv) | ||
383 | { | ||
384 | int i; | ||
385 | for (i = 0; i < 256; i++) | ||
386 | itv->api_cache[i].last_jiffies = 0; | ||
387 | } | ||
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.h b/drivers/media/video/ivtv/ivtv-mailbox.h new file mode 100644 index 00000000000..2c834d2cb56 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-mailbox.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | mailbox functions | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #ifndef IVTV_MAILBOX_H | ||
22 | #define IVTV_MAILBOX_H | ||
23 | |||
24 | #define IVTV_MBOX_DMA_END 8 | ||
25 | #define IVTV_MBOX_DMA 9 | ||
26 | |||
27 | void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb, | ||
28 | int argc, u32 data[]); | ||
29 | int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[]); | ||
30 | int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...); | ||
31 | int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...); | ||
32 | int ivtv_api_func(void *priv, u32 cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]); | ||
33 | void ivtv_mailbox_cache_invalidate(struct ivtv *itv); | ||
34 | |||
35 | #endif | ||
diff --git a/drivers/media/video/ivtv/ivtv-queue.c b/drivers/media/video/ivtv/ivtv-queue.c new file mode 100644 index 00000000000..7fde36e6d22 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-queue.c | |||
@@ -0,0 +1,297 @@ | |||
1 | /* | ||
2 | buffer queues. | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2004 Chris Kennedy <c@groovy.org> | ||
5 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include "ivtv-driver.h" | ||
23 | #include "ivtv-queue.h" | ||
24 | |||
25 | int ivtv_buf_copy_from_user(struct ivtv_stream *s, struct ivtv_buffer *buf, const char __user *src, int copybytes) | ||
26 | { | ||
27 | if (s->buf_size - buf->bytesused < copybytes) | ||
28 | copybytes = s->buf_size - buf->bytesused; | ||
29 | if (copy_from_user(buf->buf + buf->bytesused, src, copybytes)) { | ||
30 | return -EFAULT; | ||
31 | } | ||
32 | buf->bytesused += copybytes; | ||
33 | return copybytes; | ||
34 | } | ||
35 | |||
36 | void ivtv_buf_swap(struct ivtv_buffer *buf) | ||
37 | { | ||
38 | int i; | ||
39 | |||
40 | for (i = 0; i < buf->bytesused; i += 4) | ||
41 | swab32s((u32 *)(buf->buf + i)); | ||
42 | } | ||
43 | |||
44 | void ivtv_queue_init(struct ivtv_queue *q) | ||
45 | { | ||
46 | INIT_LIST_HEAD(&q->list); | ||
47 | q->buffers = 0; | ||
48 | q->length = 0; | ||
49 | q->bytesused = 0; | ||
50 | } | ||
51 | |||
52 | void ivtv_enqueue(struct ivtv_stream *s, struct ivtv_buffer *buf, struct ivtv_queue *q) | ||
53 | { | ||
54 | unsigned long flags; | ||
55 | |||
56 | /* clear the buffer if it is going to be enqueued to the free queue */ | ||
57 | if (q == &s->q_free) { | ||
58 | buf->bytesused = 0; | ||
59 | buf->readpos = 0; | ||
60 | buf->b_flags = 0; | ||
61 | buf->dma_xfer_cnt = 0; | ||
62 | } | ||
63 | spin_lock_irqsave(&s->qlock, flags); | ||
64 | list_add_tail(&buf->list, &q->list); | ||
65 | q->buffers++; | ||
66 | q->length += s->buf_size; | ||
67 | q->bytesused += buf->bytesused - buf->readpos; | ||
68 | spin_unlock_irqrestore(&s->qlock, flags); | ||
69 | } | ||
70 | |||
71 | struct ivtv_buffer *ivtv_dequeue(struct ivtv_stream *s, struct ivtv_queue *q) | ||
72 | { | ||
73 | struct ivtv_buffer *buf = NULL; | ||
74 | unsigned long flags; | ||
75 | |||
76 | spin_lock_irqsave(&s->qlock, flags); | ||
77 | if (!list_empty(&q->list)) { | ||
78 | buf = list_entry(q->list.next, struct ivtv_buffer, list); | ||
79 | list_del_init(q->list.next); | ||
80 | q->buffers--; | ||
81 | q->length -= s->buf_size; | ||
82 | q->bytesused -= buf->bytesused - buf->readpos; | ||
83 | } | ||
84 | spin_unlock_irqrestore(&s->qlock, flags); | ||
85 | return buf; | ||
86 | } | ||
87 | |||
88 | static void ivtv_queue_move_buf(struct ivtv_stream *s, struct ivtv_queue *from, | ||
89 | struct ivtv_queue *to, int clear) | ||
90 | { | ||
91 | struct ivtv_buffer *buf = list_entry(from->list.next, struct ivtv_buffer, list); | ||
92 | |||
93 | list_move_tail(from->list.next, &to->list); | ||
94 | from->buffers--; | ||
95 | from->length -= s->buf_size; | ||
96 | from->bytesused -= buf->bytesused - buf->readpos; | ||
97 | /* special handling for q_free */ | ||
98 | if (clear) | ||
99 | buf->bytesused = buf->readpos = buf->b_flags = buf->dma_xfer_cnt = 0; | ||
100 | to->buffers++; | ||
101 | to->length += s->buf_size; | ||
102 | to->bytesused += buf->bytesused - buf->readpos; | ||
103 | } | ||
104 | |||
105 | /* Move 'needed_bytes' worth of buffers from queue 'from' into queue 'to'. | ||
106 | If 'needed_bytes' == 0, then move all buffers from 'from' into 'to'. | ||
107 | If 'steal' != NULL, then buffers may also taken from that queue if | ||
108 | needed, but only if 'from' is the free queue. | ||
109 | |||
110 | The buffer is automatically cleared if it goes to the free queue. It is | ||
111 | also cleared if buffers need to be taken from the 'steal' queue and | ||
112 | the 'from' queue is the free queue. | ||
113 | |||
114 | When 'from' is q_free, then needed_bytes is compared to the total | ||
115 | available buffer length, otherwise needed_bytes is compared to the | ||
116 | bytesused value. For the 'steal' queue the total available buffer | ||
117 | length is always used. | ||
118 | |||
119 | -ENOMEM is returned if the buffers could not be obtained, 0 if all | ||
120 | buffers where obtained from the 'from' list and if non-zero then | ||
121 | the number of stolen buffers is returned. */ | ||
122 | int ivtv_queue_move(struct ivtv_stream *s, struct ivtv_queue *from, struct ivtv_queue *steal, | ||
123 | struct ivtv_queue *to, int needed_bytes) | ||
124 | { | ||
125 | unsigned long flags; | ||
126 | int rc = 0; | ||
127 | int from_free = from == &s->q_free; | ||
128 | int to_free = to == &s->q_free; | ||
129 | int bytes_available, bytes_steal; | ||
130 | |||
131 | spin_lock_irqsave(&s->qlock, flags); | ||
132 | if (needed_bytes == 0) { | ||
133 | from_free = 1; | ||
134 | needed_bytes = from->length; | ||
135 | } | ||
136 | |||
137 | bytes_available = from_free ? from->length : from->bytesused; | ||
138 | bytes_steal = (from_free && steal) ? steal->length : 0; | ||
139 | |||
140 | if (bytes_available + bytes_steal < needed_bytes) { | ||
141 | spin_unlock_irqrestore(&s->qlock, flags); | ||
142 | return -ENOMEM; | ||
143 | } | ||
144 | while (bytes_available < needed_bytes) { | ||
145 | struct ivtv_buffer *buf = list_entry(steal->list.prev, struct ivtv_buffer, list); | ||
146 | u16 dma_xfer_cnt = buf->dma_xfer_cnt; | ||
147 | |||
148 | /* move buffers from the tail of the 'steal' queue to the tail of the | ||
149 | 'from' queue. Always copy all the buffers with the same dma_xfer_cnt | ||
150 | value, this ensures that you do not end up with partial frame data | ||
151 | if one frame is stored in multiple buffers. */ | ||
152 | while (dma_xfer_cnt == buf->dma_xfer_cnt) { | ||
153 | list_move_tail(steal->list.prev, &from->list); | ||
154 | rc++; | ||
155 | steal->buffers--; | ||
156 | steal->length -= s->buf_size; | ||
157 | steal->bytesused -= buf->bytesused - buf->readpos; | ||
158 | buf->bytesused = buf->readpos = buf->b_flags = buf->dma_xfer_cnt = 0; | ||
159 | from->buffers++; | ||
160 | from->length += s->buf_size; | ||
161 | bytes_available += s->buf_size; | ||
162 | if (list_empty(&steal->list)) | ||
163 | break; | ||
164 | buf = list_entry(steal->list.prev, struct ivtv_buffer, list); | ||
165 | } | ||
166 | } | ||
167 | if (from_free) { | ||
168 | u32 old_length = to->length; | ||
169 | |||
170 | while (to->length - old_length < needed_bytes) { | ||
171 | ivtv_queue_move_buf(s, from, to, 1); | ||
172 | } | ||
173 | } | ||
174 | else { | ||
175 | u32 old_bytesused = to->bytesused; | ||
176 | |||
177 | while (to->bytesused - old_bytesused < needed_bytes) { | ||
178 | ivtv_queue_move_buf(s, from, to, to_free); | ||
179 | } | ||
180 | } | ||
181 | spin_unlock_irqrestore(&s->qlock, flags); | ||
182 | return rc; | ||
183 | } | ||
184 | |||
185 | void ivtv_flush_queues(struct ivtv_stream *s) | ||
186 | { | ||
187 | ivtv_queue_move(s, &s->q_io, NULL, &s->q_free, 0); | ||
188 | ivtv_queue_move(s, &s->q_full, NULL, &s->q_free, 0); | ||
189 | ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0); | ||
190 | ivtv_queue_move(s, &s->q_predma, NULL, &s->q_free, 0); | ||
191 | } | ||
192 | |||
193 | int ivtv_stream_alloc(struct ivtv_stream *s) | ||
194 | { | ||
195 | struct ivtv *itv = s->itv; | ||
196 | int SGsize = sizeof(struct ivtv_sg_host_element) * s->buffers; | ||
197 | int i; | ||
198 | |||
199 | if (s->buffers == 0) | ||
200 | return 0; | ||
201 | |||
202 | IVTV_DEBUG_INFO("Allocate %s%s stream: %d x %d buffers (%dkB total)\n", | ||
203 | s->dma != PCI_DMA_NONE ? "DMA " : "", | ||
204 | s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024); | ||
205 | |||
206 | s->sg_pending = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN); | ||
207 | if (s->sg_pending == NULL) { | ||
208 | IVTV_ERR("Could not allocate sg_pending for %s stream\n", s->name); | ||
209 | return -ENOMEM; | ||
210 | } | ||
211 | s->sg_pending_size = 0; | ||
212 | |||
213 | s->sg_processing = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN); | ||
214 | if (s->sg_processing == NULL) { | ||
215 | IVTV_ERR("Could not allocate sg_processing for %s stream\n", s->name); | ||
216 | kfree(s->sg_pending); | ||
217 | s->sg_pending = NULL; | ||
218 | return -ENOMEM; | ||
219 | } | ||
220 | s->sg_processing_size = 0; | ||
221 | |||
222 | s->sg_dma = kzalloc(sizeof(struct ivtv_sg_element), | ||
223 | GFP_KERNEL|__GFP_NOWARN); | ||
224 | if (s->sg_dma == NULL) { | ||
225 | IVTV_ERR("Could not allocate sg_dma for %s stream\n", s->name); | ||
226 | kfree(s->sg_pending); | ||
227 | s->sg_pending = NULL; | ||
228 | kfree(s->sg_processing); | ||
229 | s->sg_processing = NULL; | ||
230 | return -ENOMEM; | ||
231 | } | ||
232 | if (ivtv_might_use_dma(s)) { | ||
233 | s->sg_handle = pci_map_single(itv->pdev, s->sg_dma, | ||
234 | sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE); | ||
235 | ivtv_stream_sync_for_cpu(s); | ||
236 | } | ||
237 | |||
238 | /* allocate stream buffers. Initially all buffers are in q_free. */ | ||
239 | for (i = 0; i < s->buffers; i++) { | ||
240 | struct ivtv_buffer *buf = kzalloc(sizeof(struct ivtv_buffer), | ||
241 | GFP_KERNEL|__GFP_NOWARN); | ||
242 | |||
243 | if (buf == NULL) | ||
244 | break; | ||
245 | buf->buf = kmalloc(s->buf_size + 256, GFP_KERNEL|__GFP_NOWARN); | ||
246 | if (buf->buf == NULL) { | ||
247 | kfree(buf); | ||
248 | break; | ||
249 | } | ||
250 | INIT_LIST_HEAD(&buf->list); | ||
251 | if (ivtv_might_use_dma(s)) { | ||
252 | buf->dma_handle = pci_map_single(s->itv->pdev, | ||
253 | buf->buf, s->buf_size + 256, s->dma); | ||
254 | ivtv_buf_sync_for_cpu(s, buf); | ||
255 | } | ||
256 | ivtv_enqueue(s, buf, &s->q_free); | ||
257 | } | ||
258 | if (i == s->buffers) | ||
259 | return 0; | ||
260 | IVTV_ERR("Couldn't allocate buffers for %s stream\n", s->name); | ||
261 | ivtv_stream_free(s); | ||
262 | return -ENOMEM; | ||
263 | } | ||
264 | |||
265 | void ivtv_stream_free(struct ivtv_stream *s) | ||
266 | { | ||
267 | struct ivtv_buffer *buf; | ||
268 | |||
269 | /* move all buffers to q_free */ | ||
270 | ivtv_flush_queues(s); | ||
271 | |||
272 | /* empty q_free */ | ||
273 | while ((buf = ivtv_dequeue(s, &s->q_free))) { | ||
274 | if (ivtv_might_use_dma(s)) | ||
275 | pci_unmap_single(s->itv->pdev, buf->dma_handle, | ||
276 | s->buf_size + 256, s->dma); | ||
277 | kfree(buf->buf); | ||
278 | kfree(buf); | ||
279 | } | ||
280 | |||
281 | /* Free SG Array/Lists */ | ||
282 | if (s->sg_dma != NULL) { | ||
283 | if (s->sg_handle != IVTV_DMA_UNMAPPED) { | ||
284 | pci_unmap_single(s->itv->pdev, s->sg_handle, | ||
285 | sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE); | ||
286 | s->sg_handle = IVTV_DMA_UNMAPPED; | ||
287 | } | ||
288 | kfree(s->sg_pending); | ||
289 | kfree(s->sg_processing); | ||
290 | kfree(s->sg_dma); | ||
291 | s->sg_pending = NULL; | ||
292 | s->sg_processing = NULL; | ||
293 | s->sg_dma = NULL; | ||
294 | s->sg_pending_size = 0; | ||
295 | s->sg_processing_size = 0; | ||
296 | } | ||
297 | } | ||
diff --git a/drivers/media/video/ivtv/ivtv-queue.h b/drivers/media/video/ivtv/ivtv-queue.h new file mode 100644 index 00000000000..91233839a26 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-queue.h | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | buffer queues. | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2004 Chris Kennedy <c@groovy.org> | ||
5 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #ifndef IVTV_QUEUE_H | ||
23 | #define IVTV_QUEUE_H | ||
24 | |||
25 | #define IVTV_DMA_UNMAPPED ((u32) -1) | ||
26 | #define SLICED_VBI_PIO 0 | ||
27 | |||
28 | /* ivtv_buffer utility functions */ | ||
29 | |||
30 | static inline int ivtv_might_use_pio(struct ivtv_stream *s) | ||
31 | { | ||
32 | return s->dma == PCI_DMA_NONE || (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI); | ||
33 | } | ||
34 | |||
35 | static inline int ivtv_use_pio(struct ivtv_stream *s) | ||
36 | { | ||
37 | struct ivtv *itv = s->itv; | ||
38 | |||
39 | return s->dma == PCI_DMA_NONE || | ||
40 | (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set); | ||
41 | } | ||
42 | |||
43 | static inline int ivtv_might_use_dma(struct ivtv_stream *s) | ||
44 | { | ||
45 | return s->dma != PCI_DMA_NONE; | ||
46 | } | ||
47 | |||
48 | static inline int ivtv_use_dma(struct ivtv_stream *s) | ||
49 | { | ||
50 | return !ivtv_use_pio(s); | ||
51 | } | ||
52 | |||
53 | static inline void ivtv_buf_sync_for_cpu(struct ivtv_stream *s, struct ivtv_buffer *buf) | ||
54 | { | ||
55 | if (ivtv_use_dma(s)) | ||
56 | pci_dma_sync_single_for_cpu(s->itv->pdev, buf->dma_handle, | ||
57 | s->buf_size + 256, s->dma); | ||
58 | } | ||
59 | |||
60 | static inline void ivtv_buf_sync_for_device(struct ivtv_stream *s, struct ivtv_buffer *buf) | ||
61 | { | ||
62 | if (ivtv_use_dma(s)) | ||
63 | pci_dma_sync_single_for_device(s->itv->pdev, buf->dma_handle, | ||
64 | s->buf_size + 256, s->dma); | ||
65 | } | ||
66 | |||
67 | int ivtv_buf_copy_from_user(struct ivtv_stream *s, struct ivtv_buffer *buf, const char __user *src, int copybytes); | ||
68 | void ivtv_buf_swap(struct ivtv_buffer *buf); | ||
69 | |||
70 | /* ivtv_queue utility functions */ | ||
71 | void ivtv_queue_init(struct ivtv_queue *q); | ||
72 | void ivtv_enqueue(struct ivtv_stream *s, struct ivtv_buffer *buf, struct ivtv_queue *q); | ||
73 | struct ivtv_buffer *ivtv_dequeue(struct ivtv_stream *s, struct ivtv_queue *q); | ||
74 | int ivtv_queue_move(struct ivtv_stream *s, struct ivtv_queue *from, struct ivtv_queue *steal, | ||
75 | struct ivtv_queue *to, int needed_bytes); | ||
76 | void ivtv_flush_queues(struct ivtv_stream *s); | ||
77 | |||
78 | /* ivtv_stream utility functions */ | ||
79 | int ivtv_stream_alloc(struct ivtv_stream *s); | ||
80 | void ivtv_stream_free(struct ivtv_stream *s); | ||
81 | |||
82 | static inline void ivtv_stream_sync_for_cpu(struct ivtv_stream *s) | ||
83 | { | ||
84 | if (ivtv_use_dma(s)) | ||
85 | pci_dma_sync_single_for_cpu(s->itv->pdev, s->sg_handle, | ||
86 | sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE); | ||
87 | } | ||
88 | |||
89 | static inline void ivtv_stream_sync_for_device(struct ivtv_stream *s) | ||
90 | { | ||
91 | if (ivtv_use_dma(s)) | ||
92 | pci_dma_sync_single_for_device(s->itv->pdev, s->sg_handle, | ||
93 | sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE); | ||
94 | } | ||
95 | |||
96 | #endif | ||
diff --git a/drivers/media/video/ivtv/ivtv-routing.c b/drivers/media/video/ivtv/ivtv-routing.c new file mode 100644 index 00000000000..8898c569a1c --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-routing.c | |||
@@ -0,0 +1,119 @@ | |||
1 | /* | ||
2 | Audio/video-routing-related ivtv functions. | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include "ivtv-driver.h" | ||
22 | #include "ivtv-i2c.h" | ||
23 | #include "ivtv-cards.h" | ||
24 | #include "ivtv-gpio.h" | ||
25 | #include "ivtv-routing.h" | ||
26 | |||
27 | #include <media/msp3400.h> | ||
28 | #include <media/m52790.h> | ||
29 | #include <media/upd64031a.h> | ||
30 | #include <media/upd64083.h> | ||
31 | |||
32 | /* Selects the audio input and output according to the current | ||
33 | settings. */ | ||
34 | void ivtv_audio_set_io(struct ivtv *itv) | ||
35 | { | ||
36 | const struct ivtv_card_audio_input *in; | ||
37 | u32 input, output = 0; | ||
38 | |||
39 | /* Determine which input to use */ | ||
40 | if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) | ||
41 | in = &itv->card->radio_input; | ||
42 | else | ||
43 | in = &itv->card->audio_inputs[itv->audio_input]; | ||
44 | |||
45 | /* handle muxer chips */ | ||
46 | input = in->muxer_input; | ||
47 | if (itv->card->hw_muxer & IVTV_HW_M52790) | ||
48 | output = M52790_OUT_STEREO; | ||
49 | v4l2_subdev_call(itv->sd_muxer, audio, s_routing, | ||
50 | input, output, 0); | ||
51 | |||
52 | input = in->audio_input; | ||
53 | output = 0; | ||
54 | if (itv->card->hw_audio & IVTV_HW_MSP34XX) | ||
55 | output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1); | ||
56 | ivtv_call_hw(itv, itv->card->hw_audio, audio, s_routing, | ||
57 | input, output, 0); | ||
58 | } | ||
59 | |||
60 | /* Selects the video input and output according to the current | ||
61 | settings. */ | ||
62 | void ivtv_video_set_io(struct ivtv *itv) | ||
63 | { | ||
64 | int inp = itv->active_input; | ||
65 | u32 input; | ||
66 | u32 type; | ||
67 | |||
68 | v4l2_subdev_call(itv->sd_video, video, s_routing, | ||
69 | itv->card->video_inputs[inp].video_input, 0, 0); | ||
70 | |||
71 | type = itv->card->video_inputs[inp].video_type; | ||
72 | |||
73 | if (type == IVTV_CARD_INPUT_VID_TUNER) { | ||
74 | input = 0; /* Tuner */ | ||
75 | } else if (type < IVTV_CARD_INPUT_COMPOSITE1) { | ||
76 | input = 2; /* S-Video */ | ||
77 | } else { | ||
78 | input = 1; /* Composite */ | ||
79 | } | ||
80 | |||
81 | if (itv->card->hw_video & IVTV_HW_GPIO) | ||
82 | ivtv_call_hw(itv, IVTV_HW_GPIO, video, s_routing, | ||
83 | input, 0, 0); | ||
84 | |||
85 | if (itv->card->hw_video & IVTV_HW_UPD64031A) { | ||
86 | if (type == IVTV_CARD_INPUT_VID_TUNER || | ||
87 | type >= IVTV_CARD_INPUT_COMPOSITE1) { | ||
88 | /* Composite: GR on, connect to 3DYCS */ | ||
89 | input = UPD64031A_GR_ON | UPD64031A_3DYCS_COMPOSITE; | ||
90 | } else { | ||
91 | /* S-Video: GR bypassed, turn it off */ | ||
92 | input = UPD64031A_GR_OFF | UPD64031A_3DYCS_DISABLE; | ||
93 | } | ||
94 | input |= itv->card->gr_config; | ||
95 | |||
96 | ivtv_call_hw(itv, IVTV_HW_UPD64031A, video, s_routing, | ||
97 | input, 0, 0); | ||
98 | } | ||
99 | |||
100 | if (itv->card->hw_video & IVTV_HW_UPD6408X) { | ||
101 | input = UPD64083_YCS_MODE; | ||
102 | if (type > IVTV_CARD_INPUT_VID_TUNER && | ||
103 | type < IVTV_CARD_INPUT_COMPOSITE1) { | ||
104 | /* S-Video uses YCNR mode and internal Y-ADC, the | ||
105 | upd64031a is not used. */ | ||
106 | input |= UPD64083_YCNR_MODE; | ||
107 | } | ||
108 | else if (itv->card->hw_video & IVTV_HW_UPD64031A) { | ||
109 | /* Use upd64031a output for tuner and | ||
110 | composite(CX23416GYC only) inputs */ | ||
111 | if (type == IVTV_CARD_INPUT_VID_TUNER || | ||
112 | itv->card->type == IVTV_CARD_CX23416GYC) { | ||
113 | input |= UPD64083_EXT_Y_ADC; | ||
114 | } | ||
115 | } | ||
116 | ivtv_call_hw(itv, IVTV_HW_UPD6408X, video, s_routing, | ||
117 | input, 0, 0); | ||
118 | } | ||
119 | } | ||
diff --git a/drivers/media/video/ivtv/ivtv-routing.h b/drivers/media/video/ivtv/ivtv-routing.h new file mode 100644 index 00000000000..c72a9731ca0 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-routing.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | Audio/video-routing-related ivtv functions. | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #ifndef IVTV_ROUTING_H | ||
22 | #define IVTV_ROUTING_H | ||
23 | |||
24 | void ivtv_audio_set_io(struct ivtv *itv); | ||
25 | void ivtv_video_set_io(struct ivtv *itv); | ||
26 | |||
27 | #endif | ||
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c new file mode 100644 index 00000000000..e7794dc1330 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-streams.c | |||
@@ -0,0 +1,1000 @@ | |||
1 | /* | ||
2 | init/start/stop/exit stream functions | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2004 Chris Kennedy <c@groovy.org> | ||
5 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | /* License: GPL | ||
23 | * Author: Kevin Thayer <nufan_wfk at yahoo dot com> | ||
24 | * | ||
25 | * This file will hold API related functions, both internal (firmware api) | ||
26 | * and external (v4l2, etc) | ||
27 | * | ||
28 | * ----- | ||
29 | * MPG600/MPG160 support by T.Adachi <tadachi@tadachi-net.com> | ||
30 | * and Takeru KOMORIYA<komoriya@paken.org> | ||
31 | * | ||
32 | * AVerMedia M179 GPIO info by Chris Pinkham <cpinkham@bc2va.org> | ||
33 | * using information provided by Jiun-Kuei Jung @ AVerMedia. | ||
34 | */ | ||
35 | |||
36 | #include "ivtv-driver.h" | ||
37 | #include "ivtv-fileops.h" | ||
38 | #include "ivtv-queue.h" | ||
39 | #include "ivtv-mailbox.h" | ||
40 | #include "ivtv-ioctl.h" | ||
41 | #include "ivtv-irq.h" | ||
42 | #include "ivtv-yuv.h" | ||
43 | #include "ivtv-cards.h" | ||
44 | #include "ivtv-streams.h" | ||
45 | #include "ivtv-firmware.h" | ||
46 | #include <media/v4l2-event.h> | ||
47 | |||
48 | static const struct v4l2_file_operations ivtv_v4l2_enc_fops = { | ||
49 | .owner = THIS_MODULE, | ||
50 | .read = ivtv_v4l2_read, | ||
51 | .write = ivtv_v4l2_write, | ||
52 | .open = ivtv_v4l2_open, | ||
53 | .unlocked_ioctl = ivtv_v4l2_ioctl, | ||
54 | .release = ivtv_v4l2_close, | ||
55 | .poll = ivtv_v4l2_enc_poll, | ||
56 | }; | ||
57 | |||
58 | static const struct v4l2_file_operations ivtv_v4l2_dec_fops = { | ||
59 | .owner = THIS_MODULE, | ||
60 | .read = ivtv_v4l2_read, | ||
61 | .write = ivtv_v4l2_write, | ||
62 | .open = ivtv_v4l2_open, | ||
63 | .unlocked_ioctl = ivtv_v4l2_ioctl, | ||
64 | .release = ivtv_v4l2_close, | ||
65 | .poll = ivtv_v4l2_dec_poll, | ||
66 | }; | ||
67 | |||
68 | #define IVTV_V4L2_DEC_MPG_OFFSET 16 /* offset from 0 to register decoder mpg v4l2 minors on */ | ||
69 | #define IVTV_V4L2_ENC_PCM_OFFSET 24 /* offset from 0 to register pcm v4l2 minors on */ | ||
70 | #define IVTV_V4L2_ENC_YUV_OFFSET 32 /* offset from 0 to register yuv v4l2 minors on */ | ||
71 | #define IVTV_V4L2_DEC_YUV_OFFSET 48 /* offset from 0 to register decoder yuv v4l2 minors on */ | ||
72 | #define IVTV_V4L2_DEC_VBI_OFFSET 8 /* offset from 0 to register decoder vbi input v4l2 minors on */ | ||
73 | #define IVTV_V4L2_DEC_VOUT_OFFSET 16 /* offset from 0 to register vbi output v4l2 minors on */ | ||
74 | |||
75 | static struct { | ||
76 | const char *name; | ||
77 | int vfl_type; | ||
78 | int num_offset; | ||
79 | int dma, pio; | ||
80 | enum v4l2_buf_type buf_type; | ||
81 | const struct v4l2_file_operations *fops; | ||
82 | } ivtv_stream_info[] = { | ||
83 | { /* IVTV_ENC_STREAM_TYPE_MPG */ | ||
84 | "encoder MPG", | ||
85 | VFL_TYPE_GRABBER, 0, | ||
86 | PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, | ||
87 | &ivtv_v4l2_enc_fops | ||
88 | }, | ||
89 | { /* IVTV_ENC_STREAM_TYPE_YUV */ | ||
90 | "encoder YUV", | ||
91 | VFL_TYPE_GRABBER, IVTV_V4L2_ENC_YUV_OFFSET, | ||
92 | PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, | ||
93 | &ivtv_v4l2_enc_fops | ||
94 | }, | ||
95 | { /* IVTV_ENC_STREAM_TYPE_VBI */ | ||
96 | "encoder VBI", | ||
97 | VFL_TYPE_VBI, 0, | ||
98 | PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VBI_CAPTURE, | ||
99 | &ivtv_v4l2_enc_fops | ||
100 | }, | ||
101 | { /* IVTV_ENC_STREAM_TYPE_PCM */ | ||
102 | "encoder PCM", | ||
103 | VFL_TYPE_GRABBER, IVTV_V4L2_ENC_PCM_OFFSET, | ||
104 | PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_PRIVATE, | ||
105 | &ivtv_v4l2_enc_fops | ||
106 | }, | ||
107 | { /* IVTV_ENC_STREAM_TYPE_RAD */ | ||
108 | "encoder radio", | ||
109 | VFL_TYPE_RADIO, 0, | ||
110 | PCI_DMA_NONE, 1, V4L2_BUF_TYPE_PRIVATE, | ||
111 | &ivtv_v4l2_enc_fops | ||
112 | }, | ||
113 | { /* IVTV_DEC_STREAM_TYPE_MPG */ | ||
114 | "decoder MPG", | ||
115 | VFL_TYPE_GRABBER, IVTV_V4L2_DEC_MPG_OFFSET, | ||
116 | PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT, | ||
117 | &ivtv_v4l2_dec_fops | ||
118 | }, | ||
119 | { /* IVTV_DEC_STREAM_TYPE_VBI */ | ||
120 | "decoder VBI", | ||
121 | VFL_TYPE_VBI, IVTV_V4L2_DEC_VBI_OFFSET, | ||
122 | PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_CAPTURE, | ||
123 | &ivtv_v4l2_enc_fops | ||
124 | }, | ||
125 | { /* IVTV_DEC_STREAM_TYPE_VOUT */ | ||
126 | "decoder VOUT", | ||
127 | VFL_TYPE_VBI, IVTV_V4L2_DEC_VOUT_OFFSET, | ||
128 | PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_OUTPUT, | ||
129 | &ivtv_v4l2_dec_fops | ||
130 | }, | ||
131 | { /* IVTV_DEC_STREAM_TYPE_YUV */ | ||
132 | "decoder YUV", | ||
133 | VFL_TYPE_GRABBER, IVTV_V4L2_DEC_YUV_OFFSET, | ||
134 | PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT, | ||
135 | &ivtv_v4l2_dec_fops | ||
136 | } | ||
137 | }; | ||
138 | |||
139 | static void ivtv_stream_init(struct ivtv *itv, int type) | ||
140 | { | ||
141 | struct ivtv_stream *s = &itv->streams[type]; | ||
142 | struct video_device *vdev = s->vdev; | ||
143 | |||
144 | /* we need to keep vdev, so restore it afterwards */ | ||
145 | memset(s, 0, sizeof(*s)); | ||
146 | s->vdev = vdev; | ||
147 | |||
148 | /* initialize ivtv_stream fields */ | ||
149 | s->itv = itv; | ||
150 | s->type = type; | ||
151 | s->name = ivtv_stream_info[type].name; | ||
152 | |||
153 | if (ivtv_stream_info[type].pio) | ||
154 | s->dma = PCI_DMA_NONE; | ||
155 | else | ||
156 | s->dma = ivtv_stream_info[type].dma; | ||
157 | s->buf_size = itv->stream_buf_size[type]; | ||
158 | if (s->buf_size) | ||
159 | s->buffers = (itv->options.kilobytes[type] * 1024 + s->buf_size - 1) / s->buf_size; | ||
160 | spin_lock_init(&s->qlock); | ||
161 | init_waitqueue_head(&s->waitq); | ||
162 | s->id = -1; | ||
163 | s->sg_handle = IVTV_DMA_UNMAPPED; | ||
164 | ivtv_queue_init(&s->q_free); | ||
165 | ivtv_queue_init(&s->q_full); | ||
166 | ivtv_queue_init(&s->q_dma); | ||
167 | ivtv_queue_init(&s->q_predma); | ||
168 | ivtv_queue_init(&s->q_io); | ||
169 | } | ||
170 | |||
171 | static int ivtv_prep_dev(struct ivtv *itv, int type) | ||
172 | { | ||
173 | struct ivtv_stream *s = &itv->streams[type]; | ||
174 | int num_offset = ivtv_stream_info[type].num_offset; | ||
175 | int num = itv->instance + ivtv_first_minor + num_offset; | ||
176 | |||
177 | /* These four fields are always initialized. If vdev == NULL, then | ||
178 | this stream is not in use. In that case no other fields but these | ||
179 | four can be used. */ | ||
180 | s->vdev = NULL; | ||
181 | s->itv = itv; | ||
182 | s->type = type; | ||
183 | s->name = ivtv_stream_info[type].name; | ||
184 | |||
185 | /* Check whether the radio is supported */ | ||
186 | if (type == IVTV_ENC_STREAM_TYPE_RAD && !(itv->v4l2_cap & V4L2_CAP_RADIO)) | ||
187 | return 0; | ||
188 | if (type >= IVTV_DEC_STREAM_TYPE_MPG && !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
189 | return 0; | ||
190 | |||
191 | /* User explicitly selected 0 buffers for these streams, so don't | ||
192 | create them. */ | ||
193 | if (ivtv_stream_info[type].dma != PCI_DMA_NONE && | ||
194 | itv->options.kilobytes[type] == 0) { | ||
195 | IVTV_INFO("Disabled %s device\n", ivtv_stream_info[type].name); | ||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | ivtv_stream_init(itv, type); | ||
200 | |||
201 | /* allocate and initialize the v4l2 video device structure */ | ||
202 | s->vdev = video_device_alloc(); | ||
203 | if (s->vdev == NULL) { | ||
204 | IVTV_ERR("Couldn't allocate v4l2 video_device for %s\n", s->name); | ||
205 | return -ENOMEM; | ||
206 | } | ||
207 | |||
208 | snprintf(s->vdev->name, sizeof(s->vdev->name), "%s %s", | ||
209 | itv->v4l2_dev.name, s->name); | ||
210 | |||
211 | s->vdev->num = num; | ||
212 | s->vdev->v4l2_dev = &itv->v4l2_dev; | ||
213 | s->vdev->ctrl_handler = itv->v4l2_dev.ctrl_handler; | ||
214 | s->vdev->fops = ivtv_stream_info[type].fops; | ||
215 | s->vdev->release = video_device_release; | ||
216 | s->vdev->tvnorms = V4L2_STD_ALL; | ||
217 | set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags); | ||
218 | ivtv_set_funcs(s->vdev); | ||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | /* Initialize v4l2 variables and prepare v4l2 devices */ | ||
223 | int ivtv_streams_setup(struct ivtv *itv) | ||
224 | { | ||
225 | int type; | ||
226 | |||
227 | /* Setup V4L2 Devices */ | ||
228 | for (type = 0; type < IVTV_MAX_STREAMS; type++) { | ||
229 | /* Prepare device */ | ||
230 | if (ivtv_prep_dev(itv, type)) | ||
231 | break; | ||
232 | |||
233 | if (itv->streams[type].vdev == NULL) | ||
234 | continue; | ||
235 | |||
236 | /* Allocate Stream */ | ||
237 | if (ivtv_stream_alloc(&itv->streams[type])) | ||
238 | break; | ||
239 | } | ||
240 | if (type == IVTV_MAX_STREAMS) | ||
241 | return 0; | ||
242 | |||
243 | /* One or more streams could not be initialized. Clean 'em all up. */ | ||
244 | ivtv_streams_cleanup(itv, 0); | ||
245 | return -ENOMEM; | ||
246 | } | ||
247 | |||
248 | static int ivtv_reg_dev(struct ivtv *itv, int type) | ||
249 | { | ||
250 | struct ivtv_stream *s = &itv->streams[type]; | ||
251 | int vfl_type = ivtv_stream_info[type].vfl_type; | ||
252 | const char *name; | ||
253 | int num; | ||
254 | |||
255 | if (s->vdev == NULL) | ||
256 | return 0; | ||
257 | |||
258 | num = s->vdev->num; | ||
259 | /* card number + user defined offset + device offset */ | ||
260 | if (type != IVTV_ENC_STREAM_TYPE_MPG) { | ||
261 | struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG]; | ||
262 | |||
263 | if (s_mpg->vdev) | ||
264 | num = s_mpg->vdev->num + ivtv_stream_info[type].num_offset; | ||
265 | } | ||
266 | video_set_drvdata(s->vdev, s); | ||
267 | |||
268 | /* Register device. First try the desired minor, then any free one. */ | ||
269 | if (video_register_device_no_warn(s->vdev, vfl_type, num)) { | ||
270 | IVTV_ERR("Couldn't register v4l2 device for %s (device node number %d)\n", | ||
271 | s->name, num); | ||
272 | video_device_release(s->vdev); | ||
273 | s->vdev = NULL; | ||
274 | return -ENOMEM; | ||
275 | } | ||
276 | name = video_device_node_name(s->vdev); | ||
277 | |||
278 | switch (vfl_type) { | ||
279 | case VFL_TYPE_GRABBER: | ||
280 | IVTV_INFO("Registered device %s for %s (%d kB)\n", | ||
281 | name, s->name, itv->options.kilobytes[type]); | ||
282 | break; | ||
283 | case VFL_TYPE_RADIO: | ||
284 | IVTV_INFO("Registered device %s for %s\n", | ||
285 | name, s->name); | ||
286 | break; | ||
287 | case VFL_TYPE_VBI: | ||
288 | if (itv->options.kilobytes[type]) | ||
289 | IVTV_INFO("Registered device %s for %s (%d kB)\n", | ||
290 | name, s->name, itv->options.kilobytes[type]); | ||
291 | else | ||
292 | IVTV_INFO("Registered device %s for %s\n", | ||
293 | name, s->name); | ||
294 | break; | ||
295 | } | ||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | /* Register v4l2 devices */ | ||
300 | int ivtv_streams_register(struct ivtv *itv) | ||
301 | { | ||
302 | int type; | ||
303 | int err = 0; | ||
304 | |||
305 | /* Register V4L2 devices */ | ||
306 | for (type = 0; type < IVTV_MAX_STREAMS; type++) | ||
307 | err |= ivtv_reg_dev(itv, type); | ||
308 | |||
309 | if (err == 0) | ||
310 | return 0; | ||
311 | |||
312 | /* One or more streams could not be initialized. Clean 'em all up. */ | ||
313 | ivtv_streams_cleanup(itv, 1); | ||
314 | return -ENOMEM; | ||
315 | } | ||
316 | |||
317 | /* Unregister v4l2 devices */ | ||
318 | void ivtv_streams_cleanup(struct ivtv *itv, int unregister) | ||
319 | { | ||
320 | int type; | ||
321 | |||
322 | /* Teardown all streams */ | ||
323 | for (type = 0; type < IVTV_MAX_STREAMS; type++) { | ||
324 | struct video_device *vdev = itv->streams[type].vdev; | ||
325 | |||
326 | itv->streams[type].vdev = NULL; | ||
327 | if (vdev == NULL) | ||
328 | continue; | ||
329 | |||
330 | ivtv_stream_free(&itv->streams[type]); | ||
331 | /* Unregister or release device */ | ||
332 | if (unregister) | ||
333 | video_unregister_device(vdev); | ||
334 | else | ||
335 | video_device_release(vdev); | ||
336 | } | ||
337 | } | ||
338 | |||
339 | static void ivtv_vbi_setup(struct ivtv *itv) | ||
340 | { | ||
341 | int raw = ivtv_raw_vbi(itv); | ||
342 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
343 | int lines; | ||
344 | int i; | ||
345 | |||
346 | /* Reset VBI */ | ||
347 | ivtv_vapi(itv, CX2341X_ENC_SET_VBI_LINE, 5, 0xffff , 0, 0, 0, 0); | ||
348 | |||
349 | /* setup VBI registers */ | ||
350 | if (raw) | ||
351 | v4l2_subdev_call(itv->sd_video, vbi, s_raw_fmt, &itv->vbi.in.fmt.vbi); | ||
352 | else | ||
353 | v4l2_subdev_call(itv->sd_video, vbi, s_sliced_fmt, &itv->vbi.in.fmt.sliced); | ||
354 | |||
355 | /* determine number of lines and total number of VBI bytes. | ||
356 | A raw line takes 1443 bytes: 2 * 720 + 4 byte frame header - 1 | ||
357 | The '- 1' byte is probably an unused U or V byte. Or something... | ||
358 | A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal | ||
359 | header, 42 data bytes + checksum (to be confirmed) */ | ||
360 | if (raw) { | ||
361 | lines = itv->vbi.count * 2; | ||
362 | } else { | ||
363 | lines = itv->is_60hz ? 24 : 38; | ||
364 | if (itv->is_60hz && (itv->hw_flags & IVTV_HW_CX25840)) | ||
365 | lines += 2; | ||
366 | } | ||
367 | |||
368 | itv->vbi.enc_size = lines * (raw ? itv->vbi.raw_size : itv->vbi.sliced_size); | ||
369 | |||
370 | /* Note: sliced vs raw flag doesn't seem to have any effect | ||
371 | TODO: check mode (0x02) value with older ivtv versions. */ | ||
372 | data[0] = raw | 0x02 | (0xbd << 8); | ||
373 | |||
374 | /* Every X number of frames a VBI interrupt arrives (frames as in 25 or 30 fps) */ | ||
375 | data[1] = 1; | ||
376 | /* The VBI frames are stored in a ringbuffer with this size (with a VBI frame as unit) */ | ||
377 | data[2] = raw ? 4 : 4 * (itv->vbi.raw_size / itv->vbi.enc_size); | ||
378 | /* The start/stop codes determine which VBI lines end up in the raw VBI data area. | ||
379 | The codes are from table 24 in the saa7115 datasheet. Each raw/sliced/video line | ||
380 | is framed with codes FF0000XX where XX is the SAV/EAV (Start/End of Active Video) | ||
381 | code. These values for raw VBI are obtained from a driver disassembly. The sliced | ||
382 | start/stop codes was deduced from this, but they do not appear in the driver. | ||
383 | Other code pairs that I found are: 0x250E6249/0x13545454 and 0x25256262/0x38137F54. | ||
384 | However, I have no idea what these values are for. */ | ||
385 | if (itv->hw_flags & IVTV_HW_CX25840) { | ||
386 | /* Setup VBI for the cx25840 digitizer */ | ||
387 | if (raw) { | ||
388 | data[3] = 0x20602060; | ||
389 | data[4] = 0x30703070; | ||
390 | } else { | ||
391 | data[3] = 0xB0F0B0F0; | ||
392 | data[4] = 0xA0E0A0E0; | ||
393 | } | ||
394 | /* Lines per frame */ | ||
395 | data[5] = lines; | ||
396 | /* bytes per line */ | ||
397 | data[6] = (raw ? itv->vbi.raw_size : itv->vbi.sliced_size); | ||
398 | } else { | ||
399 | /* Setup VBI for the saa7115 digitizer */ | ||
400 | if (raw) { | ||
401 | data[3] = 0x25256262; | ||
402 | data[4] = 0x387F7F7F; | ||
403 | } else { | ||
404 | data[3] = 0xABABECEC; | ||
405 | data[4] = 0xB6F1F1F1; | ||
406 | } | ||
407 | /* Lines per frame */ | ||
408 | data[5] = lines; | ||
409 | /* bytes per line */ | ||
410 | data[6] = itv->vbi.enc_size / lines; | ||
411 | } | ||
412 | |||
413 | IVTV_DEBUG_INFO( | ||
414 | "Setup VBI API header 0x%08x pkts %d buffs %d ln %d sz %d\n", | ||
415 | data[0], data[1], data[2], data[5], data[6]); | ||
416 | |||
417 | ivtv_api(itv, CX2341X_ENC_SET_VBI_CONFIG, 7, data); | ||
418 | |||
419 | /* returns the VBI encoder memory area. */ | ||
420 | itv->vbi.enc_start = data[2]; | ||
421 | itv->vbi.fpi = data[0]; | ||
422 | if (!itv->vbi.fpi) | ||
423 | itv->vbi.fpi = 1; | ||
424 | |||
425 | IVTV_DEBUG_INFO("Setup VBI start 0x%08x frames %d fpi %d\n", | ||
426 | itv->vbi.enc_start, data[1], itv->vbi.fpi); | ||
427 | |||
428 | /* select VBI lines. | ||
429 | Note that the sliced argument seems to have no effect. */ | ||
430 | for (i = 2; i <= 24; i++) { | ||
431 | int valid; | ||
432 | |||
433 | if (itv->is_60hz) { | ||
434 | valid = i >= 10 && i < 22; | ||
435 | } else { | ||
436 | valid = i >= 6 && i < 24; | ||
437 | } | ||
438 | ivtv_vapi(itv, CX2341X_ENC_SET_VBI_LINE, 5, i - 1, | ||
439 | valid, 0 , 0, 0); | ||
440 | ivtv_vapi(itv, CX2341X_ENC_SET_VBI_LINE, 5, (i - 1) | 0x80000000, | ||
441 | valid, 0, 0, 0); | ||
442 | } | ||
443 | |||
444 | /* Remaining VBI questions: | ||
445 | - Is it possible to select particular VBI lines only for inclusion in the MPEG | ||
446 | stream? Currently you can only get the first X lines. | ||
447 | - Is mixed raw and sliced VBI possible? | ||
448 | - What's the meaning of the raw/sliced flag? | ||
449 | - What's the meaning of params 2, 3 & 4 of the Select VBI command? */ | ||
450 | } | ||
451 | |||
452 | int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) | ||
453 | { | ||
454 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
455 | struct ivtv *itv = s->itv; | ||
456 | int captype = 0, subtype = 0; | ||
457 | int enable_passthrough = 0; | ||
458 | |||
459 | if (s->vdev == NULL) | ||
460 | return -EINVAL; | ||
461 | |||
462 | IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name); | ||
463 | |||
464 | switch (s->type) { | ||
465 | case IVTV_ENC_STREAM_TYPE_MPG: | ||
466 | captype = 0; | ||
467 | subtype = 3; | ||
468 | |||
469 | /* Stop Passthrough */ | ||
470 | if (itv->output_mode == OUT_PASSTHROUGH) { | ||
471 | ivtv_passthrough_mode(itv, 0); | ||
472 | enable_passthrough = 1; | ||
473 | } | ||
474 | itv->mpg_data_received = itv->vbi_data_inserted = 0; | ||
475 | itv->dualwatch_jiffies = jiffies; | ||
476 | itv->dualwatch_stereo_mode = v4l2_ctrl_g_ctrl(itv->cxhdl.audio_mode); | ||
477 | itv->search_pack_header = 0; | ||
478 | break; | ||
479 | |||
480 | case IVTV_ENC_STREAM_TYPE_YUV: | ||
481 | if (itv->output_mode == OUT_PASSTHROUGH) { | ||
482 | captype = 2; | ||
483 | subtype = 11; /* video+audio+decoder */ | ||
484 | break; | ||
485 | } | ||
486 | captype = 1; | ||
487 | subtype = 1; | ||
488 | break; | ||
489 | case IVTV_ENC_STREAM_TYPE_PCM: | ||
490 | captype = 1; | ||
491 | subtype = 2; | ||
492 | break; | ||
493 | case IVTV_ENC_STREAM_TYPE_VBI: | ||
494 | captype = 1; | ||
495 | subtype = 4; | ||
496 | |||
497 | itv->vbi.frame = 0; | ||
498 | itv->vbi.inserted_frame = 0; | ||
499 | memset(itv->vbi.sliced_mpeg_size, | ||
500 | 0, sizeof(itv->vbi.sliced_mpeg_size)); | ||
501 | break; | ||
502 | default: | ||
503 | return -EINVAL; | ||
504 | } | ||
505 | s->subtype = subtype; | ||
506 | s->buffers_stolen = 0; | ||
507 | |||
508 | /* Clear Streamoff flags in case left from last capture */ | ||
509 | clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags); | ||
510 | |||
511 | if (atomic_read(&itv->capturing) == 0) { | ||
512 | int digitizer; | ||
513 | |||
514 | /* Always use frame based mode. Experiments have demonstrated that byte | ||
515 | stream based mode results in dropped frames and corruption. Not often, | ||
516 | but occasionally. Many thanks go to Leonard Orb who spent a lot of | ||
517 | effort and time trying to trace the cause of the drop outs. */ | ||
518 | /* 1 frame per DMA */ | ||
519 | /*ivtv_vapi(itv, CX2341X_ENC_SET_DMA_BLOCK_SIZE, 2, 128, 0); */ | ||
520 | ivtv_vapi(itv, CX2341X_ENC_SET_DMA_BLOCK_SIZE, 2, 1, 1); | ||
521 | |||
522 | /* Stuff from Windows, we don't know what it is */ | ||
523 | ivtv_vapi(itv, CX2341X_ENC_SET_VERT_CROP_LINE, 1, 0); | ||
524 | /* According to the docs, this should be correct. However, this is | ||
525 | untested. I don't dare enable this without having tested it. | ||
526 | Only very few old cards actually have this hardware combination. | ||
527 | ivtv_vapi(itv, CX2341X_ENC_SET_VERT_CROP_LINE, 1, | ||
528 | ((itv->hw_flags & IVTV_HW_SAA7114) && itv->is_60hz) ? 10001 : 0); | ||
529 | */ | ||
530 | ivtv_vapi(itv, CX2341X_ENC_MISC, 2, 3, !itv->has_cx23415); | ||
531 | ivtv_vapi(itv, CX2341X_ENC_MISC, 2, 8, 0); | ||
532 | ivtv_vapi(itv, CX2341X_ENC_MISC, 2, 4, 1); | ||
533 | ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12); | ||
534 | |||
535 | /* assign placeholder */ | ||
536 | ivtv_vapi(itv, CX2341X_ENC_SET_PLACEHOLDER, 12, | ||
537 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); | ||
538 | |||
539 | if (itv->card->hw_all & (IVTV_HW_SAA7115 | IVTV_HW_SAA717X)) | ||
540 | digitizer = 0xF1; | ||
541 | else if (itv->card->hw_all & IVTV_HW_SAA7114) | ||
542 | digitizer = 0xEF; | ||
543 | else /* cx25840 */ | ||
544 | digitizer = 0x140; | ||
545 | |||
546 | ivtv_vapi(itv, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, digitizer, digitizer); | ||
547 | |||
548 | /* Setup VBI */ | ||
549 | if (itv->v4l2_cap & V4L2_CAP_VBI_CAPTURE) { | ||
550 | ivtv_vbi_setup(itv); | ||
551 | } | ||
552 | |||
553 | /* assign program index info. Mask 7: select I/P/B, Num_req: 400 max */ | ||
554 | ivtv_vapi_result(itv, data, CX2341X_ENC_SET_PGM_INDEX_INFO, 2, 7, 400); | ||
555 | itv->pgm_info_offset = data[0]; | ||
556 | itv->pgm_info_num = data[1]; | ||
557 | itv->pgm_info_write_idx = 0; | ||
558 | itv->pgm_info_read_idx = 0; | ||
559 | |||
560 | IVTV_DEBUG_INFO("PGM Index at 0x%08x with %d elements\n", | ||
561 | itv->pgm_info_offset, itv->pgm_info_num); | ||
562 | |||
563 | /* Setup API for Stream */ | ||
564 | cx2341x_handler_setup(&itv->cxhdl); | ||
565 | |||
566 | /* mute if capturing radio */ | ||
567 | if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) | ||
568 | ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1, | ||
569 | 1 | (v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute_yuv) << 8)); | ||
570 | } | ||
571 | |||
572 | /* Vsync Setup */ | ||
573 | if (itv->has_cx23415 && !test_and_set_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) { | ||
574 | /* event notification (on) */ | ||
575 | ivtv_vapi(itv, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, 0, 1, IVTV_IRQ_ENC_VIM_RST, -1); | ||
576 | ivtv_clear_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST); | ||
577 | } | ||
578 | |||
579 | if (atomic_read(&itv->capturing) == 0) { | ||
580 | /* Clear all Pending Interrupts */ | ||
581 | ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE); | ||
582 | |||
583 | clear_bit(IVTV_F_I_EOS, &itv->i_flags); | ||
584 | |||
585 | cx2341x_handler_set_busy(&itv->cxhdl, 1); | ||
586 | |||
587 | /* Initialize Digitizer for Capture */ | ||
588 | /* Avoid tinny audio problem - ensure audio clocks are going */ | ||
589 | v4l2_subdev_call(itv->sd_audio, audio, s_stream, 1); | ||
590 | /* Avoid unpredictable PCI bus hang - disable video clocks */ | ||
591 | v4l2_subdev_call(itv->sd_video, video, s_stream, 0); | ||
592 | ivtv_msleep_timeout(300, 0); | ||
593 | ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0); | ||
594 | v4l2_subdev_call(itv->sd_video, video, s_stream, 1); | ||
595 | } | ||
596 | |||
597 | /* begin_capture */ | ||
598 | if (ivtv_vapi(itv, CX2341X_ENC_START_CAPTURE, 2, captype, subtype)) | ||
599 | { | ||
600 | IVTV_DEBUG_WARN( "Error starting capture!\n"); | ||
601 | return -EINVAL; | ||
602 | } | ||
603 | |||
604 | /* Start Passthrough */ | ||
605 | if (enable_passthrough) { | ||
606 | ivtv_passthrough_mode(itv, 1); | ||
607 | } | ||
608 | |||
609 | if (s->type == IVTV_ENC_STREAM_TYPE_VBI) | ||
610 | ivtv_clear_irq_mask(itv, IVTV_IRQ_ENC_VBI_CAP); | ||
611 | else | ||
612 | ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE); | ||
613 | |||
614 | /* you're live! sit back and await interrupts :) */ | ||
615 | atomic_inc(&itv->capturing); | ||
616 | return 0; | ||
617 | } | ||
618 | |||
619 | static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) | ||
620 | { | ||
621 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
622 | struct ivtv *itv = s->itv; | ||
623 | int datatype; | ||
624 | u16 width; | ||
625 | u16 height; | ||
626 | |||
627 | if (s->vdev == NULL) | ||
628 | return -EINVAL; | ||
629 | |||
630 | IVTV_DEBUG_INFO("Setting some initial decoder settings\n"); | ||
631 | |||
632 | width = itv->cxhdl.width; | ||
633 | height = itv->cxhdl.height; | ||
634 | |||
635 | /* set audio mode to left/stereo for dual/stereo mode. */ | ||
636 | ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); | ||
637 | |||
638 | /* set number of internal decoder buffers */ | ||
639 | ivtv_vapi(itv, CX2341X_DEC_SET_DISPLAY_BUFFERS, 1, 0); | ||
640 | |||
641 | /* prebuffering */ | ||
642 | ivtv_vapi(itv, CX2341X_DEC_SET_PREBUFFERING, 1, 1); | ||
643 | |||
644 | /* extract from user packets */ | ||
645 | ivtv_vapi_result(itv, data, CX2341X_DEC_EXTRACT_VBI, 1, 1); | ||
646 | itv->vbi.dec_start = data[0]; | ||
647 | |||
648 | IVTV_DEBUG_INFO("Decoder VBI RE-Insert start 0x%08x size 0x%08x\n", | ||
649 | itv->vbi.dec_start, data[1]); | ||
650 | |||
651 | /* set decoder source settings */ | ||
652 | /* Data type: 0 = mpeg from host, | ||
653 | 1 = yuv from encoder, | ||
654 | 2 = yuv_from_host */ | ||
655 | switch (s->type) { | ||
656 | case IVTV_DEC_STREAM_TYPE_YUV: | ||
657 | if (itv->output_mode == OUT_PASSTHROUGH) { | ||
658 | datatype = 1; | ||
659 | } else { | ||
660 | /* Fake size to avoid switching video standard */ | ||
661 | datatype = 2; | ||
662 | width = 720; | ||
663 | height = itv->is_out_50hz ? 576 : 480; | ||
664 | } | ||
665 | IVTV_DEBUG_INFO("Setup DEC YUV Stream data[0] = %d\n", datatype); | ||
666 | break; | ||
667 | case IVTV_DEC_STREAM_TYPE_MPG: | ||
668 | default: | ||
669 | datatype = 0; | ||
670 | break; | ||
671 | } | ||
672 | if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype, | ||
673 | width, height, itv->cxhdl.audio_properties)) { | ||
674 | IVTV_DEBUG_WARN("Couldn't initialize decoder source\n"); | ||
675 | } | ||
676 | |||
677 | /* Decoder sometimes dies here, so wait a moment */ | ||
678 | ivtv_msleep_timeout(10, 0); | ||
679 | |||
680 | /* Known failure point for firmware, so check */ | ||
681 | return ivtv_firmware_check(itv, "ivtv_setup_v4l2_decode_stream"); | ||
682 | } | ||
683 | |||
684 | int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset) | ||
685 | { | ||
686 | struct ivtv *itv = s->itv; | ||
687 | int rc; | ||
688 | |||
689 | if (s->vdev == NULL) | ||
690 | return -EINVAL; | ||
691 | |||
692 | if (test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags)) | ||
693 | return 0; /* already started */ | ||
694 | |||
695 | IVTV_DEBUG_INFO("Starting decode stream %s (gop_offset %d)\n", s->name, gop_offset); | ||
696 | |||
697 | rc = ivtv_setup_v4l2_decode_stream(s); | ||
698 | if (rc < 0) { | ||
699 | clear_bit(IVTV_F_S_STREAMING, &s->s_flags); | ||
700 | return rc; | ||
701 | } | ||
702 | |||
703 | /* set dma size to 65536 bytes */ | ||
704 | ivtv_vapi(itv, CX2341X_DEC_SET_DMA_BLOCK_SIZE, 1, 65536); | ||
705 | |||
706 | /* Clear Streamoff */ | ||
707 | clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags); | ||
708 | |||
709 | /* Zero out decoder counters */ | ||
710 | writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA_END].data[0]); | ||
711 | writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA_END].data[1]); | ||
712 | writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA_END].data[2]); | ||
713 | writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA_END].data[3]); | ||
714 | writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA].data[0]); | ||
715 | writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA].data[1]); | ||
716 | writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA].data[2]); | ||
717 | writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA].data[3]); | ||
718 | |||
719 | /* turn on notification of dual/stereo mode change */ | ||
720 | ivtv_vapi(itv, CX2341X_DEC_SET_EVENT_NOTIFICATION, 4, 0, 1, IVTV_IRQ_DEC_AUD_MODE_CHG, -1); | ||
721 | |||
722 | /* start playback */ | ||
723 | ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, gop_offset, 0); | ||
724 | |||
725 | /* Let things settle before we actually start */ | ||
726 | ivtv_msleep_timeout(10, 0); | ||
727 | |||
728 | /* Clear the following Interrupt mask bits for decoding */ | ||
729 | ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_DECODE); | ||
730 | IVTV_DEBUG_IRQ("IRQ Mask is now: 0x%08x\n", itv->irqmask); | ||
731 | |||
732 | /* you're live! sit back and await interrupts :) */ | ||
733 | atomic_inc(&itv->decoding); | ||
734 | return 0; | ||
735 | } | ||
736 | |||
737 | void ivtv_stop_all_captures(struct ivtv *itv) | ||
738 | { | ||
739 | int i; | ||
740 | |||
741 | for (i = IVTV_MAX_STREAMS - 1; i >= 0; i--) { | ||
742 | struct ivtv_stream *s = &itv->streams[i]; | ||
743 | |||
744 | if (s->vdev == NULL) | ||
745 | continue; | ||
746 | if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { | ||
747 | ivtv_stop_v4l2_encode_stream(s, 0); | ||
748 | } | ||
749 | } | ||
750 | } | ||
751 | |||
752 | int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) | ||
753 | { | ||
754 | struct ivtv *itv = s->itv; | ||
755 | DECLARE_WAITQUEUE(wait, current); | ||
756 | int cap_type; | ||
757 | int stopmode; | ||
758 | |||
759 | if (s->vdev == NULL) | ||
760 | return -EINVAL; | ||
761 | |||
762 | /* This function assumes that you are allowed to stop the capture | ||
763 | and that we are actually capturing */ | ||
764 | |||
765 | IVTV_DEBUG_INFO("Stop Capture\n"); | ||
766 | |||
767 | if (s->type == IVTV_DEC_STREAM_TYPE_VOUT) | ||
768 | return 0; | ||
769 | if (atomic_read(&itv->capturing) == 0) | ||
770 | return 0; | ||
771 | |||
772 | switch (s->type) { | ||
773 | case IVTV_ENC_STREAM_TYPE_YUV: | ||
774 | cap_type = 1; | ||
775 | break; | ||
776 | case IVTV_ENC_STREAM_TYPE_PCM: | ||
777 | cap_type = 1; | ||
778 | break; | ||
779 | case IVTV_ENC_STREAM_TYPE_VBI: | ||
780 | cap_type = 1; | ||
781 | break; | ||
782 | case IVTV_ENC_STREAM_TYPE_MPG: | ||
783 | default: | ||
784 | cap_type = 0; | ||
785 | break; | ||
786 | } | ||
787 | |||
788 | /* Stop Capture Mode */ | ||
789 | if (s->type == IVTV_ENC_STREAM_TYPE_MPG && gop_end) { | ||
790 | stopmode = 0; | ||
791 | } else { | ||
792 | stopmode = 1; | ||
793 | } | ||
794 | |||
795 | /* end_capture */ | ||
796 | /* when: 0 = end of GOP 1 = NOW!, type: 0 = mpeg, subtype: 3 = video+audio */ | ||
797 | ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, stopmode, cap_type, s->subtype); | ||
798 | |||
799 | if (!test_bit(IVTV_F_S_PASSTHROUGH, &s->s_flags)) { | ||
800 | if (s->type == IVTV_ENC_STREAM_TYPE_MPG && gop_end) { | ||
801 | /* only run these if we're shutting down the last cap */ | ||
802 | unsigned long duration; | ||
803 | unsigned long then = jiffies; | ||
804 | |||
805 | add_wait_queue(&itv->eos_waitq, &wait); | ||
806 | |||
807 | set_current_state(TASK_INTERRUPTIBLE); | ||
808 | |||
809 | /* wait 2s for EOS interrupt */ | ||
810 | while (!test_bit(IVTV_F_I_EOS, &itv->i_flags) && | ||
811 | time_before(jiffies, | ||
812 | then + msecs_to_jiffies(2000))) { | ||
813 | schedule_timeout(msecs_to_jiffies(10)); | ||
814 | } | ||
815 | |||
816 | /* To convert jiffies to ms, we must multiply by 1000 | ||
817 | * and divide by HZ. To avoid runtime division, we | ||
818 | * convert this to multiplication by 1000/HZ. | ||
819 | * Since integer division truncates, we get the best | ||
820 | * accuracy if we do a rounding calculation of the constant. | ||
821 | * Think of the case where HZ is 1024. | ||
822 | */ | ||
823 | duration = ((1000 + HZ / 2) / HZ) * (jiffies - then); | ||
824 | |||
825 | if (!test_bit(IVTV_F_I_EOS, &itv->i_flags)) { | ||
826 | IVTV_DEBUG_WARN("%s: EOS interrupt not received! stopping anyway.\n", s->name); | ||
827 | IVTV_DEBUG_WARN("%s: waited %lu ms.\n", s->name, duration); | ||
828 | } else { | ||
829 | IVTV_DEBUG_INFO("%s: EOS took %lu ms to occur.\n", s->name, duration); | ||
830 | } | ||
831 | set_current_state(TASK_RUNNING); | ||
832 | remove_wait_queue(&itv->eos_waitq, &wait); | ||
833 | set_bit(IVTV_F_S_STREAMOFF, &s->s_flags); | ||
834 | } | ||
835 | |||
836 | /* Handle any pending interrupts */ | ||
837 | ivtv_msleep_timeout(100, 0); | ||
838 | } | ||
839 | |||
840 | atomic_dec(&itv->capturing); | ||
841 | |||
842 | /* Clear capture and no-read bits */ | ||
843 | clear_bit(IVTV_F_S_STREAMING, &s->s_flags); | ||
844 | |||
845 | if (s->type == IVTV_ENC_STREAM_TYPE_VBI) | ||
846 | ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VBI_CAP); | ||
847 | |||
848 | if (atomic_read(&itv->capturing) > 0) { | ||
849 | return 0; | ||
850 | } | ||
851 | |||
852 | cx2341x_handler_set_busy(&itv->cxhdl, 0); | ||
853 | |||
854 | /* Set the following Interrupt mask bits for capture */ | ||
855 | ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE); | ||
856 | del_timer(&itv->dma_timer); | ||
857 | |||
858 | /* event notification (off) */ | ||
859 | if (test_and_clear_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) { | ||
860 | /* type: 0 = refresh */ | ||
861 | /* on/off: 0 = off, intr: 0x10000000, mbox_id: -1: none */ | ||
862 | ivtv_vapi(itv, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_ENC_VIM_RST, -1); | ||
863 | ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST); | ||
864 | } | ||
865 | |||
866 | /* Raw-passthrough is implied on start. Make sure it's stopped so | ||
867 | the encoder will re-initialize when next started */ | ||
868 | ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, 1, 2, 7); | ||
869 | |||
870 | wake_up(&s->waitq); | ||
871 | |||
872 | return 0; | ||
873 | } | ||
874 | |||
875 | int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts) | ||
876 | { | ||
877 | static const struct v4l2_event ev = { | ||
878 | .type = V4L2_EVENT_EOS, | ||
879 | }; | ||
880 | struct ivtv *itv = s->itv; | ||
881 | |||
882 | if (s->vdev == NULL) | ||
883 | return -EINVAL; | ||
884 | |||
885 | if (s->type != IVTV_DEC_STREAM_TYPE_YUV && s->type != IVTV_DEC_STREAM_TYPE_MPG) | ||
886 | return -EINVAL; | ||
887 | |||
888 | if (!test_bit(IVTV_F_S_STREAMING, &s->s_flags)) | ||
889 | return 0; | ||
890 | |||
891 | IVTV_DEBUG_INFO("Stop Decode at %llu, flags: %x\n", (unsigned long long)pts, flags); | ||
892 | |||
893 | /* Stop Decoder */ | ||
894 | if (!(flags & VIDEO_CMD_STOP_IMMEDIATELY) || pts) { | ||
895 | u32 tmp = 0; | ||
896 | |||
897 | /* Wait until the decoder is no longer running */ | ||
898 | if (pts) { | ||
899 | ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 3, | ||
900 | 0, (u32)(pts & 0xffffffff), (u32)(pts >> 32)); | ||
901 | } | ||
902 | while (1) { | ||
903 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
904 | ivtv_vapi_result(itv, data, CX2341X_DEC_GET_XFER_INFO, 0); | ||
905 | if (s->q_full.buffers + s->q_dma.buffers == 0) { | ||
906 | if (tmp == data[3]) | ||
907 | break; | ||
908 | tmp = data[3]; | ||
909 | } | ||
910 | if (ivtv_msleep_timeout(100, 1)) | ||
911 | break; | ||
912 | } | ||
913 | } | ||
914 | ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 3, flags & VIDEO_CMD_STOP_TO_BLACK, 0, 0); | ||
915 | |||
916 | /* turn off notification of dual/stereo mode change */ | ||
917 | ivtv_vapi(itv, CX2341X_DEC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_DEC_AUD_MODE_CHG, -1); | ||
918 | |||
919 | ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_DECODE); | ||
920 | del_timer(&itv->dma_timer); | ||
921 | |||
922 | clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags); | ||
923 | clear_bit(IVTV_F_S_STREAMING, &s->s_flags); | ||
924 | ivtv_flush_queues(s); | ||
925 | |||
926 | /* decoder needs time to settle */ | ||
927 | ivtv_msleep_timeout(40, 0); | ||
928 | |||
929 | /* decrement decoding */ | ||
930 | atomic_dec(&itv->decoding); | ||
931 | |||
932 | set_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags); | ||
933 | wake_up(&itv->event_waitq); | ||
934 | v4l2_event_queue(s->vdev, &ev); | ||
935 | |||
936 | /* wake up wait queues */ | ||
937 | wake_up(&s->waitq); | ||
938 | |||
939 | return 0; | ||
940 | } | ||
941 | |||
942 | int ivtv_passthrough_mode(struct ivtv *itv, int enable) | ||
943 | { | ||
944 | struct ivtv_stream *yuv_stream = &itv->streams[IVTV_ENC_STREAM_TYPE_YUV]; | ||
945 | struct ivtv_stream *dec_stream = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV]; | ||
946 | |||
947 | if (yuv_stream->vdev == NULL || dec_stream->vdev == NULL) | ||
948 | return -EINVAL; | ||
949 | |||
950 | IVTV_DEBUG_INFO("ivtv ioctl: Select passthrough mode\n"); | ||
951 | |||
952 | /* Prevent others from starting/stopping streams while we | ||
953 | initiate/terminate passthrough mode */ | ||
954 | if (enable) { | ||
955 | if (itv->output_mode == OUT_PASSTHROUGH) { | ||
956 | return 0; | ||
957 | } | ||
958 | if (ivtv_set_output_mode(itv, OUT_PASSTHROUGH) != OUT_PASSTHROUGH) | ||
959 | return -EBUSY; | ||
960 | |||
961 | /* Fully initialize stream, and then unflag init */ | ||
962 | set_bit(IVTV_F_S_PASSTHROUGH, &dec_stream->s_flags); | ||
963 | set_bit(IVTV_F_S_STREAMING, &dec_stream->s_flags); | ||
964 | |||
965 | /* Setup YUV Decoder */ | ||
966 | ivtv_setup_v4l2_decode_stream(dec_stream); | ||
967 | |||
968 | /* Start Decoder */ | ||
969 | ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, 0, 1); | ||
970 | atomic_inc(&itv->decoding); | ||
971 | |||
972 | /* Setup capture if not already done */ | ||
973 | if (atomic_read(&itv->capturing) == 0) { | ||
974 | cx2341x_handler_setup(&itv->cxhdl); | ||
975 | cx2341x_handler_set_busy(&itv->cxhdl, 1); | ||
976 | } | ||
977 | |||
978 | /* Start Passthrough Mode */ | ||
979 | ivtv_vapi(itv, CX2341X_ENC_START_CAPTURE, 2, 2, 11); | ||
980 | atomic_inc(&itv->capturing); | ||
981 | return 0; | ||
982 | } | ||
983 | |||
984 | if (itv->output_mode != OUT_PASSTHROUGH) | ||
985 | return 0; | ||
986 | |||
987 | /* Stop Passthrough Mode */ | ||
988 | ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, 1, 2, 11); | ||
989 | ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 3, 1, 0, 0); | ||
990 | |||
991 | atomic_dec(&itv->capturing); | ||
992 | atomic_dec(&itv->decoding); | ||
993 | clear_bit(IVTV_F_S_PASSTHROUGH, &dec_stream->s_flags); | ||
994 | clear_bit(IVTV_F_S_STREAMING, &dec_stream->s_flags); | ||
995 | itv->output_mode = OUT_NONE; | ||
996 | if (atomic_read(&itv->capturing) == 0) | ||
997 | cx2341x_handler_set_busy(&itv->cxhdl, 0); | ||
998 | |||
999 | return 0; | ||
1000 | } | ||
diff --git a/drivers/media/video/ivtv/ivtv-streams.h b/drivers/media/video/ivtv/ivtv-streams.h new file mode 100644 index 00000000000..a653a513641 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-streams.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | init/start/stop/exit stream functions | ||
3 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
4 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #ifndef IVTV_STREAMS_H | ||
22 | #define IVTV_STREAMS_H | ||
23 | |||
24 | int ivtv_streams_setup(struct ivtv *itv); | ||
25 | int ivtv_streams_register(struct ivtv *itv); | ||
26 | void ivtv_streams_cleanup(struct ivtv *itv, int unregister); | ||
27 | |||
28 | /* Capture related */ | ||
29 | int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s); | ||
30 | int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end); | ||
31 | int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset); | ||
32 | int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts); | ||
33 | |||
34 | void ivtv_stop_all_captures(struct ivtv *itv); | ||
35 | int ivtv_passthrough_mode(struct ivtv *itv, int enable); | ||
36 | |||
37 | #endif | ||
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c new file mode 100644 index 00000000000..69cc8166b20 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-udma.c | |||
@@ -0,0 +1,234 @@ | |||
1 | /* | ||
2 | User DMA | ||
3 | |||
4 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
5 | Copyright (C) 2004 Chris Kennedy <c@groovy.org> | ||
6 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2 of the License, or | ||
11 | (at your option) any later version. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | GNU General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU General Public License | ||
19 | along with this program; if not, write to the Free Software | ||
20 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #include "ivtv-driver.h" | ||
24 | #include "ivtv-udma.h" | ||
25 | |||
26 | void ivtv_udma_get_page_info(struct ivtv_dma_page_info *dma_page, unsigned long first, unsigned long size) | ||
27 | { | ||
28 | dma_page->uaddr = first & PAGE_MASK; | ||
29 | dma_page->offset = first & ~PAGE_MASK; | ||
30 | dma_page->tail = 1 + ((first+size-1) & ~PAGE_MASK); | ||
31 | dma_page->first = (first & PAGE_MASK) >> PAGE_SHIFT; | ||
32 | dma_page->last = ((first+size-1) & PAGE_MASK) >> PAGE_SHIFT; | ||
33 | dma_page->page_count = dma_page->last - dma_page->first + 1; | ||
34 | if (dma_page->page_count == 1) dma_page->tail -= dma_page->offset; | ||
35 | } | ||
36 | |||
37 | int ivtv_udma_fill_sg_list (struct ivtv_user_dma *dma, struct ivtv_dma_page_info *dma_page, int map_offset) | ||
38 | { | ||
39 | int i, offset; | ||
40 | unsigned long flags; | ||
41 | |||
42 | if (map_offset < 0) | ||
43 | return map_offset; | ||
44 | |||
45 | offset = dma_page->offset; | ||
46 | |||
47 | /* Fill SG Array with new values */ | ||
48 | for (i = 0; i < dma_page->page_count; i++) { | ||
49 | unsigned int len = (i == dma_page->page_count - 1) ? | ||
50 | dma_page->tail : PAGE_SIZE - offset; | ||
51 | |||
52 | if (PageHighMem(dma->map[map_offset])) { | ||
53 | void *src; | ||
54 | |||
55 | if (dma->bouncemap[map_offset] == NULL) | ||
56 | dma->bouncemap[map_offset] = alloc_page(GFP_KERNEL); | ||
57 | if (dma->bouncemap[map_offset] == NULL) | ||
58 | return -1; | ||
59 | local_irq_save(flags); | ||
60 | src = kmap_atomic(dma->map[map_offset], KM_BOUNCE_READ) + offset; | ||
61 | memcpy(page_address(dma->bouncemap[map_offset]) + offset, src, len); | ||
62 | kunmap_atomic(src, KM_BOUNCE_READ); | ||
63 | local_irq_restore(flags); | ||
64 | sg_set_page(&dma->SGlist[map_offset], dma->bouncemap[map_offset], len, offset); | ||
65 | } | ||
66 | else { | ||
67 | sg_set_page(&dma->SGlist[map_offset], dma->map[map_offset], len, offset); | ||
68 | } | ||
69 | offset = 0; | ||
70 | map_offset++; | ||
71 | } | ||
72 | return map_offset; | ||
73 | } | ||
74 | |||
75 | void ivtv_udma_fill_sg_array (struct ivtv_user_dma *dma, u32 buffer_offset, u32 buffer_offset_2, u32 split) { | ||
76 | int i; | ||
77 | struct scatterlist *sg; | ||
78 | |||
79 | for (i = 0, sg = dma->SGlist; i < dma->SG_length; i++, sg++) { | ||
80 | dma->SGarray[i].size = cpu_to_le32(sg_dma_len(sg)); | ||
81 | dma->SGarray[i].src = cpu_to_le32(sg_dma_address(sg)); | ||
82 | dma->SGarray[i].dst = cpu_to_le32(buffer_offset); | ||
83 | buffer_offset += sg_dma_len(sg); | ||
84 | |||
85 | split -= sg_dma_len(sg); | ||
86 | if (split == 0) | ||
87 | buffer_offset = buffer_offset_2; | ||
88 | } | ||
89 | } | ||
90 | |||
91 | /* User DMA Buffers */ | ||
92 | void ivtv_udma_alloc(struct ivtv *itv) | ||
93 | { | ||
94 | if (itv->udma.SG_handle == 0) { | ||
95 | /* Map DMA Page Array Buffer */ | ||
96 | itv->udma.SG_handle = pci_map_single(itv->pdev, itv->udma.SGarray, | ||
97 | sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE); | ||
98 | ivtv_udma_sync_for_cpu(itv); | ||
99 | } | ||
100 | } | ||
101 | |||
102 | int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr, | ||
103 | void __user *userbuf, int size_in_bytes) | ||
104 | { | ||
105 | struct ivtv_dma_page_info user_dma; | ||
106 | struct ivtv_user_dma *dma = &itv->udma; | ||
107 | int i, err; | ||
108 | |||
109 | IVTV_DEBUG_DMA("ivtv_udma_setup, dst: 0x%08x\n", (unsigned int)ivtv_dest_addr); | ||
110 | |||
111 | /* Still in USE */ | ||
112 | if (dma->SG_length || dma->page_count) { | ||
113 | IVTV_DEBUG_WARN("ivtv_udma_setup: SG_length %d page_count %d still full?\n", | ||
114 | dma->SG_length, dma->page_count); | ||
115 | return -EBUSY; | ||
116 | } | ||
117 | |||
118 | ivtv_udma_get_page_info(&user_dma, (unsigned long)userbuf, size_in_bytes); | ||
119 | |||
120 | if (user_dma.page_count <= 0) { | ||
121 | IVTV_DEBUG_WARN("ivtv_udma_setup: Error %d page_count from %d bytes %d offset\n", | ||
122 | user_dma.page_count, size_in_bytes, user_dma.offset); | ||
123 | return -EINVAL; | ||
124 | } | ||
125 | |||
126 | /* Get user pages for DMA Xfer */ | ||
127 | down_read(¤t->mm->mmap_sem); | ||
128 | err = get_user_pages(current, current->mm, | ||
129 | user_dma.uaddr, user_dma.page_count, 0, 1, dma->map, NULL); | ||
130 | up_read(¤t->mm->mmap_sem); | ||
131 | |||
132 | if (user_dma.page_count != err) { | ||
133 | IVTV_DEBUG_WARN("failed to map user pages, returned %d instead of %d\n", | ||
134 | err, user_dma.page_count); | ||
135 | if (err >= 0) { | ||
136 | for (i = 0; i < err; i++) | ||
137 | put_page(dma->map[i]); | ||
138 | return -EINVAL; | ||
139 | } | ||
140 | return err; | ||
141 | } | ||
142 | |||
143 | dma->page_count = user_dma.page_count; | ||
144 | |||
145 | /* Fill SG List with new values */ | ||
146 | if (ivtv_udma_fill_sg_list(dma, &user_dma, 0) < 0) { | ||
147 | for (i = 0; i < dma->page_count; i++) { | ||
148 | put_page(dma->map[i]); | ||
149 | } | ||
150 | dma->page_count = 0; | ||
151 | return -ENOMEM; | ||
152 | } | ||
153 | |||
154 | /* Map SG List */ | ||
155 | dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); | ||
156 | |||
157 | /* Fill SG Array with new values */ | ||
158 | ivtv_udma_fill_sg_array (dma, ivtv_dest_addr, 0, -1); | ||
159 | |||
160 | /* Tag SG Array with Interrupt Bit */ | ||
161 | dma->SGarray[dma->SG_length - 1].size |= cpu_to_le32(0x80000000); | ||
162 | |||
163 | ivtv_udma_sync_for_device(itv); | ||
164 | return dma->page_count; | ||
165 | } | ||
166 | |||
167 | void ivtv_udma_unmap(struct ivtv *itv) | ||
168 | { | ||
169 | struct ivtv_user_dma *dma = &itv->udma; | ||
170 | int i; | ||
171 | |||
172 | IVTV_DEBUG_INFO("ivtv_unmap_user_dma\n"); | ||
173 | |||
174 | /* Nothing to free */ | ||
175 | if (dma->page_count == 0) | ||
176 | return; | ||
177 | |||
178 | /* Unmap Scatterlist */ | ||
179 | if (dma->SG_length) { | ||
180 | pci_unmap_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); | ||
181 | dma->SG_length = 0; | ||
182 | } | ||
183 | /* sync DMA */ | ||
184 | ivtv_udma_sync_for_cpu(itv); | ||
185 | |||
186 | /* Release User Pages */ | ||
187 | for (i = 0; i < dma->page_count; i++) { | ||
188 | put_page(dma->map[i]); | ||
189 | } | ||
190 | dma->page_count = 0; | ||
191 | } | ||
192 | |||
193 | void ivtv_udma_free(struct ivtv *itv) | ||
194 | { | ||
195 | int i; | ||
196 | |||
197 | /* Unmap SG Array */ | ||
198 | if (itv->udma.SG_handle) { | ||
199 | pci_unmap_single(itv->pdev, itv->udma.SG_handle, | ||
200 | sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE); | ||
201 | } | ||
202 | |||
203 | /* Unmap Scatterlist */ | ||
204 | if (itv->udma.SG_length) { | ||
205 | pci_unmap_sg(itv->pdev, itv->udma.SGlist, itv->udma.page_count, PCI_DMA_TODEVICE); | ||
206 | } | ||
207 | |||
208 | for (i = 0; i < IVTV_DMA_SG_OSD_ENT; i++) { | ||
209 | if (itv->udma.bouncemap[i]) | ||
210 | __free_page(itv->udma.bouncemap[i]); | ||
211 | } | ||
212 | } | ||
213 | |||
214 | void ivtv_udma_start(struct ivtv *itv) | ||
215 | { | ||
216 | IVTV_DEBUG_DMA("start UDMA\n"); | ||
217 | write_reg(itv->udma.SG_handle, IVTV_REG_DECDMAADDR); | ||
218 | write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER); | ||
219 | set_bit(IVTV_F_I_DMA, &itv->i_flags); | ||
220 | set_bit(IVTV_F_I_UDMA, &itv->i_flags); | ||
221 | clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags); | ||
222 | } | ||
223 | |||
224 | void ivtv_udma_prepare(struct ivtv *itv) | ||
225 | { | ||
226 | unsigned long flags; | ||
227 | |||
228 | spin_lock_irqsave(&itv->dma_reg_lock, flags); | ||
229 | if (!test_bit(IVTV_F_I_DMA, &itv->i_flags)) | ||
230 | ivtv_udma_start(itv); | ||
231 | else | ||
232 | set_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags); | ||
233 | spin_unlock_irqrestore(&itv->dma_reg_lock, flags); | ||
234 | } | ||
diff --git a/drivers/media/video/ivtv/ivtv-udma.h b/drivers/media/video/ivtv/ivtv-udma.h new file mode 100644 index 00000000000..ee3c9efb5b7 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-udma.h | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> | ||
3 | Copyright (C) 2004 Chris Kennedy <c@groovy.org> | ||
4 | Copyright (C) 2006-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #ifndef IVTV_UDMA_H | ||
22 | #define IVTV_UDMA_H | ||
23 | |||
24 | /* User DMA functions */ | ||
25 | void ivtv_udma_get_page_info(struct ivtv_dma_page_info *dma_page, unsigned long first, unsigned long size); | ||
26 | int ivtv_udma_fill_sg_list(struct ivtv_user_dma *dma, struct ivtv_dma_page_info *dma_page, int map_offset); | ||
27 | void ivtv_udma_fill_sg_array(struct ivtv_user_dma *dma, u32 buffer_offset, u32 buffer_offset_2, u32 split); | ||
28 | int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr, | ||
29 | void __user *userbuf, int size_in_bytes); | ||
30 | void ivtv_udma_unmap(struct ivtv *itv); | ||
31 | void ivtv_udma_free(struct ivtv *itv); | ||
32 | void ivtv_udma_alloc(struct ivtv *itv); | ||
33 | void ivtv_udma_prepare(struct ivtv *itv); | ||
34 | void ivtv_udma_start(struct ivtv *itv); | ||
35 | |||
36 | static inline void ivtv_udma_sync_for_device(struct ivtv *itv) | ||
37 | { | ||
38 | pci_dma_sync_single_for_device(itv->pdev, itv->udma.SG_handle, | ||
39 | sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE); | ||
40 | } | ||
41 | |||
42 | static inline void ivtv_udma_sync_for_cpu(struct ivtv *itv) | ||
43 | { | ||
44 | pci_dma_sync_single_for_cpu(itv->pdev, itv->udma.SG_handle, | ||
45 | sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE); | ||
46 | } | ||
47 | |||
48 | #endif | ||
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c new file mode 100644 index 00000000000..293db806d93 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-vbi.c | |||
@@ -0,0 +1,549 @@ | |||
1 | /* | ||
2 | Vertical Blank Interval support functions | ||
3 | Copyright (C) 2004-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the Free Software | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | |||
20 | #include "ivtv-driver.h" | ||
21 | #include "ivtv-i2c.h" | ||
22 | #include "ivtv-ioctl.h" | ||
23 | #include "ivtv-queue.h" | ||
24 | #include "ivtv-cards.h" | ||
25 | #include "ivtv-vbi.h" | ||
26 | |||
27 | static void ivtv_set_vps(struct ivtv *itv, int enabled) | ||
28 | { | ||
29 | struct v4l2_sliced_vbi_data data; | ||
30 | |||
31 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
32 | return; | ||
33 | data.id = V4L2_SLICED_VPS; | ||
34 | data.field = 0; | ||
35 | data.line = enabled ? 16 : 0; | ||
36 | data.data[2] = itv->vbi.vps_payload.data[0]; | ||
37 | data.data[8] = itv->vbi.vps_payload.data[1]; | ||
38 | data.data[9] = itv->vbi.vps_payload.data[2]; | ||
39 | data.data[10] = itv->vbi.vps_payload.data[3]; | ||
40 | data.data[11] = itv->vbi.vps_payload.data[4]; | ||
41 | ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data); | ||
42 | } | ||
43 | |||
44 | static void ivtv_set_cc(struct ivtv *itv, int mode, const struct vbi_cc *cc) | ||
45 | { | ||
46 | struct v4l2_sliced_vbi_data data; | ||
47 | |||
48 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
49 | return; | ||
50 | data.id = V4L2_SLICED_CAPTION_525; | ||
51 | data.field = 0; | ||
52 | data.line = (mode & 1) ? 21 : 0; | ||
53 | data.data[0] = cc->odd[0]; | ||
54 | data.data[1] = cc->odd[1]; | ||
55 | ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data); | ||
56 | data.field = 1; | ||
57 | data.line = (mode & 2) ? 21 : 0; | ||
58 | data.data[0] = cc->even[0]; | ||
59 | data.data[1] = cc->even[1]; | ||
60 | ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data); | ||
61 | } | ||
62 | |||
63 | static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode) | ||
64 | { | ||
65 | struct v4l2_sliced_vbi_data data; | ||
66 | |||
67 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
68 | return; | ||
69 | /* When using a 50 Hz system, always turn on the | ||
70 | wide screen signal with 4x3 ratio as the default. | ||
71 | Turning this signal on and off can confuse certain | ||
72 | TVs. As far as I can tell there is no reason not to | ||
73 | transmit this signal. */ | ||
74 | if ((itv->std_out & V4L2_STD_625_50) && !enabled) { | ||
75 | enabled = 1; | ||
76 | mode = 0x08; /* 4x3 full format */ | ||
77 | } | ||
78 | data.id = V4L2_SLICED_WSS_625; | ||
79 | data.field = 0; | ||
80 | data.line = enabled ? 23 : 0; | ||
81 | data.data[0] = mode & 0xff; | ||
82 | data.data[1] = (mode >> 8) & 0xff; | ||
83 | ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data); | ||
84 | } | ||
85 | |||
86 | static int odd_parity(u8 c) | ||
87 | { | ||
88 | c ^= (c >> 4); | ||
89 | c ^= (c >> 2); | ||
90 | c ^= (c >> 1); | ||
91 | |||
92 | return c & 1; | ||
93 | } | ||
94 | |||
95 | static void ivtv_write_vbi_line(struct ivtv *itv, | ||
96 | const struct v4l2_sliced_vbi_data *d, | ||
97 | struct vbi_cc *cc, int *found_cc) | ||
98 | { | ||
99 | struct vbi_info *vi = &itv->vbi; | ||
100 | |||
101 | if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) { | ||
102 | if (d->field) { | ||
103 | cc->even[0] = d->data[0]; | ||
104 | cc->even[1] = d->data[1]; | ||
105 | } else { | ||
106 | cc->odd[0] = d->data[0]; | ||
107 | cc->odd[1] = d->data[1]; | ||
108 | } | ||
109 | *found_cc = 1; | ||
110 | } else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) { | ||
111 | struct vbi_vps vps; | ||
112 | |||
113 | vps.data[0] = d->data[2]; | ||
114 | vps.data[1] = d->data[8]; | ||
115 | vps.data[2] = d->data[9]; | ||
116 | vps.data[3] = d->data[10]; | ||
117 | vps.data[4] = d->data[11]; | ||
118 | if (memcmp(&vps, &vi->vps_payload, sizeof(vps))) { | ||
119 | vi->vps_payload = vps; | ||
120 | set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags); | ||
121 | } | ||
122 | } else if (d->id == V4L2_SLICED_WSS_625 && | ||
123 | d->line == 23 && d->field == 0) { | ||
124 | int wss = d->data[0] | d->data[1] << 8; | ||
125 | |||
126 | if (vi->wss_payload != wss) { | ||
127 | vi->wss_payload = wss; | ||
128 | set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags); | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | |||
133 | static void ivtv_write_vbi_cc_lines(struct ivtv *itv, const struct vbi_cc *cc) | ||
134 | { | ||
135 | struct vbi_info *vi = &itv->vbi; | ||
136 | |||
137 | if (vi->cc_payload_idx < ARRAY_SIZE(vi->cc_payload)) { | ||
138 | memcpy(&vi->cc_payload[vi->cc_payload_idx], cc, | ||
139 | sizeof(struct vbi_cc)); | ||
140 | vi->cc_payload_idx++; | ||
141 | set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | static void ivtv_write_vbi(struct ivtv *itv, | ||
146 | const struct v4l2_sliced_vbi_data *sliced, | ||
147 | size_t cnt) | ||
148 | { | ||
149 | struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } }; | ||
150 | int found_cc = 0; | ||
151 | size_t i; | ||
152 | |||
153 | for (i = 0; i < cnt; i++) | ||
154 | ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc); | ||
155 | |||
156 | if (found_cc) | ||
157 | ivtv_write_vbi_cc_lines(itv, &cc); | ||
158 | } | ||
159 | |||
160 | ssize_t | ||
161 | ivtv_write_vbi_from_user(struct ivtv *itv, | ||
162 | const struct v4l2_sliced_vbi_data __user *sliced, | ||
163 | size_t cnt) | ||
164 | { | ||
165 | struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } }; | ||
166 | int found_cc = 0; | ||
167 | size_t i; | ||
168 | struct v4l2_sliced_vbi_data d; | ||
169 | ssize_t ret = cnt * sizeof(struct v4l2_sliced_vbi_data); | ||
170 | |||
171 | for (i = 0; i < cnt; i++) { | ||
172 | if (copy_from_user(&d, sliced + i, | ||
173 | sizeof(struct v4l2_sliced_vbi_data))) { | ||
174 | ret = -EFAULT; | ||
175 | break; | ||
176 | } | ||
177 | ivtv_write_vbi_line(itv, &d, &cc, &found_cc); | ||
178 | } | ||
179 | |||
180 | if (found_cc) | ||
181 | ivtv_write_vbi_cc_lines(itv, &cc); | ||
182 | |||
183 | return ret; | ||
184 | } | ||
185 | |||
186 | static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp) | ||
187 | { | ||
188 | int line = 0; | ||
189 | int i; | ||
190 | u32 linemask[2] = { 0, 0 }; | ||
191 | unsigned short size; | ||
192 | static const u8 mpeg_hdr_data[] = { | ||
193 | 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66, | ||
194 | 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff, | ||
195 | 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80, | ||
196 | 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff | ||
197 | }; | ||
198 | const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */ | ||
199 | int idx = itv->vbi.frame % IVTV_VBI_FRAMES; | ||
200 | u8 *dst = &itv->vbi.sliced_mpeg_data[idx][0]; | ||
201 | |||
202 | for (i = 0; i < lines; i++) { | ||
203 | int f, l; | ||
204 | |||
205 | if (itv->vbi.sliced_data[i].id == 0) | ||
206 | continue; | ||
207 | |||
208 | l = itv->vbi.sliced_data[i].line - 6; | ||
209 | f = itv->vbi.sliced_data[i].field; | ||
210 | if (f) | ||
211 | l += 18; | ||
212 | if (l < 32) | ||
213 | linemask[0] |= (1 << l); | ||
214 | else | ||
215 | linemask[1] |= (1 << (l - 32)); | ||
216 | dst[sd + 12 + line * 43] = | ||
217 | ivtv_service2vbi(itv->vbi.sliced_data[i].id); | ||
218 | memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42); | ||
219 | line++; | ||
220 | } | ||
221 | memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data)); | ||
222 | if (line == 36) { | ||
223 | /* All lines are used, so there is no space for the linemask | ||
224 | (the max size of the VBI data is 36 * 43 + 4 bytes). | ||
225 | So in this case we use the magic number 'ITV0'. */ | ||
226 | memcpy(dst + sd, "ITV0", 4); | ||
227 | memcpy(dst + sd + 4, dst + sd + 12, line * 43); | ||
228 | size = 4 + ((43 * line + 3) & ~3); | ||
229 | } else { | ||
230 | memcpy(dst + sd, "itv0", 4); | ||
231 | cpu_to_le32s(&linemask[0]); | ||
232 | cpu_to_le32s(&linemask[1]); | ||
233 | memcpy(dst + sd + 4, &linemask[0], 8); | ||
234 | size = 12 + ((43 * line + 3) & ~3); | ||
235 | } | ||
236 | dst[4+16] = (size + 10) >> 8; | ||
237 | dst[5+16] = (size + 10) & 0xff; | ||
238 | dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6); | ||
239 | dst[10+16] = (pts_stamp >> 22) & 0xff; | ||
240 | dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff); | ||
241 | dst[12+16] = (pts_stamp >> 7) & 0xff; | ||
242 | dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1); | ||
243 | itv->vbi.sliced_mpeg_size[idx] = sd + size; | ||
244 | } | ||
245 | |||
246 | static int ivtv_convert_ivtv_vbi(struct ivtv *itv, u8 *p) | ||
247 | { | ||
248 | u32 linemask[2]; | ||
249 | int i, l, id2; | ||
250 | int line = 0; | ||
251 | |||
252 | if (!memcmp(p, "itv0", 4)) { | ||
253 | memcpy(linemask, p + 4, 8); | ||
254 | p += 12; | ||
255 | } else if (!memcmp(p, "ITV0", 4)) { | ||
256 | linemask[0] = 0xffffffff; | ||
257 | linemask[1] = 0xf; | ||
258 | p += 4; | ||
259 | } else { | ||
260 | /* unknown VBI data, convert to empty VBI frame */ | ||
261 | linemask[0] = linemask[1] = 0; | ||
262 | } | ||
263 | for (i = 0; i < 36; i++) { | ||
264 | int err = 0; | ||
265 | |||
266 | if (i < 32 && !(linemask[0] & (1 << i))) | ||
267 | continue; | ||
268 | if (i >= 32 && !(linemask[1] & (1 << (i - 32)))) | ||
269 | continue; | ||
270 | id2 = *p & 0xf; | ||
271 | switch (id2) { | ||
272 | case IVTV_SLICED_TYPE_TELETEXT_B: | ||
273 | id2 = V4L2_SLICED_TELETEXT_B; | ||
274 | break; | ||
275 | case IVTV_SLICED_TYPE_CAPTION_525: | ||
276 | id2 = V4L2_SLICED_CAPTION_525; | ||
277 | err = !odd_parity(p[1]) || !odd_parity(p[2]); | ||
278 | break; | ||
279 | case IVTV_SLICED_TYPE_VPS: | ||
280 | id2 = V4L2_SLICED_VPS; | ||
281 | break; | ||
282 | case IVTV_SLICED_TYPE_WSS_625: | ||
283 | id2 = V4L2_SLICED_WSS_625; | ||
284 | break; | ||
285 | default: | ||
286 | id2 = 0; | ||
287 | break; | ||
288 | } | ||
289 | if (err == 0) { | ||
290 | l = (i < 18) ? i + 6 : i - 18 + 6; | ||
291 | itv->vbi.sliced_dec_data[line].line = l; | ||
292 | itv->vbi.sliced_dec_data[line].field = i >= 18; | ||
293 | itv->vbi.sliced_dec_data[line].id = id2; | ||
294 | memcpy(itv->vbi.sliced_dec_data[line].data, p + 1, 42); | ||
295 | line++; | ||
296 | } | ||
297 | p += 43; | ||
298 | } | ||
299 | while (line < 36) { | ||
300 | itv->vbi.sliced_dec_data[line].id = 0; | ||
301 | itv->vbi.sliced_dec_data[line].line = 0; | ||
302 | itv->vbi.sliced_dec_data[line].field = 0; | ||
303 | line++; | ||
304 | } | ||
305 | return line * sizeof(itv->vbi.sliced_dec_data[0]); | ||
306 | } | ||
307 | |||
308 | /* Compress raw VBI format, removes leading SAV codes and surplus space after the | ||
309 | field. | ||
310 | Returns new compressed size. */ | ||
311 | static u32 compress_raw_buf(struct ivtv *itv, u8 *buf, u32 size) | ||
312 | { | ||
313 | u32 line_size = itv->vbi.raw_decoder_line_size; | ||
314 | u32 lines = itv->vbi.count; | ||
315 | u8 sav1 = itv->vbi.raw_decoder_sav_odd_field; | ||
316 | u8 sav2 = itv->vbi.raw_decoder_sav_even_field; | ||
317 | u8 *q = buf; | ||
318 | u8 *p; | ||
319 | int i; | ||
320 | |||
321 | for (i = 0; i < lines; i++) { | ||
322 | p = buf + i * line_size; | ||
323 | |||
324 | /* Look for SAV code */ | ||
325 | if (p[0] != 0xff || p[1] || p[2] || (p[3] != sav1 && p[3] != sav2)) { | ||
326 | break; | ||
327 | } | ||
328 | memcpy(q, p + 4, line_size - 4); | ||
329 | q += line_size - 4; | ||
330 | } | ||
331 | return lines * (line_size - 4); | ||
332 | } | ||
333 | |||
334 | |||
335 | /* Compressed VBI format, all found sliced blocks put next to one another | ||
336 | Returns new compressed size */ | ||
337 | static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8 sav) | ||
338 | { | ||
339 | u32 line_size = itv->vbi.sliced_decoder_line_size; | ||
340 | struct v4l2_decode_vbi_line vbi; | ||
341 | int i; | ||
342 | unsigned lines = 0; | ||
343 | |||
344 | /* find the first valid line */ | ||
345 | for (i = 0; i < size; i++, buf++) { | ||
346 | if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav) | ||
347 | break; | ||
348 | } | ||
349 | |||
350 | size -= i; | ||
351 | if (size < line_size) { | ||
352 | return line; | ||
353 | } | ||
354 | for (i = 0; i < size / line_size; i++) { | ||
355 | u8 *p = buf + i * line_size; | ||
356 | |||
357 | /* Look for SAV code */ | ||
358 | if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) { | ||
359 | continue; | ||
360 | } | ||
361 | vbi.p = p + 4; | ||
362 | v4l2_subdev_call(itv->sd_video, vbi, decode_vbi_line, &vbi); | ||
363 | if (vbi.type && !(lines & (1 << vbi.line))) { | ||
364 | lines |= 1 << vbi.line; | ||
365 | itv->vbi.sliced_data[line].id = vbi.type; | ||
366 | itv->vbi.sliced_data[line].field = vbi.is_second_field; | ||
367 | itv->vbi.sliced_data[line].line = vbi.line; | ||
368 | memcpy(itv->vbi.sliced_data[line].data, vbi.p, 42); | ||
369 | line++; | ||
370 | } | ||
371 | } | ||
372 | return line; | ||
373 | } | ||
374 | |||
375 | void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf, | ||
376 | u64 pts_stamp, int streamtype) | ||
377 | { | ||
378 | u8 *p = (u8 *) buf->buf; | ||
379 | u32 size = buf->bytesused; | ||
380 | int y; | ||
381 | |||
382 | /* Raw VBI data */ | ||
383 | if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && ivtv_raw_vbi(itv)) { | ||
384 | u8 type; | ||
385 | |||
386 | ivtv_buf_swap(buf); | ||
387 | |||
388 | type = p[3]; | ||
389 | |||
390 | size = buf->bytesused = compress_raw_buf(itv, p, size); | ||
391 | |||
392 | /* second field of the frame? */ | ||
393 | if (type == itv->vbi.raw_decoder_sav_even_field) { | ||
394 | /* Dirty hack needed for backwards | ||
395 | compatibility of old VBI software. */ | ||
396 | p += size - 4; | ||
397 | memcpy(p, &itv->vbi.frame, 4); | ||
398 | itv->vbi.frame++; | ||
399 | } | ||
400 | return; | ||
401 | } | ||
402 | |||
403 | /* Sliced VBI data with data insertion */ | ||
404 | if (streamtype == IVTV_ENC_STREAM_TYPE_VBI) { | ||
405 | int lines; | ||
406 | |||
407 | ivtv_buf_swap(buf); | ||
408 | |||
409 | /* first field */ | ||
410 | lines = compress_sliced_buf(itv, 0, p, size / 2, | ||
411 | itv->vbi.sliced_decoder_sav_odd_field); | ||
412 | /* second field */ | ||
413 | /* experimentation shows that the second half does not always begin | ||
414 | at the exact address. So start a bit earlier (hence 32). */ | ||
415 | lines = compress_sliced_buf(itv, lines, p + size / 2 - 32, size / 2 + 32, | ||
416 | itv->vbi.sliced_decoder_sav_even_field); | ||
417 | /* always return at least one empty line */ | ||
418 | if (lines == 0) { | ||
419 | itv->vbi.sliced_data[0].id = 0; | ||
420 | itv->vbi.sliced_data[0].line = 0; | ||
421 | itv->vbi.sliced_data[0].field = 0; | ||
422 | lines = 1; | ||
423 | } | ||
424 | buf->bytesused = size = lines * sizeof(itv->vbi.sliced_data[0]); | ||
425 | memcpy(p, &itv->vbi.sliced_data[0], size); | ||
426 | |||
427 | if (itv->vbi.insert_mpeg) { | ||
428 | copy_vbi_data(itv, lines, pts_stamp); | ||
429 | } | ||
430 | itv->vbi.frame++; | ||
431 | return; | ||
432 | } | ||
433 | |||
434 | /* Sliced VBI re-inserted from an MPEG stream */ | ||
435 | if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) { | ||
436 | /* If the size is not 4-byte aligned, then the starting address | ||
437 | for the swapping is also shifted. After swapping the data the | ||
438 | real start address of the VBI data is exactly 4 bytes after the | ||
439 | original start. It's a bit fiddly but it works like a charm. | ||
440 | Non-4-byte alignment happens when an lseek is done on the input | ||
441 | mpeg file to a non-4-byte aligned position. So on arrival here | ||
442 | the VBI data is also non-4-byte aligned. */ | ||
443 | int offset = size & 3; | ||
444 | int cnt; | ||
445 | |||
446 | if (offset) { | ||
447 | p += 4 - offset; | ||
448 | } | ||
449 | /* Swap Buffer */ | ||
450 | for (y = 0; y < size; y += 4) { | ||
451 | swab32s((u32 *)(p + y)); | ||
452 | } | ||
453 | |||
454 | cnt = ivtv_convert_ivtv_vbi(itv, p + offset); | ||
455 | memcpy(buf->buf, itv->vbi.sliced_dec_data, cnt); | ||
456 | buf->bytesused = cnt; | ||
457 | |||
458 | ivtv_write_vbi(itv, itv->vbi.sliced_dec_data, | ||
459 | cnt / sizeof(itv->vbi.sliced_dec_data[0])); | ||
460 | return; | ||
461 | } | ||
462 | } | ||
463 | |||
464 | void ivtv_disable_cc(struct ivtv *itv) | ||
465 | { | ||
466 | struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } }; | ||
467 | |||
468 | clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags); | ||
469 | ivtv_set_cc(itv, 0, &cc); | ||
470 | itv->vbi.cc_payload_idx = 0; | ||
471 | } | ||
472 | |||
473 | |||
474 | void ivtv_vbi_work_handler(struct ivtv *itv) | ||
475 | { | ||
476 | struct vbi_info *vi = &itv->vbi; | ||
477 | struct v4l2_sliced_vbi_data data; | ||
478 | struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } }; | ||
479 | |||
480 | /* Lock */ | ||
481 | if (itv->output_mode == OUT_PASSTHROUGH) { | ||
482 | if (itv->is_50hz) { | ||
483 | data.id = V4L2_SLICED_WSS_625; | ||
484 | data.field = 0; | ||
485 | |||
486 | if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) { | ||
487 | ivtv_set_wss(itv, 1, data.data[0] & 0xf); | ||
488 | vi->wss_missing_cnt = 0; | ||
489 | } else if (vi->wss_missing_cnt == 4) { | ||
490 | ivtv_set_wss(itv, 1, 0x8); /* 4x3 full format */ | ||
491 | } else { | ||
492 | vi->wss_missing_cnt++; | ||
493 | } | ||
494 | } | ||
495 | else { | ||
496 | int mode = 0; | ||
497 | |||
498 | data.id = V4L2_SLICED_CAPTION_525; | ||
499 | data.field = 0; | ||
500 | if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) { | ||
501 | mode |= 1; | ||
502 | cc.odd[0] = data.data[0]; | ||
503 | cc.odd[1] = data.data[1]; | ||
504 | } | ||
505 | data.field = 1; | ||
506 | if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) { | ||
507 | mode |= 2; | ||
508 | cc.even[0] = data.data[0]; | ||
509 | cc.even[1] = data.data[1]; | ||
510 | } | ||
511 | if (mode) { | ||
512 | vi->cc_missing_cnt = 0; | ||
513 | ivtv_set_cc(itv, mode, &cc); | ||
514 | } else if (vi->cc_missing_cnt == 4) { | ||
515 | ivtv_set_cc(itv, 0, &cc); | ||
516 | } else { | ||
517 | vi->cc_missing_cnt++; | ||
518 | } | ||
519 | } | ||
520 | return; | ||
521 | } | ||
522 | |||
523 | if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) { | ||
524 | ivtv_set_wss(itv, 1, vi->wss_payload & 0xf); | ||
525 | } | ||
526 | |||
527 | if (test_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags)) { | ||
528 | if (vi->cc_payload_idx == 0) { | ||
529 | clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags); | ||
530 | ivtv_set_cc(itv, 3, &cc); | ||
531 | } | ||
532 | while (vi->cc_payload_idx) { | ||
533 | cc = vi->cc_payload[0]; | ||
534 | |||
535 | memcpy(vi->cc_payload, vi->cc_payload + 1, | ||
536 | sizeof(vi->cc_payload) - sizeof(vi->cc_payload[0])); | ||
537 | vi->cc_payload_idx--; | ||
538 | if (vi->cc_payload_idx && cc.odd[0] == 0x80 && cc.odd[1] == 0x80) | ||
539 | continue; | ||
540 | |||
541 | ivtv_set_cc(itv, 3, &cc); | ||
542 | break; | ||
543 | } | ||
544 | } | ||
545 | |||
546 | if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) { | ||
547 | ivtv_set_vps(itv, 1); | ||
548 | } | ||
549 | } | ||
diff --git a/drivers/media/video/ivtv/ivtv-vbi.h b/drivers/media/video/ivtv/ivtv-vbi.h new file mode 100644 index 00000000000..166dd0b75d0 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-vbi.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | Vertical Blank Interval support functions | ||
3 | Copyright (C) 2004-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the Free Software | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | |||
20 | #ifndef IVTV_VBI_H | ||
21 | #define IVTV_VBI_H | ||
22 | |||
23 | ssize_t | ||
24 | ivtv_write_vbi_from_user(struct ivtv *itv, | ||
25 | const struct v4l2_sliced_vbi_data __user *sliced, | ||
26 | size_t count); | ||
27 | void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf, | ||
28 | u64 pts_stamp, int streamtype); | ||
29 | int ivtv_used_line(struct ivtv *itv, int line, int field); | ||
30 | void ivtv_disable_cc(struct ivtv *itv); | ||
31 | void ivtv_set_vbi(unsigned long arg); | ||
32 | void ivtv_vbi_work_handler(struct ivtv *itv); | ||
33 | |||
34 | #endif | ||
diff --git a/drivers/media/video/ivtv/ivtv-version.h b/drivers/media/video/ivtv/ivtv-version.h new file mode 100644 index 00000000000..a20f346fcad --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-version.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | ivtv driver version information | ||
3 | Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the Free Software | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | |||
20 | #ifndef IVTV_VERSION_H | ||
21 | #define IVTV_VERSION_H | ||
22 | |||
23 | #define IVTV_DRIVER_NAME "ivtv" | ||
24 | #define IVTV_VERSION "1.4.3" | ||
25 | |||
26 | #endif | ||
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c new file mode 100644 index 00000000000..dcbab6ad4c2 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-yuv.c | |||
@@ -0,0 +1,1280 @@ | |||
1 | /* | ||
2 | yuv support | ||
3 | |||
4 | Copyright (C) 2007 Ian Armstrong <ian@iarmst.demon.co.uk> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include "ivtv-driver.h" | ||
22 | #include "ivtv-udma.h" | ||
23 | #include "ivtv-yuv.h" | ||
24 | |||
25 | /* YUV buffer offsets */ | ||
26 | const u32 yuv_offset[IVTV_YUV_BUFFERS] = { | ||
27 | 0x001a8600, | ||
28 | 0x00240400, | ||
29 | 0x002d8200, | ||
30 | 0x00370000, | ||
31 | 0x00029000, | ||
32 | 0x000C0E00, | ||
33 | 0x006B0400, | ||
34 | 0x00748200 | ||
35 | }; | ||
36 | |||
37 | static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma, | ||
38 | struct ivtv_dma_frame *args) | ||
39 | { | ||
40 | struct ivtv_dma_page_info y_dma; | ||
41 | struct ivtv_dma_page_info uv_dma; | ||
42 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
43 | u8 frame = yi->draw_frame; | ||
44 | struct yuv_frame_info *f = &yi->new_frame_info[frame]; | ||
45 | int i; | ||
46 | int y_pages, uv_pages; | ||
47 | unsigned long y_buffer_offset, uv_buffer_offset; | ||
48 | int y_decode_height, uv_decode_height, y_size; | ||
49 | |||
50 | y_buffer_offset = IVTV_DECODER_OFFSET + yuv_offset[frame]; | ||
51 | uv_buffer_offset = y_buffer_offset + IVTV_YUV_BUFFER_UV_OFFSET; | ||
52 | |||
53 | y_decode_height = uv_decode_height = f->src_h + f->src_y; | ||
54 | |||
55 | if (f->offset_y) | ||
56 | y_buffer_offset += 720 * 16; | ||
57 | |||
58 | if (y_decode_height & 15) | ||
59 | y_decode_height = (y_decode_height + 16) & ~15; | ||
60 | |||
61 | if (uv_decode_height & 31) | ||
62 | uv_decode_height = (uv_decode_height + 32) & ~31; | ||
63 | |||
64 | y_size = 720 * y_decode_height; | ||
65 | |||
66 | /* Still in USE */ | ||
67 | if (dma->SG_length || dma->page_count) { | ||
68 | IVTV_DEBUG_WARN | ||
69 | ("prep_user_dma: SG_length %d page_count %d still full?\n", | ||
70 | dma->SG_length, dma->page_count); | ||
71 | return -EBUSY; | ||
72 | } | ||
73 | |||
74 | ivtv_udma_get_page_info (&y_dma, (unsigned long)args->y_source, 720 * y_decode_height); | ||
75 | ivtv_udma_get_page_info (&uv_dma, (unsigned long)args->uv_source, 360 * uv_decode_height); | ||
76 | |||
77 | /* Get user pages for DMA Xfer */ | ||
78 | down_read(¤t->mm->mmap_sem); | ||
79 | y_pages = get_user_pages(current, current->mm, y_dma.uaddr, y_dma.page_count, 0, 1, &dma->map[0], NULL); | ||
80 | uv_pages = 0; /* silence gcc. value is set and consumed only if: */ | ||
81 | if (y_pages == y_dma.page_count) { | ||
82 | uv_pages = get_user_pages(current, current->mm, | ||
83 | uv_dma.uaddr, uv_dma.page_count, 0, 1, | ||
84 | &dma->map[y_pages], NULL); | ||
85 | } | ||
86 | up_read(¤t->mm->mmap_sem); | ||
87 | |||
88 | if (y_pages != y_dma.page_count || uv_pages != uv_dma.page_count) { | ||
89 | int rc = -EFAULT; | ||
90 | |||
91 | if (y_pages == y_dma.page_count) { | ||
92 | IVTV_DEBUG_WARN | ||
93 | ("failed to map uv user pages, returned %d " | ||
94 | "expecting %d\n", uv_pages, uv_dma.page_count); | ||
95 | |||
96 | if (uv_pages >= 0) { | ||
97 | for (i = 0; i < uv_pages; i++) | ||
98 | put_page(dma->map[y_pages + i]); | ||
99 | rc = -EFAULT; | ||
100 | } else { | ||
101 | rc = uv_pages; | ||
102 | } | ||
103 | } else { | ||
104 | IVTV_DEBUG_WARN | ||
105 | ("failed to map y user pages, returned %d " | ||
106 | "expecting %d\n", y_pages, y_dma.page_count); | ||
107 | } | ||
108 | if (y_pages >= 0) { | ||
109 | for (i = 0; i < y_pages; i++) | ||
110 | put_page(dma->map[i]); | ||
111 | /* | ||
112 | * Inherit the -EFAULT from rc's | ||
113 | * initialization, but allow it to be | ||
114 | * overriden by uv_pages above if it was an | ||
115 | * actual errno. | ||
116 | */ | ||
117 | } else { | ||
118 | rc = y_pages; | ||
119 | } | ||
120 | return rc; | ||
121 | } | ||
122 | |||
123 | dma->page_count = y_pages + uv_pages; | ||
124 | |||
125 | /* Fill & map SG List */ | ||
126 | if (ivtv_udma_fill_sg_list (dma, &uv_dma, ivtv_udma_fill_sg_list (dma, &y_dma, 0)) < 0) { | ||
127 | IVTV_DEBUG_WARN("could not allocate bounce buffers for highmem userspace buffers\n"); | ||
128 | for (i = 0; i < dma->page_count; i++) { | ||
129 | put_page(dma->map[i]); | ||
130 | } | ||
131 | dma->page_count = 0; | ||
132 | return -ENOMEM; | ||
133 | } | ||
134 | dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); | ||
135 | |||
136 | /* Fill SG Array with new values */ | ||
137 | ivtv_udma_fill_sg_array(dma, y_buffer_offset, uv_buffer_offset, y_size); | ||
138 | |||
139 | /* If we've offset the y plane, ensure top area is blanked */ | ||
140 | if (f->offset_y && yi->blanking_dmaptr) { | ||
141 | dma->SGarray[dma->SG_length].size = cpu_to_le32(720*16); | ||
142 | dma->SGarray[dma->SG_length].src = cpu_to_le32(yi->blanking_dmaptr); | ||
143 | dma->SGarray[dma->SG_length].dst = cpu_to_le32(IVTV_DECODER_OFFSET + yuv_offset[frame]); | ||
144 | dma->SG_length++; | ||
145 | } | ||
146 | |||
147 | /* Tag SG Array with Interrupt Bit */ | ||
148 | dma->SGarray[dma->SG_length - 1].size |= cpu_to_le32(0x80000000); | ||
149 | |||
150 | ivtv_udma_sync_for_device(itv); | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | /* We rely on a table held in the firmware - Quick check. */ | ||
155 | int ivtv_yuv_filter_check(struct ivtv *itv) | ||
156 | { | ||
157 | int i, y, uv; | ||
158 | |||
159 | for (i = 0, y = 16, uv = 4; i < 16; i++, y += 24, uv += 12) { | ||
160 | if ((read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + y) != i << 16) || | ||
161 | (read_dec(IVTV_YUV_VERTICAL_FILTER_OFFSET + uv) != i << 16)) { | ||
162 | IVTV_WARN ("YUV filter table not found in firmware.\n"); | ||
163 | return -1; | ||
164 | } | ||
165 | } | ||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static void ivtv_yuv_filter(struct ivtv *itv, int h_filter, int v_filter_1, int v_filter_2) | ||
170 | { | ||
171 | u32 i, line; | ||
172 | |||
173 | /* If any filter is -1, then don't update it */ | ||
174 | if (h_filter > -1) { | ||
175 | if (h_filter > 4) | ||
176 | h_filter = 4; | ||
177 | i = IVTV_YUV_HORIZONTAL_FILTER_OFFSET + (h_filter * 384); | ||
178 | for (line = 0; line < 16; line++) { | ||
179 | write_reg(read_dec(i), 0x02804); | ||
180 | write_reg(read_dec(i), 0x0281c); | ||
181 | i += 4; | ||
182 | write_reg(read_dec(i), 0x02808); | ||
183 | write_reg(read_dec(i), 0x02820); | ||
184 | i += 4; | ||
185 | write_reg(read_dec(i), 0x0280c); | ||
186 | write_reg(read_dec(i), 0x02824); | ||
187 | i += 4; | ||
188 | write_reg(read_dec(i), 0x02810); | ||
189 | write_reg(read_dec(i), 0x02828); | ||
190 | i += 4; | ||
191 | write_reg(read_dec(i), 0x02814); | ||
192 | write_reg(read_dec(i), 0x0282c); | ||
193 | i += 8; | ||
194 | write_reg(0, 0x02818); | ||
195 | write_reg(0, 0x02830); | ||
196 | } | ||
197 | IVTV_DEBUG_YUV("h_filter -> %d\n", h_filter); | ||
198 | } | ||
199 | |||
200 | if (v_filter_1 > -1) { | ||
201 | if (v_filter_1 > 4) | ||
202 | v_filter_1 = 4; | ||
203 | i = IVTV_YUV_VERTICAL_FILTER_OFFSET + (v_filter_1 * 192); | ||
204 | for (line = 0; line < 16; line++) { | ||
205 | write_reg(read_dec(i), 0x02900); | ||
206 | i += 4; | ||
207 | write_reg(read_dec(i), 0x02904); | ||
208 | i += 8; | ||
209 | write_reg(0, 0x02908); | ||
210 | } | ||
211 | IVTV_DEBUG_YUV("v_filter_1 -> %d\n", v_filter_1); | ||
212 | } | ||
213 | |||
214 | if (v_filter_2 > -1) { | ||
215 | if (v_filter_2 > 4) | ||
216 | v_filter_2 = 4; | ||
217 | i = IVTV_YUV_VERTICAL_FILTER_OFFSET + (v_filter_2 * 192); | ||
218 | for (line = 0; line < 16; line++) { | ||
219 | write_reg(read_dec(i), 0x0290c); | ||
220 | i += 4; | ||
221 | write_reg(read_dec(i), 0x02910); | ||
222 | i += 8; | ||
223 | write_reg(0, 0x02914); | ||
224 | } | ||
225 | IVTV_DEBUG_YUV("v_filter_2 -> %d\n", v_filter_2); | ||
226 | } | ||
227 | } | ||
228 | |||
229 | static void ivtv_yuv_handle_horizontal(struct ivtv *itv, struct yuv_frame_info *f) | ||
230 | { | ||
231 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
232 | u32 reg_2834, reg_2838, reg_283c; | ||
233 | u32 reg_2844, reg_2854, reg_285c; | ||
234 | u32 reg_2864, reg_2874, reg_2890; | ||
235 | u32 reg_2870, reg_2870_base, reg_2870_offset; | ||
236 | int x_cutoff; | ||
237 | int h_filter; | ||
238 | u32 master_width; | ||
239 | |||
240 | IVTV_DEBUG_WARN | ||
241 | ("Adjust to width %d src_w %d dst_w %d src_x %d dst_x %d\n", | ||
242 | f->tru_w, f->src_w, f->dst_w, f->src_x, f->dst_x); | ||
243 | |||
244 | /* How wide is the src image */ | ||
245 | x_cutoff = f->src_w + f->src_x; | ||
246 | |||
247 | /* Set the display width */ | ||
248 | reg_2834 = f->dst_w; | ||
249 | reg_2838 = reg_2834; | ||
250 | |||
251 | /* Set the display position */ | ||
252 | reg_2890 = f->dst_x; | ||
253 | |||
254 | /* Index into the image horizontally */ | ||
255 | reg_2870 = 0; | ||
256 | |||
257 | /* 2870 is normally fudged to align video coords with osd coords. | ||
258 | If running full screen, it causes an unwanted left shift | ||
259 | Remove the fudge if we almost fill the screen. | ||
260 | Gradually adjust the offset to avoid the video 'snapping' | ||
261 | left/right if it gets dragged through this region. | ||
262 | Only do this if osd is full width. */ | ||
263 | if (f->vis_w == 720) { | ||
264 | if ((f->tru_x - f->pan_x > -1) && (f->tru_x - f->pan_x <= 40) && (f->dst_w >= 680)) | ||
265 | reg_2870 = 10 - (f->tru_x - f->pan_x) / 4; | ||
266 | else if ((f->tru_x - f->pan_x < 0) && (f->tru_x - f->pan_x >= -20) && (f->dst_w >= 660)) | ||
267 | reg_2870 = (10 + (f->tru_x - f->pan_x) / 2); | ||
268 | |||
269 | if (f->dst_w >= f->src_w) | ||
270 | reg_2870 = reg_2870 << 16 | reg_2870; | ||
271 | else | ||
272 | reg_2870 = ((reg_2870 & ~1) << 15) | (reg_2870 & ~1); | ||
273 | } | ||
274 | |||
275 | if (f->dst_w < f->src_w) | ||
276 | reg_2870 = 0x000d000e - reg_2870; | ||
277 | else | ||
278 | reg_2870 = 0x0012000e - reg_2870; | ||
279 | |||
280 | /* We're also using 2870 to shift the image left (src_x & negative dst_x) */ | ||
281 | reg_2870_offset = (f->src_x * ((f->dst_w << 21) / f->src_w)) >> 19; | ||
282 | |||
283 | if (f->dst_w >= f->src_w) { | ||
284 | x_cutoff &= ~1; | ||
285 | master_width = (f->src_w * 0x00200000) / (f->dst_w); | ||
286 | if (master_width * f->dst_w != f->src_w * 0x00200000) | ||
287 | master_width++; | ||
288 | reg_2834 = (reg_2834 << 16) | x_cutoff; | ||
289 | reg_2838 = (reg_2838 << 16) | x_cutoff; | ||
290 | reg_283c = master_width >> 2; | ||
291 | reg_2844 = master_width >> 2; | ||
292 | reg_2854 = master_width; | ||
293 | reg_285c = master_width >> 1; | ||
294 | reg_2864 = master_width >> 1; | ||
295 | |||
296 | /* We also need to factor in the scaling | ||
297 | (src_w - dst_w) / (src_w / 4) */ | ||
298 | if (f->dst_w > f->src_w) | ||
299 | reg_2870_base = ((f->dst_w - f->src_w)<<16) / (f->src_w <<14); | ||
300 | else | ||
301 | reg_2870_base = 0; | ||
302 | |||
303 | reg_2870 += (((reg_2870_offset << 14) & 0xFFFF0000) | reg_2870_offset >> 2) + (reg_2870_base << 17 | reg_2870_base); | ||
304 | reg_2874 = 0; | ||
305 | } else if (f->dst_w < f->src_w / 2) { | ||
306 | master_width = (f->src_w * 0x00080000) / f->dst_w; | ||
307 | if (master_width * f->dst_w != f->src_w * 0x00080000) | ||
308 | master_width++; | ||
309 | reg_2834 = (reg_2834 << 16) | x_cutoff; | ||
310 | reg_2838 = (reg_2838 << 16) | x_cutoff; | ||
311 | reg_283c = master_width >> 2; | ||
312 | reg_2844 = master_width >> 1; | ||
313 | reg_2854 = master_width; | ||
314 | reg_285c = master_width >> 1; | ||
315 | reg_2864 = master_width >> 1; | ||
316 | reg_2870 += ((reg_2870_offset << 15) & 0xFFFF0000) | reg_2870_offset; | ||
317 | reg_2870 += (5 - (((f->src_w + f->src_w / 2) - 1) / f->dst_w)) << 16; | ||
318 | reg_2874 = 0x00000012; | ||
319 | } else { | ||
320 | master_width = (f->src_w * 0x00100000) / f->dst_w; | ||
321 | if (master_width * f->dst_w != f->src_w * 0x00100000) | ||
322 | master_width++; | ||
323 | reg_2834 = (reg_2834 << 16) | x_cutoff; | ||
324 | reg_2838 = (reg_2838 << 16) | x_cutoff; | ||
325 | reg_283c = master_width >> 2; | ||
326 | reg_2844 = master_width >> 1; | ||
327 | reg_2854 = master_width; | ||
328 | reg_285c = master_width >> 1; | ||
329 | reg_2864 = master_width >> 1; | ||
330 | reg_2870 += ((reg_2870_offset << 14) & 0xFFFF0000) | reg_2870_offset >> 1; | ||
331 | reg_2870 += (5 - (((f->src_w * 3) - 1) / f->dst_w)) << 16; | ||
332 | reg_2874 = 0x00000001; | ||
333 | } | ||
334 | |||
335 | /* Select the horizontal filter */ | ||
336 | if (f->src_w == f->dst_w) { | ||
337 | /* An exact size match uses filter 0 */ | ||
338 | h_filter = 0; | ||
339 | } else { | ||
340 | /* Figure out which filter to use */ | ||
341 | h_filter = ((f->src_w << 16) / f->dst_w) >> 15; | ||
342 | h_filter = (h_filter >> 1) + (h_filter & 1); | ||
343 | /* Only an exact size match can use filter 0 */ | ||
344 | h_filter += !h_filter; | ||
345 | } | ||
346 | |||
347 | write_reg(reg_2834, 0x02834); | ||
348 | write_reg(reg_2838, 0x02838); | ||
349 | IVTV_DEBUG_YUV("Update reg 0x2834 %08x->%08x 0x2838 %08x->%08x\n", | ||
350 | yi->reg_2834, reg_2834, yi->reg_2838, reg_2838); | ||
351 | |||
352 | write_reg(reg_283c, 0x0283c); | ||
353 | write_reg(reg_2844, 0x02844); | ||
354 | |||
355 | IVTV_DEBUG_YUV("Update reg 0x283c %08x->%08x 0x2844 %08x->%08x\n", | ||
356 | yi->reg_283c, reg_283c, yi->reg_2844, reg_2844); | ||
357 | |||
358 | write_reg(0x00080514, 0x02840); | ||
359 | write_reg(0x00100514, 0x02848); | ||
360 | IVTV_DEBUG_YUV("Update reg 0x2840 %08x->%08x 0x2848 %08x->%08x\n", | ||
361 | yi->reg_2840, 0x00080514, yi->reg_2848, 0x00100514); | ||
362 | |||
363 | write_reg(reg_2854, 0x02854); | ||
364 | IVTV_DEBUG_YUV("Update reg 0x2854 %08x->%08x \n", | ||
365 | yi->reg_2854, reg_2854); | ||
366 | |||
367 | write_reg(reg_285c, 0x0285c); | ||
368 | write_reg(reg_2864, 0x02864); | ||
369 | IVTV_DEBUG_YUV("Update reg 0x285c %08x->%08x 0x2864 %08x->%08x\n", | ||
370 | yi->reg_285c, reg_285c, yi->reg_2864, reg_2864); | ||
371 | |||
372 | write_reg(reg_2874, 0x02874); | ||
373 | IVTV_DEBUG_YUV("Update reg 0x2874 %08x->%08x\n", | ||
374 | yi->reg_2874, reg_2874); | ||
375 | |||
376 | write_reg(reg_2870, 0x02870); | ||
377 | IVTV_DEBUG_YUV("Update reg 0x2870 %08x->%08x\n", | ||
378 | yi->reg_2870, reg_2870); | ||
379 | |||
380 | write_reg(reg_2890, 0x02890); | ||
381 | IVTV_DEBUG_YUV("Update reg 0x2890 %08x->%08x\n", | ||
382 | yi->reg_2890, reg_2890); | ||
383 | |||
384 | /* Only update the filter if we really need to */ | ||
385 | if (h_filter != yi->h_filter) { | ||
386 | ivtv_yuv_filter(itv, h_filter, -1, -1); | ||
387 | yi->h_filter = h_filter; | ||
388 | } | ||
389 | } | ||
390 | |||
391 | static void ivtv_yuv_handle_vertical(struct ivtv *itv, struct yuv_frame_info *f) | ||
392 | { | ||
393 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
394 | u32 master_height; | ||
395 | u32 reg_2918, reg_291c, reg_2920, reg_2928; | ||
396 | u32 reg_2930, reg_2934, reg_293c; | ||
397 | u32 reg_2940, reg_2944, reg_294c; | ||
398 | u32 reg_2950, reg_2954, reg_2958, reg_295c; | ||
399 | u32 reg_2960, reg_2964, reg_2968, reg_296c; | ||
400 | u32 reg_289c; | ||
401 | u32 src_major_y, src_minor_y; | ||
402 | u32 src_major_uv, src_minor_uv; | ||
403 | u32 reg_2964_base, reg_2968_base; | ||
404 | int v_filter_1, v_filter_2; | ||
405 | |||
406 | IVTV_DEBUG_WARN | ||
407 | ("Adjust to height %d src_h %d dst_h %d src_y %d dst_y %d\n", | ||
408 | f->tru_h, f->src_h, f->dst_h, f->src_y, f->dst_y); | ||
409 | |||
410 | /* What scaling mode is being used... */ | ||
411 | IVTV_DEBUG_YUV("Scaling mode Y: %s\n", | ||
412 | f->interlaced_y ? "Interlaced" : "Progressive"); | ||
413 | |||
414 | IVTV_DEBUG_YUV("Scaling mode UV: %s\n", | ||
415 | f->interlaced_uv ? "Interlaced" : "Progressive"); | ||
416 | |||
417 | /* What is the source video being treated as... */ | ||
418 | IVTV_DEBUG_WARN("Source video: %s\n", | ||
419 | f->interlaced ? "Interlaced" : "Progressive"); | ||
420 | |||
421 | /* We offset into the image using two different index methods, so split | ||
422 | the y source coord into two parts. */ | ||
423 | if (f->src_y < 8) { | ||
424 | src_minor_uv = f->src_y; | ||
425 | src_major_uv = 0; | ||
426 | } else { | ||
427 | src_minor_uv = 8; | ||
428 | src_major_uv = f->src_y - 8; | ||
429 | } | ||
430 | |||
431 | src_minor_y = src_minor_uv; | ||
432 | src_major_y = src_major_uv; | ||
433 | |||
434 | if (f->offset_y) | ||
435 | src_minor_y += 16; | ||
436 | |||
437 | if (f->interlaced_y) | ||
438 | reg_2918 = (f->dst_h << 16) | (f->src_h + src_minor_y); | ||
439 | else | ||
440 | reg_2918 = (f->dst_h << 16) | ((f->src_h + src_minor_y) << 1); | ||
441 | |||
442 | if (f->interlaced_uv) | ||
443 | reg_291c = (f->dst_h << 16) | ((f->src_h + src_minor_uv) >> 1); | ||
444 | else | ||
445 | reg_291c = (f->dst_h << 16) | (f->src_h + src_minor_uv); | ||
446 | |||
447 | reg_2964_base = (src_minor_y * ((f->dst_h << 16) / f->src_h)) >> 14; | ||
448 | reg_2968_base = (src_minor_uv * ((f->dst_h << 16) / f->src_h)) >> 14; | ||
449 | |||
450 | if (f->dst_h / 2 >= f->src_h && !f->interlaced_y) { | ||
451 | master_height = (f->src_h * 0x00400000) / f->dst_h; | ||
452 | if ((f->src_h * 0x00400000) - (master_height * f->dst_h) >= f->dst_h / 2) | ||
453 | master_height++; | ||
454 | reg_2920 = master_height >> 2; | ||
455 | reg_2928 = master_height >> 3; | ||
456 | reg_2930 = master_height; | ||
457 | reg_2940 = master_height >> 1; | ||
458 | reg_2964_base >>= 3; | ||
459 | reg_2968_base >>= 3; | ||
460 | reg_296c = 0x00000000; | ||
461 | } else if (f->dst_h >= f->src_h) { | ||
462 | master_height = (f->src_h * 0x00400000) / f->dst_h; | ||
463 | master_height = (master_height >> 1) + (master_height & 1); | ||
464 | reg_2920 = master_height >> 2; | ||
465 | reg_2928 = master_height >> 2; | ||
466 | reg_2930 = master_height; | ||
467 | reg_2940 = master_height >> 1; | ||
468 | reg_296c = 0x00000000; | ||
469 | if (f->interlaced_y) { | ||
470 | reg_2964_base >>= 3; | ||
471 | } else { | ||
472 | reg_296c++; | ||
473 | reg_2964_base >>= 2; | ||
474 | } | ||
475 | if (f->interlaced_uv) | ||
476 | reg_2928 >>= 1; | ||
477 | reg_2968_base >>= 3; | ||
478 | } else if (f->dst_h >= f->src_h / 2) { | ||
479 | master_height = (f->src_h * 0x00200000) / f->dst_h; | ||
480 | master_height = (master_height >> 1) + (master_height & 1); | ||
481 | reg_2920 = master_height >> 2; | ||
482 | reg_2928 = master_height >> 2; | ||
483 | reg_2930 = master_height; | ||
484 | reg_2940 = master_height; | ||
485 | reg_296c = 0x00000101; | ||
486 | if (f->interlaced_y) { | ||
487 | reg_2964_base >>= 2; | ||
488 | } else { | ||
489 | reg_296c++; | ||
490 | reg_2964_base >>= 1; | ||
491 | } | ||
492 | if (f->interlaced_uv) | ||
493 | reg_2928 >>= 1; | ||
494 | reg_2968_base >>= 2; | ||
495 | } else { | ||
496 | master_height = (f->src_h * 0x00100000) / f->dst_h; | ||
497 | master_height = (master_height >> 1) + (master_height & 1); | ||
498 | reg_2920 = master_height >> 2; | ||
499 | reg_2928 = master_height >> 2; | ||
500 | reg_2930 = master_height; | ||
501 | reg_2940 = master_height; | ||
502 | reg_2964_base >>= 1; | ||
503 | reg_2968_base >>= 2; | ||
504 | reg_296c = 0x00000102; | ||
505 | } | ||
506 | |||
507 | /* FIXME These registers change depending on scaled / unscaled output | ||
508 | We really need to work out what they should be */ | ||
509 | if (f->src_h == f->dst_h) { | ||
510 | reg_2934 = 0x00020000; | ||
511 | reg_293c = 0x00100000; | ||
512 | reg_2944 = 0x00040000; | ||
513 | reg_294c = 0x000b0000; | ||
514 | } else { | ||
515 | reg_2934 = 0x00000FF0; | ||
516 | reg_293c = 0x00000FF0; | ||
517 | reg_2944 = 0x00000FF0; | ||
518 | reg_294c = 0x00000FF0; | ||
519 | } | ||
520 | |||
521 | /* The first line to be displayed */ | ||
522 | reg_2950 = 0x00010000 + src_major_y; | ||
523 | if (f->interlaced_y) | ||
524 | reg_2950 += 0x00010000; | ||
525 | reg_2954 = reg_2950 + 1; | ||
526 | |||
527 | reg_2958 = 0x00010000 + (src_major_y >> 1); | ||
528 | if (f->interlaced_uv) | ||
529 | reg_2958 += 0x00010000; | ||
530 | reg_295c = reg_2958 + 1; | ||
531 | |||
532 | if (yi->decode_height == 480) | ||
533 | reg_289c = 0x011e0017; | ||
534 | else | ||
535 | reg_289c = 0x01500017; | ||
536 | |||
537 | if (f->dst_y < 0) | ||
538 | reg_289c = (reg_289c - ((f->dst_y & ~1)<<15))-(f->dst_y >>1); | ||
539 | else | ||
540 | reg_289c = (reg_289c + ((f->dst_y & ~1)<<15))+(f->dst_y >>1); | ||
541 | |||
542 | /* How much of the source to decode. | ||
543 | Take into account the source offset */ | ||
544 | reg_2960 = ((src_minor_y + f->src_h + src_major_y) - 1) | | ||
545 | (((src_minor_uv + f->src_h + src_major_uv - 1) & ~1) << 15); | ||
546 | |||
547 | /* Calculate correct value for register 2964 */ | ||
548 | if (f->src_h == f->dst_h) { | ||
549 | reg_2964 = 1; | ||
550 | } else { | ||
551 | reg_2964 = 2 + ((f->dst_h << 1) / f->src_h); | ||
552 | reg_2964 = (reg_2964 >> 1) + (reg_2964 & 1); | ||
553 | } | ||
554 | reg_2968 = (reg_2964 << 16) + reg_2964 + (reg_2964 >> 1); | ||
555 | reg_2964 = (reg_2964 << 16) + reg_2964 + (reg_2964 * 46 / 94); | ||
556 | |||
557 | /* Okay, we've wasted time working out the correct value, | ||
558 | but if we use it, it fouls the the window alignment. | ||
559 | Fudge it to what we want... */ | ||
560 | reg_2964 = 0x00010001 + ((reg_2964 & 0x0000FFFF) - (reg_2964 >> 16)); | ||
561 | reg_2968 = 0x00010001 + ((reg_2968 & 0x0000FFFF) - (reg_2968 >> 16)); | ||
562 | |||
563 | /* Deviate further from what it should be. I find the flicker headache | ||
564 | inducing so try to reduce it slightly. Leave 2968 as-is otherwise | ||
565 | colours foul. */ | ||
566 | if ((reg_2964 != 0x00010001) && (f->dst_h / 2 <= f->src_h)) | ||
567 | reg_2964 = (reg_2964 & 0xFFFF0000) + ((reg_2964 & 0x0000FFFF) / 2); | ||
568 | |||
569 | if (!f->interlaced_y) | ||
570 | reg_2964 -= 0x00010001; | ||
571 | if (!f->interlaced_uv) | ||
572 | reg_2968 -= 0x00010001; | ||
573 | |||
574 | reg_2964 += ((reg_2964_base << 16) | reg_2964_base); | ||
575 | reg_2968 += ((reg_2968_base << 16) | reg_2968_base); | ||
576 | |||
577 | /* Select the vertical filter */ | ||
578 | if (f->src_h == f->dst_h) { | ||
579 | /* An exact size match uses filter 0/1 */ | ||
580 | v_filter_1 = 0; | ||
581 | v_filter_2 = 1; | ||
582 | } else { | ||
583 | /* Figure out which filter to use */ | ||
584 | v_filter_1 = ((f->src_h << 16) / f->dst_h) >> 15; | ||
585 | v_filter_1 = (v_filter_1 >> 1) + (v_filter_1 & 1); | ||
586 | /* Only an exact size match can use filter 0 */ | ||
587 | v_filter_1 += !v_filter_1; | ||
588 | v_filter_2 = v_filter_1; | ||
589 | } | ||
590 | |||
591 | write_reg(reg_2934, 0x02934); | ||
592 | write_reg(reg_293c, 0x0293c); | ||
593 | IVTV_DEBUG_YUV("Update reg 0x2934 %08x->%08x 0x293c %08x->%08x\n", | ||
594 | yi->reg_2934, reg_2934, yi->reg_293c, reg_293c); | ||
595 | write_reg(reg_2944, 0x02944); | ||
596 | write_reg(reg_294c, 0x0294c); | ||
597 | IVTV_DEBUG_YUV("Update reg 0x2944 %08x->%08x 0x294c %08x->%08x\n", | ||
598 | yi->reg_2944, reg_2944, yi->reg_294c, reg_294c); | ||
599 | |||
600 | /* Ensure 2970 is 0 (does it ever change ?) */ | ||
601 | /* write_reg(0,0x02970); */ | ||
602 | /* IVTV_DEBUG_YUV("Update reg 0x2970 %08x->%08x\n", yi->reg_2970, 0); */ | ||
603 | |||
604 | write_reg(reg_2930, 0x02938); | ||
605 | write_reg(reg_2930, 0x02930); | ||
606 | IVTV_DEBUG_YUV("Update reg 0x2930 %08x->%08x 0x2938 %08x->%08x\n", | ||
607 | yi->reg_2930, reg_2930, yi->reg_2938, reg_2930); | ||
608 | |||
609 | write_reg(reg_2928, 0x02928); | ||
610 | write_reg(reg_2928 + 0x514, 0x0292C); | ||
611 | IVTV_DEBUG_YUV("Update reg 0x2928 %08x->%08x 0x292c %08x->%08x\n", | ||
612 | yi->reg_2928, reg_2928, yi->reg_292c, reg_2928 + 0x514); | ||
613 | |||
614 | write_reg(reg_2920, 0x02920); | ||
615 | write_reg(reg_2920 + 0x514, 0x02924); | ||
616 | IVTV_DEBUG_YUV("Update reg 0x2920 %08x->%08x 0x2924 %08x->%08x\n", | ||
617 | yi->reg_2920, reg_2920, yi->reg_2924, reg_2920 + 0x514); | ||
618 | |||
619 | write_reg(reg_2918, 0x02918); | ||
620 | write_reg(reg_291c, 0x0291C); | ||
621 | IVTV_DEBUG_YUV("Update reg 0x2918 %08x->%08x 0x291C %08x->%08x\n", | ||
622 | yi->reg_2918, reg_2918, yi->reg_291c, reg_291c); | ||
623 | |||
624 | write_reg(reg_296c, 0x0296c); | ||
625 | IVTV_DEBUG_YUV("Update reg 0x296c %08x->%08x\n", | ||
626 | yi->reg_296c, reg_296c); | ||
627 | |||
628 | write_reg(reg_2940, 0x02948); | ||
629 | write_reg(reg_2940, 0x02940); | ||
630 | IVTV_DEBUG_YUV("Update reg 0x2940 %08x->%08x 0x2948 %08x->%08x\n", | ||
631 | yi->reg_2940, reg_2940, yi->reg_2948, reg_2940); | ||
632 | |||
633 | write_reg(reg_2950, 0x02950); | ||
634 | write_reg(reg_2954, 0x02954); | ||
635 | IVTV_DEBUG_YUV("Update reg 0x2950 %08x->%08x 0x2954 %08x->%08x\n", | ||
636 | yi->reg_2950, reg_2950, yi->reg_2954, reg_2954); | ||
637 | |||
638 | write_reg(reg_2958, 0x02958); | ||
639 | write_reg(reg_295c, 0x0295C); | ||
640 | IVTV_DEBUG_YUV("Update reg 0x2958 %08x->%08x 0x295C %08x->%08x\n", | ||
641 | yi->reg_2958, reg_2958, yi->reg_295c, reg_295c); | ||
642 | |||
643 | write_reg(reg_2960, 0x02960); | ||
644 | IVTV_DEBUG_YUV("Update reg 0x2960 %08x->%08x \n", | ||
645 | yi->reg_2960, reg_2960); | ||
646 | |||
647 | write_reg(reg_2964, 0x02964); | ||
648 | write_reg(reg_2968, 0x02968); | ||
649 | IVTV_DEBUG_YUV("Update reg 0x2964 %08x->%08x 0x2968 %08x->%08x\n", | ||
650 | yi->reg_2964, reg_2964, yi->reg_2968, reg_2968); | ||
651 | |||
652 | write_reg(reg_289c, 0x0289c); | ||
653 | IVTV_DEBUG_YUV("Update reg 0x289c %08x->%08x\n", | ||
654 | yi->reg_289c, reg_289c); | ||
655 | |||
656 | /* Only update filter 1 if we really need to */ | ||
657 | if (v_filter_1 != yi->v_filter_1) { | ||
658 | ivtv_yuv_filter(itv, -1, v_filter_1, -1); | ||
659 | yi->v_filter_1 = v_filter_1; | ||
660 | } | ||
661 | |||
662 | /* Only update filter 2 if we really need to */ | ||
663 | if (v_filter_2 != yi->v_filter_2) { | ||
664 | ivtv_yuv_filter(itv, -1, -1, v_filter_2); | ||
665 | yi->v_filter_2 = v_filter_2; | ||
666 | } | ||
667 | } | ||
668 | |||
669 | /* Modify the supplied coordinate information to fit the visible osd area */ | ||
670 | static u32 ivtv_yuv_window_setup(struct ivtv *itv, struct yuv_frame_info *f) | ||
671 | { | ||
672 | struct yuv_frame_info *of = &itv->yuv_info.old_frame_info; | ||
673 | int osd_crop; | ||
674 | u32 osd_scale; | ||
675 | u32 yuv_update = 0; | ||
676 | |||
677 | /* Sorry, but no negative coords for src */ | ||
678 | if (f->src_x < 0) | ||
679 | f->src_x = 0; | ||
680 | if (f->src_y < 0) | ||
681 | f->src_y = 0; | ||
682 | |||
683 | /* Can only reduce width down to 1/4 original size */ | ||
684 | if ((osd_crop = f->src_w - 4 * f->dst_w) > 0) { | ||
685 | f->src_x += osd_crop / 2; | ||
686 | f->src_w = (f->src_w - osd_crop) & ~3; | ||
687 | f->dst_w = f->src_w / 4; | ||
688 | f->dst_w += f->dst_w & 1; | ||
689 | } | ||
690 | |||
691 | /* Can only reduce height down to 1/4 original size */ | ||
692 | if (f->src_h / f->dst_h >= 2) { | ||
693 | /* Overflow may be because we're running progressive, | ||
694 | so force mode switch */ | ||
695 | f->interlaced_y = 1; | ||
696 | /* Make sure we're still within limits for interlace */ | ||
697 | if ((osd_crop = f->src_h - 4 * f->dst_h) > 0) { | ||
698 | /* If we reach here we'll have to force the height. */ | ||
699 | f->src_y += osd_crop / 2; | ||
700 | f->src_h = (f->src_h - osd_crop) & ~3; | ||
701 | f->dst_h = f->src_h / 4; | ||
702 | f->dst_h += f->dst_h & 1; | ||
703 | } | ||
704 | } | ||
705 | |||
706 | /* If there's nothing to safe to display, we may as well stop now */ | ||
707 | if ((int)f->dst_w <= 2 || (int)f->dst_h <= 2 || | ||
708 | (int)f->src_w <= 2 || (int)f->src_h <= 2) { | ||
709 | return IVTV_YUV_UPDATE_INVALID; | ||
710 | } | ||
711 | |||
712 | /* Ensure video remains inside OSD area */ | ||
713 | osd_scale = (f->src_h << 16) / f->dst_h; | ||
714 | |||
715 | if ((osd_crop = f->pan_y - f->dst_y) > 0) { | ||
716 | /* Falls off the upper edge - crop */ | ||
717 | f->src_y += (osd_scale * osd_crop) >> 16; | ||
718 | f->src_h -= (osd_scale * osd_crop) >> 16; | ||
719 | f->dst_h -= osd_crop; | ||
720 | f->dst_y = 0; | ||
721 | } else { | ||
722 | f->dst_y -= f->pan_y; | ||
723 | } | ||
724 | |||
725 | if ((osd_crop = f->dst_h + f->dst_y - f->vis_h) > 0) { | ||
726 | /* Falls off the lower edge - crop */ | ||
727 | f->dst_h -= osd_crop; | ||
728 | f->src_h -= (osd_scale * osd_crop) >> 16; | ||
729 | } | ||
730 | |||
731 | osd_scale = (f->src_w << 16) / f->dst_w; | ||
732 | |||
733 | if ((osd_crop = f->pan_x - f->dst_x) > 0) { | ||
734 | /* Fall off the left edge - crop */ | ||
735 | f->src_x += (osd_scale * osd_crop) >> 16; | ||
736 | f->src_w -= (osd_scale * osd_crop) >> 16; | ||
737 | f->dst_w -= osd_crop; | ||
738 | f->dst_x = 0; | ||
739 | } else { | ||
740 | f->dst_x -= f->pan_x; | ||
741 | } | ||
742 | |||
743 | if ((osd_crop = f->dst_w + f->dst_x - f->vis_w) > 0) { | ||
744 | /* Falls off the right edge - crop */ | ||
745 | f->dst_w -= osd_crop; | ||
746 | f->src_w -= (osd_scale * osd_crop) >> 16; | ||
747 | } | ||
748 | |||
749 | if (itv->yuv_info.track_osd) { | ||
750 | /* The OSD can be moved. Track to it */ | ||
751 | f->dst_x += itv->yuv_info.osd_x_offset; | ||
752 | f->dst_y += itv->yuv_info.osd_y_offset; | ||
753 | } | ||
754 | |||
755 | /* Width & height for both src & dst must be even. | ||
756 | Same for coordinates. */ | ||
757 | f->dst_w &= ~1; | ||
758 | f->dst_x &= ~1; | ||
759 | |||
760 | f->src_w += f->src_x & 1; | ||
761 | f->src_x &= ~1; | ||
762 | |||
763 | f->src_w &= ~1; | ||
764 | f->dst_w &= ~1; | ||
765 | |||
766 | f->dst_h &= ~1; | ||
767 | f->dst_y &= ~1; | ||
768 | |||
769 | f->src_h += f->src_y & 1; | ||
770 | f->src_y &= ~1; | ||
771 | |||
772 | f->src_h &= ~1; | ||
773 | f->dst_h &= ~1; | ||
774 | |||
775 | /* Due to rounding, we may have reduced the output size to <1/4 of | ||
776 | the source. Check again, but this time just resize. Don't change | ||
777 | source coordinates */ | ||
778 | if (f->dst_w < f->src_w / 4) { | ||
779 | f->src_w &= ~3; | ||
780 | f->dst_w = f->src_w / 4; | ||
781 | f->dst_w += f->dst_w & 1; | ||
782 | } | ||
783 | if (f->dst_h < f->src_h / 4) { | ||
784 | f->src_h &= ~3; | ||
785 | f->dst_h = f->src_h / 4; | ||
786 | f->dst_h += f->dst_h & 1; | ||
787 | } | ||
788 | |||
789 | /* Check again. If there's nothing to safe to display, stop now */ | ||
790 | if ((int)f->dst_w <= 2 || (int)f->dst_h <= 2 || | ||
791 | (int)f->src_w <= 2 || (int)f->src_h <= 2) { | ||
792 | return IVTV_YUV_UPDATE_INVALID; | ||
793 | } | ||
794 | |||
795 | /* Both x offset & width are linked, so they have to be done together */ | ||
796 | if ((of->dst_w != f->dst_w) || (of->src_w != f->src_w) || | ||
797 | (of->dst_x != f->dst_x) || (of->src_x != f->src_x) || | ||
798 | (of->pan_x != f->pan_x) || (of->vis_w != f->vis_w)) { | ||
799 | yuv_update |= IVTV_YUV_UPDATE_HORIZONTAL; | ||
800 | } | ||
801 | |||
802 | if ((of->src_h != f->src_h) || (of->dst_h != f->dst_h) || | ||
803 | (of->dst_y != f->dst_y) || (of->src_y != f->src_y) || | ||
804 | (of->pan_y != f->pan_y) || (of->vis_h != f->vis_h) || | ||
805 | (of->lace_mode != f->lace_mode) || | ||
806 | (of->interlaced_y != f->interlaced_y) || | ||
807 | (of->interlaced_uv != f->interlaced_uv)) { | ||
808 | yuv_update |= IVTV_YUV_UPDATE_VERTICAL; | ||
809 | } | ||
810 | |||
811 | return yuv_update; | ||
812 | } | ||
813 | |||
814 | /* Update the scaling register to the requested value */ | ||
815 | void ivtv_yuv_work_handler(struct ivtv *itv) | ||
816 | { | ||
817 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
818 | struct yuv_frame_info f; | ||
819 | int frame = yi->update_frame; | ||
820 | u32 yuv_update; | ||
821 | |||
822 | IVTV_DEBUG_YUV("Update yuv registers for frame %d\n", frame); | ||
823 | f = yi->new_frame_info[frame]; | ||
824 | |||
825 | if (yi->track_osd) { | ||
826 | /* Snapshot the osd pan info */ | ||
827 | f.pan_x = yi->osd_x_pan; | ||
828 | f.pan_y = yi->osd_y_pan; | ||
829 | f.vis_w = yi->osd_vis_w; | ||
830 | f.vis_h = yi->osd_vis_h; | ||
831 | } else { | ||
832 | /* Not tracking the osd, so assume full screen */ | ||
833 | f.pan_x = 0; | ||
834 | f.pan_y = 0; | ||
835 | f.vis_w = 720; | ||
836 | f.vis_h = yi->decode_height; | ||
837 | } | ||
838 | |||
839 | /* Calculate the display window coordinates. Exit if nothing left */ | ||
840 | if (!(yuv_update = ivtv_yuv_window_setup(itv, &f))) | ||
841 | return; | ||
842 | |||
843 | if (yuv_update & IVTV_YUV_UPDATE_INVALID) { | ||
844 | write_reg(0x01008080, 0x2898); | ||
845 | } else if (yuv_update) { | ||
846 | write_reg(0x00108080, 0x2898); | ||
847 | |||
848 | if (yuv_update & IVTV_YUV_UPDATE_HORIZONTAL) | ||
849 | ivtv_yuv_handle_horizontal(itv, &f); | ||
850 | |||
851 | if (yuv_update & IVTV_YUV_UPDATE_VERTICAL) | ||
852 | ivtv_yuv_handle_vertical(itv, &f); | ||
853 | } | ||
854 | yi->old_frame_info = f; | ||
855 | } | ||
856 | |||
857 | static void ivtv_yuv_init(struct ivtv *itv) | ||
858 | { | ||
859 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
860 | |||
861 | IVTV_DEBUG_YUV("ivtv_yuv_init\n"); | ||
862 | |||
863 | /* Take a snapshot of the current register settings */ | ||
864 | yi->reg_2834 = read_reg(0x02834); | ||
865 | yi->reg_2838 = read_reg(0x02838); | ||
866 | yi->reg_283c = read_reg(0x0283c); | ||
867 | yi->reg_2840 = read_reg(0x02840); | ||
868 | yi->reg_2844 = read_reg(0x02844); | ||
869 | yi->reg_2848 = read_reg(0x02848); | ||
870 | yi->reg_2854 = read_reg(0x02854); | ||
871 | yi->reg_285c = read_reg(0x0285c); | ||
872 | yi->reg_2864 = read_reg(0x02864); | ||
873 | yi->reg_2870 = read_reg(0x02870); | ||
874 | yi->reg_2874 = read_reg(0x02874); | ||
875 | yi->reg_2898 = read_reg(0x02898); | ||
876 | yi->reg_2890 = read_reg(0x02890); | ||
877 | |||
878 | yi->reg_289c = read_reg(0x0289c); | ||
879 | yi->reg_2918 = read_reg(0x02918); | ||
880 | yi->reg_291c = read_reg(0x0291c); | ||
881 | yi->reg_2920 = read_reg(0x02920); | ||
882 | yi->reg_2924 = read_reg(0x02924); | ||
883 | yi->reg_2928 = read_reg(0x02928); | ||
884 | yi->reg_292c = read_reg(0x0292c); | ||
885 | yi->reg_2930 = read_reg(0x02930); | ||
886 | yi->reg_2934 = read_reg(0x02934); | ||
887 | yi->reg_2938 = read_reg(0x02938); | ||
888 | yi->reg_293c = read_reg(0x0293c); | ||
889 | yi->reg_2940 = read_reg(0x02940); | ||
890 | yi->reg_2944 = read_reg(0x02944); | ||
891 | yi->reg_2948 = read_reg(0x02948); | ||
892 | yi->reg_294c = read_reg(0x0294c); | ||
893 | yi->reg_2950 = read_reg(0x02950); | ||
894 | yi->reg_2954 = read_reg(0x02954); | ||
895 | yi->reg_2958 = read_reg(0x02958); | ||
896 | yi->reg_295c = read_reg(0x0295c); | ||
897 | yi->reg_2960 = read_reg(0x02960); | ||
898 | yi->reg_2964 = read_reg(0x02964); | ||
899 | yi->reg_2968 = read_reg(0x02968); | ||
900 | yi->reg_296c = read_reg(0x0296c); | ||
901 | yi->reg_2970 = read_reg(0x02970); | ||
902 | |||
903 | yi->v_filter_1 = -1; | ||
904 | yi->v_filter_2 = -1; | ||
905 | yi->h_filter = -1; | ||
906 | |||
907 | /* Set some valid size info */ | ||
908 | yi->osd_x_offset = read_reg(0x02a04) & 0x00000FFF; | ||
909 | yi->osd_y_offset = (read_reg(0x02a04) >> 16) & 0x00000FFF; | ||
910 | |||
911 | /* Bit 2 of reg 2878 indicates current decoder output format | ||
912 | 0 : NTSC 1 : PAL */ | ||
913 | if (read_reg(0x2878) & 4) | ||
914 | yi->decode_height = 576; | ||
915 | else | ||
916 | yi->decode_height = 480; | ||
917 | |||
918 | if (!itv->osd_info) { | ||
919 | yi->osd_vis_w = 720 - yi->osd_x_offset; | ||
920 | yi->osd_vis_h = yi->decode_height - yi->osd_y_offset; | ||
921 | } else { | ||
922 | /* If no visible size set, assume full size */ | ||
923 | if (!yi->osd_vis_w) | ||
924 | yi->osd_vis_w = 720 - yi->osd_x_offset; | ||
925 | |||
926 | if (!yi->osd_vis_h) { | ||
927 | yi->osd_vis_h = yi->decode_height - yi->osd_y_offset; | ||
928 | } else if (yi->osd_vis_h + yi->osd_y_offset > yi->decode_height) { | ||
929 | /* If output video standard has changed, requested height may | ||
930 | not be legal */ | ||
931 | IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n", | ||
932 | yi->osd_vis_h + yi->osd_y_offset, | ||
933 | yi->decode_height); | ||
934 | yi->osd_vis_h = yi->decode_height - yi->osd_y_offset; | ||
935 | } | ||
936 | } | ||
937 | |||
938 | /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */ | ||
939 | yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL|__GFP_NOWARN); | ||
940 | if (yi->blanking_ptr) { | ||
941 | yi->blanking_dmaptr = pci_map_single(itv->pdev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE); | ||
942 | } else { | ||
943 | yi->blanking_dmaptr = 0; | ||
944 | IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n"); | ||
945 | } | ||
946 | |||
947 | /* Enable YUV decoder output */ | ||
948 | write_reg_sync(0x01, IVTV_REG_VDM); | ||
949 | |||
950 | set_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags); | ||
951 | atomic_set(&yi->next_dma_frame, 0); | ||
952 | } | ||
953 | |||
954 | /* Get next available yuv buffer on PVR350 */ | ||
955 | static void ivtv_yuv_next_free(struct ivtv *itv) | ||
956 | { | ||
957 | int draw, display; | ||
958 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
959 | |||
960 | if (atomic_read(&yi->next_dma_frame) == -1) | ||
961 | ivtv_yuv_init(itv); | ||
962 | |||
963 | draw = atomic_read(&yi->next_fill_frame); | ||
964 | display = atomic_read(&yi->next_dma_frame); | ||
965 | |||
966 | if (display > draw) | ||
967 | display -= IVTV_YUV_BUFFERS; | ||
968 | |||
969 | if (draw - display >= yi->max_frames_buffered) | ||
970 | draw = (u8)(draw - 1) % IVTV_YUV_BUFFERS; | ||
971 | else | ||
972 | yi->new_frame_info[draw].update = 0; | ||
973 | |||
974 | yi->draw_frame = draw; | ||
975 | } | ||
976 | |||
977 | /* Set up frame according to ivtv_dma_frame parameters */ | ||
978 | static void ivtv_yuv_setup_frame(struct ivtv *itv, struct ivtv_dma_frame *args) | ||
979 | { | ||
980 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
981 | u8 frame = yi->draw_frame; | ||
982 | u8 last_frame = (u8)(frame - 1) % IVTV_YUV_BUFFERS; | ||
983 | struct yuv_frame_info *nf = &yi->new_frame_info[frame]; | ||
984 | struct yuv_frame_info *of = &yi->new_frame_info[last_frame]; | ||
985 | int lace_threshold = yi->lace_threshold; | ||
986 | |||
987 | /* Preserve old update flag in case we're overwriting a queued frame */ | ||
988 | int update = nf->update; | ||
989 | |||
990 | /* Take a snapshot of the yuv coordinate information */ | ||
991 | nf->src_x = args->src.left; | ||
992 | nf->src_y = args->src.top; | ||
993 | nf->src_w = args->src.width; | ||
994 | nf->src_h = args->src.height; | ||
995 | nf->dst_x = args->dst.left; | ||
996 | nf->dst_y = args->dst.top; | ||
997 | nf->dst_w = args->dst.width; | ||
998 | nf->dst_h = args->dst.height; | ||
999 | nf->tru_x = args->dst.left; | ||
1000 | nf->tru_w = args->src_width; | ||
1001 | nf->tru_h = args->src_height; | ||
1002 | |||
1003 | /* Are we going to offset the Y plane */ | ||
1004 | nf->offset_y = (nf->tru_h + nf->src_x < 512 - 16) ? 1 : 0; | ||
1005 | |||
1006 | nf->update = 0; | ||
1007 | nf->interlaced_y = 0; | ||
1008 | nf->interlaced_uv = 0; | ||
1009 | nf->delay = 0; | ||
1010 | nf->sync_field = 0; | ||
1011 | nf->lace_mode = yi->lace_mode & IVTV_YUV_MODE_MASK; | ||
1012 | |||
1013 | if (lace_threshold < 0) | ||
1014 | lace_threshold = yi->decode_height - 1; | ||
1015 | |||
1016 | /* Work out the lace settings */ | ||
1017 | switch (nf->lace_mode) { | ||
1018 | case IVTV_YUV_MODE_PROGRESSIVE: /* Progressive mode */ | ||
1019 | nf->interlaced = 0; | ||
1020 | if (nf->tru_h < 512 || (nf->tru_h > 576 && nf->tru_h < 1021)) | ||
1021 | nf->interlaced_y = 0; | ||
1022 | else | ||
1023 | nf->interlaced_y = 1; | ||
1024 | |||
1025 | if (nf->tru_h < 1021 && (nf->dst_h >= nf->src_h / 2)) | ||
1026 | nf->interlaced_uv = 0; | ||
1027 | else | ||
1028 | nf->interlaced_uv = 1; | ||
1029 | break; | ||
1030 | |||
1031 | case IVTV_YUV_MODE_AUTO: | ||
1032 | if (nf->tru_h <= lace_threshold || nf->tru_h > 576 || nf->tru_w > 720) { | ||
1033 | nf->interlaced = 0; | ||
1034 | if ((nf->tru_h < 512) || | ||
1035 | (nf->tru_h > 576 && nf->tru_h < 1021) || | ||
1036 | (nf->tru_w > 720 && nf->tru_h < 1021)) | ||
1037 | nf->interlaced_y = 0; | ||
1038 | else | ||
1039 | nf->interlaced_y = 1; | ||
1040 | if (nf->tru_h < 1021 && (nf->dst_h >= nf->src_h / 2)) | ||
1041 | nf->interlaced_uv = 0; | ||
1042 | else | ||
1043 | nf->interlaced_uv = 1; | ||
1044 | } else { | ||
1045 | nf->interlaced = 1; | ||
1046 | nf->interlaced_y = 1; | ||
1047 | nf->interlaced_uv = 1; | ||
1048 | } | ||
1049 | break; | ||
1050 | |||
1051 | case IVTV_YUV_MODE_INTERLACED: /* Interlace mode */ | ||
1052 | default: | ||
1053 | nf->interlaced = 1; | ||
1054 | nf->interlaced_y = 1; | ||
1055 | nf->interlaced_uv = 1; | ||
1056 | break; | ||
1057 | } | ||
1058 | |||
1059 | if (memcmp(&yi->old_frame_info_args, nf, sizeof(*nf))) { | ||
1060 | yi->old_frame_info_args = *nf; | ||
1061 | nf->update = 1; | ||
1062 | IVTV_DEBUG_YUV("Requesting reg update for frame %d\n", frame); | ||
1063 | } | ||
1064 | |||
1065 | nf->update |= update; | ||
1066 | nf->sync_field = yi->lace_sync_field; | ||
1067 | nf->delay = nf->sync_field != of->sync_field; | ||
1068 | } | ||
1069 | |||
1070 | /* Frame is complete & ready for display */ | ||
1071 | void ivtv_yuv_frame_complete(struct ivtv *itv) | ||
1072 | { | ||
1073 | atomic_set(&itv->yuv_info.next_fill_frame, | ||
1074 | (itv->yuv_info.draw_frame + 1) % IVTV_YUV_BUFFERS); | ||
1075 | } | ||
1076 | |||
1077 | static int ivtv_yuv_udma_frame(struct ivtv *itv, struct ivtv_dma_frame *args) | ||
1078 | { | ||
1079 | DEFINE_WAIT(wait); | ||
1080 | int rc = 0; | ||
1081 | int got_sig = 0; | ||
1082 | /* DMA the frame */ | ||
1083 | mutex_lock(&itv->udma.lock); | ||
1084 | |||
1085 | if ((rc = ivtv_yuv_prep_user_dma(itv, &itv->udma, args)) != 0) { | ||
1086 | mutex_unlock(&itv->udma.lock); | ||
1087 | return rc; | ||
1088 | } | ||
1089 | |||
1090 | ivtv_udma_prepare(itv); | ||
1091 | prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); | ||
1092 | /* if no UDMA is pending and no UDMA is in progress, then the DMA | ||
1093 | is finished */ | ||
1094 | while (test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags) || | ||
1095 | test_bit(IVTV_F_I_UDMA, &itv->i_flags)) { | ||
1096 | /* don't interrupt if the DMA is in progress but break off | ||
1097 | a still pending DMA. */ | ||
1098 | got_sig = signal_pending(current); | ||
1099 | if (got_sig && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags)) | ||
1100 | break; | ||
1101 | got_sig = 0; | ||
1102 | schedule(); | ||
1103 | } | ||
1104 | finish_wait(&itv->dma_waitq, &wait); | ||
1105 | |||
1106 | /* Unmap Last DMA Xfer */ | ||
1107 | ivtv_udma_unmap(itv); | ||
1108 | |||
1109 | if (got_sig) { | ||
1110 | IVTV_DEBUG_INFO("User stopped YUV UDMA\n"); | ||
1111 | mutex_unlock(&itv->udma.lock); | ||
1112 | return -EINTR; | ||
1113 | } | ||
1114 | |||
1115 | ivtv_yuv_frame_complete(itv); | ||
1116 | |||
1117 | mutex_unlock(&itv->udma.lock); | ||
1118 | return rc; | ||
1119 | } | ||
1120 | |||
1121 | /* Setup frame according to V4L2 parameters */ | ||
1122 | void ivtv_yuv_setup_stream_frame(struct ivtv *itv) | ||
1123 | { | ||
1124 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
1125 | struct ivtv_dma_frame dma_args; | ||
1126 | |||
1127 | ivtv_yuv_next_free(itv); | ||
1128 | |||
1129 | /* Copy V4L2 parameters to an ivtv_dma_frame struct... */ | ||
1130 | dma_args.y_source = NULL; | ||
1131 | dma_args.uv_source = NULL; | ||
1132 | dma_args.src.left = 0; | ||
1133 | dma_args.src.top = 0; | ||
1134 | dma_args.src.width = yi->v4l2_src_w; | ||
1135 | dma_args.src.height = yi->v4l2_src_h; | ||
1136 | dma_args.dst = yi->main_rect; | ||
1137 | dma_args.src_width = yi->v4l2_src_w; | ||
1138 | dma_args.src_height = yi->v4l2_src_h; | ||
1139 | |||
1140 | /* ... and use the same setup routine as ivtv_yuv_prep_frame */ | ||
1141 | ivtv_yuv_setup_frame(itv, &dma_args); | ||
1142 | |||
1143 | if (!itv->dma_data_req_offset) | ||
1144 | itv->dma_data_req_offset = yuv_offset[yi->draw_frame]; | ||
1145 | } | ||
1146 | |||
1147 | /* Attempt to dma a frame from a user buffer */ | ||
1148 | int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void __user *src) | ||
1149 | { | ||
1150 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
1151 | struct ivtv_dma_frame dma_args; | ||
1152 | |||
1153 | ivtv_yuv_setup_stream_frame(itv); | ||
1154 | |||
1155 | /* We only need to supply source addresses for this */ | ||
1156 | dma_args.y_source = src; | ||
1157 | dma_args.uv_source = src + 720 * ((yi->v4l2_src_h + 31) & ~31); | ||
1158 | return ivtv_yuv_udma_frame(itv, &dma_args); | ||
1159 | } | ||
1160 | |||
1161 | /* IVTV_IOC_DMA_FRAME ioctl handler */ | ||
1162 | int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args) | ||
1163 | { | ||
1164 | /* IVTV_DEBUG_INFO("yuv_prep_frame\n"); */ | ||
1165 | |||
1166 | ivtv_yuv_next_free(itv); | ||
1167 | ivtv_yuv_setup_frame(itv, args); | ||
1168 | return ivtv_yuv_udma_frame(itv, args); | ||
1169 | } | ||
1170 | |||
1171 | void ivtv_yuv_close(struct ivtv *itv) | ||
1172 | { | ||
1173 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
1174 | int h_filter, v_filter_1, v_filter_2; | ||
1175 | |||
1176 | IVTV_DEBUG_YUV("ivtv_yuv_close\n"); | ||
1177 | ivtv_waitq(&itv->vsync_waitq); | ||
1178 | |||
1179 | yi->running = 0; | ||
1180 | atomic_set(&yi->next_dma_frame, -1); | ||
1181 | atomic_set(&yi->next_fill_frame, 0); | ||
1182 | |||
1183 | /* Reset registers we have changed so mpeg playback works */ | ||
1184 | |||
1185 | /* If we fully restore this register, the display may remain active. | ||
1186 | Restore, but set one bit to blank the video. Firmware will always | ||
1187 | clear this bit when needed, so not a problem. */ | ||
1188 | write_reg(yi->reg_2898 | 0x01000000, 0x2898); | ||
1189 | |||
1190 | write_reg(yi->reg_2834, 0x02834); | ||
1191 | write_reg(yi->reg_2838, 0x02838); | ||
1192 | write_reg(yi->reg_283c, 0x0283c); | ||
1193 | write_reg(yi->reg_2840, 0x02840); | ||
1194 | write_reg(yi->reg_2844, 0x02844); | ||
1195 | write_reg(yi->reg_2848, 0x02848); | ||
1196 | write_reg(yi->reg_2854, 0x02854); | ||
1197 | write_reg(yi->reg_285c, 0x0285c); | ||
1198 | write_reg(yi->reg_2864, 0x02864); | ||
1199 | write_reg(yi->reg_2870, 0x02870); | ||
1200 | write_reg(yi->reg_2874, 0x02874); | ||
1201 | write_reg(yi->reg_2890, 0x02890); | ||
1202 | write_reg(yi->reg_289c, 0x0289c); | ||
1203 | |||
1204 | write_reg(yi->reg_2918, 0x02918); | ||
1205 | write_reg(yi->reg_291c, 0x0291c); | ||
1206 | write_reg(yi->reg_2920, 0x02920); | ||
1207 | write_reg(yi->reg_2924, 0x02924); | ||
1208 | write_reg(yi->reg_2928, 0x02928); | ||
1209 | write_reg(yi->reg_292c, 0x0292c); | ||
1210 | write_reg(yi->reg_2930, 0x02930); | ||
1211 | write_reg(yi->reg_2934, 0x02934); | ||
1212 | write_reg(yi->reg_2938, 0x02938); | ||
1213 | write_reg(yi->reg_293c, 0x0293c); | ||
1214 | write_reg(yi->reg_2940, 0x02940); | ||
1215 | write_reg(yi->reg_2944, 0x02944); | ||
1216 | write_reg(yi->reg_2948, 0x02948); | ||
1217 | write_reg(yi->reg_294c, 0x0294c); | ||
1218 | write_reg(yi->reg_2950, 0x02950); | ||
1219 | write_reg(yi->reg_2954, 0x02954); | ||
1220 | write_reg(yi->reg_2958, 0x02958); | ||
1221 | write_reg(yi->reg_295c, 0x0295c); | ||
1222 | write_reg(yi->reg_2960, 0x02960); | ||
1223 | write_reg(yi->reg_2964, 0x02964); | ||
1224 | write_reg(yi->reg_2968, 0x02968); | ||
1225 | write_reg(yi->reg_296c, 0x0296c); | ||
1226 | write_reg(yi->reg_2970, 0x02970); | ||
1227 | |||
1228 | /* Prepare to restore filters */ | ||
1229 | |||
1230 | /* First the horizontal filter */ | ||
1231 | if ((yi->reg_2834 & 0x0000FFFF) == (yi->reg_2834 >> 16)) { | ||
1232 | /* An exact size match uses filter 0 */ | ||
1233 | h_filter = 0; | ||
1234 | } else { | ||
1235 | /* Figure out which filter to use */ | ||
1236 | h_filter = ((yi->reg_2834 << 16) / (yi->reg_2834 >> 16)) >> 15; | ||
1237 | h_filter = (h_filter >> 1) + (h_filter & 1); | ||
1238 | /* Only an exact size match can use filter 0. */ | ||
1239 | h_filter += !h_filter; | ||
1240 | } | ||
1241 | |||
1242 | /* Now the vertical filter */ | ||
1243 | if ((yi->reg_2918 & 0x0000FFFF) == (yi->reg_2918 >> 16)) { | ||
1244 | /* An exact size match uses filter 0/1 */ | ||
1245 | v_filter_1 = 0; | ||
1246 | v_filter_2 = 1; | ||
1247 | } else { | ||
1248 | /* Figure out which filter to use */ | ||
1249 | v_filter_1 = ((yi->reg_2918 << 16) / (yi->reg_2918 >> 16)) >> 15; | ||
1250 | v_filter_1 = (v_filter_1 >> 1) + (v_filter_1 & 1); | ||
1251 | /* Only an exact size match can use filter 0 */ | ||
1252 | v_filter_1 += !v_filter_1; | ||
1253 | v_filter_2 = v_filter_1; | ||
1254 | } | ||
1255 | |||
1256 | /* Now restore the filters */ | ||
1257 | ivtv_yuv_filter(itv, h_filter, v_filter_1, v_filter_2); | ||
1258 | |||
1259 | /* and clear a few registers */ | ||
1260 | write_reg(0, 0x02814); | ||
1261 | write_reg(0, 0x0282c); | ||
1262 | write_reg(0, 0x02904); | ||
1263 | write_reg(0, 0x02910); | ||
1264 | |||
1265 | /* Release the blanking buffer */ | ||
1266 | if (yi->blanking_ptr) { | ||
1267 | kfree(yi->blanking_ptr); | ||
1268 | yi->blanking_ptr = NULL; | ||
1269 | pci_unmap_single(itv->pdev, yi->blanking_dmaptr, 720*16, PCI_DMA_TODEVICE); | ||
1270 | } | ||
1271 | |||
1272 | /* Invalidate the old dimension information */ | ||
1273 | yi->old_frame_info.src_w = 0; | ||
1274 | yi->old_frame_info.src_h = 0; | ||
1275 | yi->old_frame_info_args.src_w = 0; | ||
1276 | yi->old_frame_info_args.src_h = 0; | ||
1277 | |||
1278 | /* All done. */ | ||
1279 | clear_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags); | ||
1280 | } | ||
diff --git a/drivers/media/video/ivtv/ivtv-yuv.h b/drivers/media/video/ivtv/ivtv-yuv.h new file mode 100644 index 00000000000..ca5173fbf00 --- /dev/null +++ b/drivers/media/video/ivtv/ivtv-yuv.h | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | yuv support | ||
3 | |||
4 | Copyright (C) 2007 Ian Armstrong <ian@iarmst.demon.co.uk> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #ifndef IVTV_YUV_H | ||
22 | #define IVTV_YUV_H | ||
23 | |||
24 | #define IVTV_YUV_BUFFER_UV_OFFSET 0x65400 /* Offset to UV Buffer */ | ||
25 | |||
26 | /* Offset to filter table in firmware */ | ||
27 | #define IVTV_YUV_HORIZONTAL_FILTER_OFFSET 0x025d8 | ||
28 | #define IVTV_YUV_VERTICAL_FILTER_OFFSET 0x03358 | ||
29 | |||
30 | #define IVTV_YUV_UPDATE_HORIZONTAL 0x01 | ||
31 | #define IVTV_YUV_UPDATE_VERTICAL 0x02 | ||
32 | #define IVTV_YUV_UPDATE_INVALID 0x04 | ||
33 | |||
34 | extern const u32 yuv_offset[IVTV_YUV_BUFFERS]; | ||
35 | |||
36 | int ivtv_yuv_filter_check(struct ivtv *itv); | ||
37 | void ivtv_yuv_setup_stream_frame(struct ivtv *itv); | ||
38 | int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void __user *src); | ||
39 | void ivtv_yuv_frame_complete(struct ivtv *itv); | ||
40 | int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args); | ||
41 | void ivtv_yuv_close(struct ivtv *itv); | ||
42 | void ivtv_yuv_work_handler(struct ivtv *itv); | ||
43 | |||
44 | #endif | ||
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c new file mode 100644 index 00000000000..6b7c9c82333 --- /dev/null +++ b/drivers/media/video/ivtv/ivtvfb.c | |||
@@ -0,0 +1,1317 @@ | |||
1 | /* | ||
2 | On Screen Display cx23415 Framebuffer driver | ||
3 | |||
4 | This module presents the cx23415 OSD (onscreen display) framebuffer memory | ||
5 | as a standard Linux /dev/fb style framebuffer device. The framebuffer has | ||
6 | support for 8, 16 & 32 bpp packed pixel formats with alpha channel. In 16bpp | ||
7 | mode, there is a choice of a three color depths (12, 15 or 16 bits), but no | ||
8 | local alpha. The colorspace is selectable between rgb & yuv. | ||
9 | Depending on the TV standard configured in the ivtv module at load time, | ||
10 | the initial resolution is either 640x400 (NTSC) or 640x480 (PAL) at 8bpp. | ||
11 | Video timings are locked to ensure a vertical refresh rate of 50Hz (PAL) | ||
12 | or 59.94 (NTSC) | ||
13 | |||
14 | Copyright (c) 2003 Matt T. Yourst <yourst@yourst.com> | ||
15 | |||
16 | Derived from drivers/video/vesafb.c | ||
17 | Portions (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de> | ||
18 | |||
19 | 2.6 kernel port: | ||
20 | Copyright (C) 2004 Matthias Badaire | ||
21 | |||
22 | Copyright (C) 2004 Chris Kennedy <c@groovy.org> | ||
23 | |||
24 | Copyright (C) 2006 Ian Armstrong <ian@iarmst.demon.co.uk> | ||
25 | |||
26 | This program is free software; you can redistribute it and/or modify | ||
27 | it under the terms of the GNU General Public License as published by | ||
28 | the Free Software Foundation; either version 2 of the License, or | ||
29 | (at your option) any later version. | ||
30 | |||
31 | This program is distributed in the hope that it will be useful, | ||
32 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
33 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
34 | GNU General Public License for more details. | ||
35 | |||
36 | You should have received a copy of the GNU General Public License | ||
37 | along with this program; if not, write to the Free Software | ||
38 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
39 | */ | ||
40 | |||
41 | #include <linux/module.h> | ||
42 | #include <linux/kernel.h> | ||
43 | #include <linux/fb.h> | ||
44 | #include <linux/ivtvfb.h> | ||
45 | #include <linux/slab.h> | ||
46 | |||
47 | #ifdef CONFIG_MTRR | ||
48 | #include <asm/mtrr.h> | ||
49 | #endif | ||
50 | |||
51 | #include "ivtv-driver.h" | ||
52 | #include "ivtv-cards.h" | ||
53 | #include "ivtv-i2c.h" | ||
54 | #include "ivtv-udma.h" | ||
55 | #include "ivtv-mailbox.h" | ||
56 | #include "ivtv-firmware.h" | ||
57 | |||
58 | /* card parameters */ | ||
59 | static int ivtvfb_card_id = -1; | ||
60 | static int ivtvfb_debug = 0; | ||
61 | static int osd_laced; | ||
62 | static int osd_depth; | ||
63 | static int osd_upper; | ||
64 | static int osd_left; | ||
65 | static int osd_yres; | ||
66 | static int osd_xres; | ||
67 | |||
68 | module_param(ivtvfb_card_id, int, 0444); | ||
69 | module_param_named(debug,ivtvfb_debug, int, 0644); | ||
70 | module_param(osd_laced, bool, 0444); | ||
71 | module_param(osd_depth, int, 0444); | ||
72 | module_param(osd_upper, int, 0444); | ||
73 | module_param(osd_left, int, 0444); | ||
74 | module_param(osd_yres, int, 0444); | ||
75 | module_param(osd_xres, int, 0444); | ||
76 | |||
77 | MODULE_PARM_DESC(ivtvfb_card_id, | ||
78 | "Only use framebuffer of the specified ivtv card (0-31)\n" | ||
79 | "\t\t\tdefault -1: initialize all available framebuffers"); | ||
80 | |||
81 | MODULE_PARM_DESC(debug, | ||
82 | "Debug level (bitmask). Default: errors only\n" | ||
83 | "\t\t\t(debug = 3 gives full debugging)"); | ||
84 | |||
85 | /* Why upper, left, xres, yres, depth, laced ? To match terminology used | ||
86 | by fbset. | ||
87 | Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */ | ||
88 | |||
89 | MODULE_PARM_DESC(osd_laced, | ||
90 | "Interlaced mode\n" | ||
91 | "\t\t\t0=off\n" | ||
92 | "\t\t\t1=on\n" | ||
93 | "\t\t\tdefault off"); | ||
94 | |||
95 | MODULE_PARM_DESC(osd_depth, | ||
96 | "Bits per pixel - 8, 16, 32\n" | ||
97 | "\t\t\tdefault 8"); | ||
98 | |||
99 | MODULE_PARM_DESC(osd_upper, | ||
100 | "Vertical start position\n" | ||
101 | "\t\t\tdefault 0 (Centered)"); | ||
102 | |||
103 | MODULE_PARM_DESC(osd_left, | ||
104 | "Horizontal start position\n" | ||
105 | "\t\t\tdefault 0 (Centered)"); | ||
106 | |||
107 | MODULE_PARM_DESC(osd_yres, | ||
108 | "Display height\n" | ||
109 | "\t\t\tdefault 480 (PAL)\n" | ||
110 | "\t\t\t 400 (NTSC)"); | ||
111 | |||
112 | MODULE_PARM_DESC(osd_xres, | ||
113 | "Display width\n" | ||
114 | "\t\t\tdefault 640"); | ||
115 | |||
116 | MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil, John Harvey, Ian Armstrong"); | ||
117 | MODULE_LICENSE("GPL"); | ||
118 | |||
119 | /* --------------------------------------------------------------------- */ | ||
120 | |||
121 | #define IVTVFB_DBGFLG_WARN (1 << 0) | ||
122 | #define IVTVFB_DBGFLG_INFO (1 << 1) | ||
123 | |||
124 | #define IVTVFB_DEBUG(x, type, fmt, args...) \ | ||
125 | do { \ | ||
126 | if ((x) & ivtvfb_debug) \ | ||
127 | printk(KERN_INFO "ivtvfb%d " type ": " fmt, itv->instance , ## args); \ | ||
128 | } while (0) | ||
129 | #define IVTVFB_DEBUG_WARN(fmt, args...) IVTVFB_DEBUG(IVTVFB_DBGFLG_WARN, "warning", fmt , ## args) | ||
130 | #define IVTVFB_DEBUG_INFO(fmt, args...) IVTVFB_DEBUG(IVTVFB_DBGFLG_INFO, "info", fmt , ## args) | ||
131 | |||
132 | /* Standard kernel messages */ | ||
133 | #define IVTVFB_ERR(fmt, args...) printk(KERN_ERR "ivtvfb%d: " fmt, itv->instance , ## args) | ||
134 | #define IVTVFB_WARN(fmt, args...) printk(KERN_WARNING "ivtvfb%d: " fmt, itv->instance , ## args) | ||
135 | #define IVTVFB_INFO(fmt, args...) printk(KERN_INFO "ivtvfb%d: " fmt, itv->instance , ## args) | ||
136 | |||
137 | /* --------------------------------------------------------------------- */ | ||
138 | |||
139 | #define IVTV_OSD_MAX_WIDTH 720 | ||
140 | #define IVTV_OSD_MAX_HEIGHT 576 | ||
141 | |||
142 | #define IVTV_OSD_BPP_8 0x00 | ||
143 | #define IVTV_OSD_BPP_16_444 0x03 | ||
144 | #define IVTV_OSD_BPP_16_555 0x02 | ||
145 | #define IVTV_OSD_BPP_16_565 0x01 | ||
146 | #define IVTV_OSD_BPP_32 0x04 | ||
147 | |||
148 | struct osd_info { | ||
149 | /* Physical base address */ | ||
150 | unsigned long video_pbase; | ||
151 | /* Relative base address (relative to start of decoder memory) */ | ||
152 | u32 video_rbase; | ||
153 | /* Mapped base address */ | ||
154 | volatile char __iomem *video_vbase; | ||
155 | /* Buffer size */ | ||
156 | u32 video_buffer_size; | ||
157 | |||
158 | #ifdef CONFIG_MTRR | ||
159 | /* video_base rounded down as required by hardware MTRRs */ | ||
160 | unsigned long fb_start_aligned_physaddr; | ||
161 | /* video_base rounded up as required by hardware MTRRs */ | ||
162 | unsigned long fb_end_aligned_physaddr; | ||
163 | #endif | ||
164 | |||
165 | /* Store the buffer offset */ | ||
166 | int set_osd_coords_x; | ||
167 | int set_osd_coords_y; | ||
168 | |||
169 | /* Current dimensions (NOT VISIBLE SIZE!) */ | ||
170 | int display_width; | ||
171 | int display_height; | ||
172 | int display_byte_stride; | ||
173 | |||
174 | /* Current bits per pixel */ | ||
175 | int bits_per_pixel; | ||
176 | int bytes_per_pixel; | ||
177 | |||
178 | /* Frame buffer stuff */ | ||
179 | struct fb_info ivtvfb_info; | ||
180 | struct fb_var_screeninfo ivtvfb_defined; | ||
181 | struct fb_fix_screeninfo ivtvfb_fix; | ||
182 | |||
183 | /* Used for a warm start */ | ||
184 | struct fb_var_screeninfo fbvar_cur; | ||
185 | int blank_cur; | ||
186 | u32 palette_cur[256]; | ||
187 | u32 pan_cur; | ||
188 | }; | ||
189 | |||
190 | struct ivtv_osd_coords { | ||
191 | unsigned long offset; | ||
192 | unsigned long max_offset; | ||
193 | int pixel_stride; | ||
194 | int lines; | ||
195 | int x; | ||
196 | int y; | ||
197 | }; | ||
198 | |||
199 | /* --------------------------------------------------------------------- */ | ||
200 | |||
201 | /* ivtv API calls for framebuffer related support */ | ||
202 | |||
203 | static int ivtvfb_get_framebuffer(struct ivtv *itv, u32 *fbbase, | ||
204 | u32 *fblength) | ||
205 | { | ||
206 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
207 | int rc; | ||
208 | |||
209 | ivtv_firmware_check(itv, "ivtvfb_get_framebuffer"); | ||
210 | rc = ivtv_vapi_result(itv, data, CX2341X_OSD_GET_FRAMEBUFFER, 0); | ||
211 | *fbbase = data[0]; | ||
212 | *fblength = data[1]; | ||
213 | return rc; | ||
214 | } | ||
215 | |||
216 | static int ivtvfb_get_osd_coords(struct ivtv *itv, | ||
217 | struct ivtv_osd_coords *osd) | ||
218 | { | ||
219 | struct osd_info *oi = itv->osd_info; | ||
220 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
221 | |||
222 | ivtv_vapi_result(itv, data, CX2341X_OSD_GET_OSD_COORDS, 0); | ||
223 | |||
224 | osd->offset = data[0] - oi->video_rbase; | ||
225 | osd->max_offset = oi->display_width * oi->display_height * 4; | ||
226 | osd->pixel_stride = data[1]; | ||
227 | osd->lines = data[2]; | ||
228 | osd->x = data[3]; | ||
229 | osd->y = data[4]; | ||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | static int ivtvfb_set_osd_coords(struct ivtv *itv, const struct ivtv_osd_coords *osd) | ||
234 | { | ||
235 | struct osd_info *oi = itv->osd_info; | ||
236 | |||
237 | oi->display_width = osd->pixel_stride; | ||
238 | oi->display_byte_stride = osd->pixel_stride * oi->bytes_per_pixel; | ||
239 | oi->set_osd_coords_x += osd->x; | ||
240 | oi->set_osd_coords_y = osd->y; | ||
241 | |||
242 | return ivtv_vapi(itv, CX2341X_OSD_SET_OSD_COORDS, 5, | ||
243 | osd->offset + oi->video_rbase, | ||
244 | osd->pixel_stride, | ||
245 | osd->lines, osd->x, osd->y); | ||
246 | } | ||
247 | |||
248 | static int ivtvfb_set_display_window(struct ivtv *itv, struct v4l2_rect *ivtv_window) | ||
249 | { | ||
250 | int osd_height_limit = itv->is_out_50hz ? 576 : 480; | ||
251 | |||
252 | /* Only fail if resolution too high, otherwise fudge the start coords. */ | ||
253 | if ((ivtv_window->height > osd_height_limit) || (ivtv_window->width > IVTV_OSD_MAX_WIDTH)) | ||
254 | return -EINVAL; | ||
255 | |||
256 | /* Ensure we don't exceed display limits */ | ||
257 | if (ivtv_window->top + ivtv_window->height > osd_height_limit) { | ||
258 | IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid height setting (%d, %d)\n", | ||
259 | ivtv_window->top, ivtv_window->height); | ||
260 | ivtv_window->top = osd_height_limit - ivtv_window->height; | ||
261 | } | ||
262 | |||
263 | if (ivtv_window->left + ivtv_window->width > IVTV_OSD_MAX_WIDTH) { | ||
264 | IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid width setting (%d, %d)\n", | ||
265 | ivtv_window->left, ivtv_window->width); | ||
266 | ivtv_window->left = IVTV_OSD_MAX_WIDTH - ivtv_window->width; | ||
267 | } | ||
268 | |||
269 | /* Set the OSD origin */ | ||
270 | write_reg((ivtv_window->top << 16) | ivtv_window->left, 0x02a04); | ||
271 | |||
272 | /* How much to display */ | ||
273 | write_reg(((ivtv_window->top+ivtv_window->height) << 16) | (ivtv_window->left+ivtv_window->width), 0x02a08); | ||
274 | |||
275 | /* Pass this info back the yuv handler */ | ||
276 | itv->yuv_info.osd_vis_w = ivtv_window->width; | ||
277 | itv->yuv_info.osd_vis_h = ivtv_window->height; | ||
278 | itv->yuv_info.osd_x_offset = ivtv_window->left; | ||
279 | itv->yuv_info.osd_y_offset = ivtv_window->top; | ||
280 | |||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv, | ||
285 | unsigned long ivtv_dest_addr, void __user *userbuf, | ||
286 | int size_in_bytes) | ||
287 | { | ||
288 | DEFINE_WAIT(wait); | ||
289 | int got_sig = 0; | ||
290 | |||
291 | mutex_lock(&itv->udma.lock); | ||
292 | /* Map User DMA */ | ||
293 | if (ivtv_udma_setup(itv, ivtv_dest_addr, userbuf, size_in_bytes) <= 0) { | ||
294 | mutex_unlock(&itv->udma.lock); | ||
295 | IVTVFB_WARN("ivtvfb_prep_dec_dma_to_device, " | ||
296 | "Error with get_user_pages: %d bytes, %d pages returned\n", | ||
297 | size_in_bytes, itv->udma.page_count); | ||
298 | |||
299 | /* get_user_pages must have failed completely */ | ||
300 | return -EIO; | ||
301 | } | ||
302 | |||
303 | IVTVFB_DEBUG_INFO("ivtvfb_prep_dec_dma_to_device, %d bytes, %d pages\n", | ||
304 | size_in_bytes, itv->udma.page_count); | ||
305 | |||
306 | ivtv_udma_prepare(itv); | ||
307 | prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); | ||
308 | /* if no UDMA is pending and no UDMA is in progress, then the DMA | ||
309 | is finished */ | ||
310 | while (test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags) || | ||
311 | test_bit(IVTV_F_I_UDMA, &itv->i_flags)) { | ||
312 | /* don't interrupt if the DMA is in progress but break off | ||
313 | a still pending DMA. */ | ||
314 | got_sig = signal_pending(current); | ||
315 | if (got_sig && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags)) | ||
316 | break; | ||
317 | got_sig = 0; | ||
318 | schedule(); | ||
319 | } | ||
320 | finish_wait(&itv->dma_waitq, &wait); | ||
321 | |||
322 | /* Unmap Last DMA Xfer */ | ||
323 | ivtv_udma_unmap(itv); | ||
324 | mutex_unlock(&itv->udma.lock); | ||
325 | if (got_sig) { | ||
326 | IVTV_DEBUG_INFO("User stopped OSD\n"); | ||
327 | return -EINTR; | ||
328 | } | ||
329 | |||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source, | ||
334 | unsigned long dest_offset, int count) | ||
335 | { | ||
336 | DEFINE_WAIT(wait); | ||
337 | struct osd_info *oi = itv->osd_info; | ||
338 | |||
339 | /* Nothing to do */ | ||
340 | if (count == 0) { | ||
341 | IVTVFB_DEBUG_WARN("ivtvfb_prep_frame: Nothing to do. count = 0\n"); | ||
342 | return -EINVAL; | ||
343 | } | ||
344 | |||
345 | /* Check Total FB Size */ | ||
346 | if ((dest_offset + count) > oi->video_buffer_size) { | ||
347 | IVTVFB_WARN("ivtvfb_prep_frame: Overflowing the framebuffer %ld, only %d available\n", | ||
348 | dest_offset + count, oi->video_buffer_size); | ||
349 | return -E2BIG; | ||
350 | } | ||
351 | |||
352 | /* Not fatal, but will have undesirable results */ | ||
353 | if ((unsigned long)source & 3) | ||
354 | IVTVFB_WARN("ivtvfb_prep_frame: Source address not 32 bit aligned (0x%08lx)\n", | ||
355 | (unsigned long)source); | ||
356 | |||
357 | if (dest_offset & 3) | ||
358 | IVTVFB_WARN("ivtvfb_prep_frame: Dest offset not 32 bit aligned (%ld)\n", dest_offset); | ||
359 | |||
360 | if (count & 3) | ||
361 | IVTVFB_WARN("ivtvfb_prep_frame: Count not a multiple of 4 (%d)\n", count); | ||
362 | |||
363 | /* Check Source */ | ||
364 | if (!access_ok(VERIFY_READ, source + dest_offset, count)) { | ||
365 | IVTVFB_WARN("Invalid userspace pointer 0x%08lx\n", | ||
366 | (unsigned long)source); | ||
367 | |||
368 | IVTVFB_DEBUG_WARN("access_ok() failed for offset 0x%08lx source 0x%08lx count %d\n", | ||
369 | dest_offset, (unsigned long)source, | ||
370 | count); | ||
371 | return -EINVAL; | ||
372 | } | ||
373 | |||
374 | /* OSD Address to send DMA to */ | ||
375 | dest_offset += IVTV_DECODER_OFFSET + oi->video_rbase; | ||
376 | |||
377 | /* Fill Buffers */ | ||
378 | return ivtvfb_prep_dec_dma_to_device(itv, dest_offset, source, count); | ||
379 | } | ||
380 | |||
381 | static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf, | ||
382 | size_t count, loff_t *ppos) | ||
383 | { | ||
384 | unsigned long p = *ppos; | ||
385 | void *dst; | ||
386 | int err = 0; | ||
387 | int dma_err; | ||
388 | unsigned long total_size; | ||
389 | struct ivtv *itv = (struct ivtv *) info->par; | ||
390 | unsigned long dma_offset = | ||
391 | IVTV_DECODER_OFFSET + itv->osd_info->video_rbase; | ||
392 | unsigned long dma_size; | ||
393 | u16 lead = 0, tail = 0; | ||
394 | |||
395 | if (info->state != FBINFO_STATE_RUNNING) | ||
396 | return -EPERM; | ||
397 | |||
398 | total_size = info->screen_size; | ||
399 | |||
400 | if (total_size == 0) | ||
401 | total_size = info->fix.smem_len; | ||
402 | |||
403 | if (p > total_size) | ||
404 | return -EFBIG; | ||
405 | |||
406 | if (count > total_size) { | ||
407 | err = -EFBIG; | ||
408 | count = total_size; | ||
409 | } | ||
410 | |||
411 | if (count + p > total_size) { | ||
412 | if (!err) | ||
413 | err = -ENOSPC; | ||
414 | count = total_size - p; | ||
415 | } | ||
416 | |||
417 | dst = (void __force *) (info->screen_base + p); | ||
418 | |||
419 | if (info->fbops->fb_sync) | ||
420 | info->fbops->fb_sync(info); | ||
421 | |||
422 | /* If transfer size > threshold and both src/dst | ||
423 | addresses are aligned, use DMA */ | ||
424 | if (count >= 4096 && | ||
425 | ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) { | ||
426 | /* Odd address = can't DMA. Align */ | ||
427 | if ((unsigned long)dst & 3) { | ||
428 | lead = 4 - ((unsigned long)dst & 3); | ||
429 | if (copy_from_user(dst, buf, lead)) | ||
430 | return -EFAULT; | ||
431 | buf += lead; | ||
432 | dst += lead; | ||
433 | } | ||
434 | /* DMA resolution is 32 bits */ | ||
435 | if ((count - lead) & 3) | ||
436 | tail = (count - lead) & 3; | ||
437 | /* DMA the data */ | ||
438 | dma_size = count - lead - tail; | ||
439 | dma_err = ivtvfb_prep_dec_dma_to_device(itv, | ||
440 | p + lead + dma_offset, (void __user *)buf, dma_size); | ||
441 | if (dma_err) | ||
442 | return dma_err; | ||
443 | dst += dma_size; | ||
444 | buf += dma_size; | ||
445 | /* Copy any leftover data */ | ||
446 | if (tail && copy_from_user(dst, buf, tail)) | ||
447 | return -EFAULT; | ||
448 | } else if (copy_from_user(dst, buf, count)) { | ||
449 | return -EFAULT; | ||
450 | } | ||
451 | |||
452 | if (!err) | ||
453 | *ppos += count; | ||
454 | |||
455 | return (err) ? err : count; | ||
456 | } | ||
457 | |||
458 | static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) | ||
459 | { | ||
460 | DEFINE_WAIT(wait); | ||
461 | struct ivtv *itv = (struct ivtv *)info->par; | ||
462 | int rc = 0; | ||
463 | |||
464 | switch (cmd) { | ||
465 | case FBIOGET_VBLANK: { | ||
466 | struct fb_vblank vblank; | ||
467 | u32 trace; | ||
468 | |||
469 | memset(&vblank, 0, sizeof(struct fb_vblank)); | ||
470 | |||
471 | vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT | | ||
472 | FB_VBLANK_HAVE_VSYNC; | ||
473 | trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16; | ||
474 | if (itv->is_out_50hz && trace > 312) | ||
475 | trace -= 312; | ||
476 | else if (itv->is_out_60hz && trace > 262) | ||
477 | trace -= 262; | ||
478 | if (trace == 1) | ||
479 | vblank.flags |= FB_VBLANK_VSYNCING; | ||
480 | vblank.count = itv->last_vsync_field; | ||
481 | vblank.vcount = trace; | ||
482 | vblank.hcount = 0; | ||
483 | if (copy_to_user((void __user *)arg, &vblank, sizeof(vblank))) | ||
484 | return -EFAULT; | ||
485 | return 0; | ||
486 | } | ||
487 | |||
488 | case FBIO_WAITFORVSYNC: | ||
489 | prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE); | ||
490 | if (!schedule_timeout(msecs_to_jiffies(50))) | ||
491 | rc = -ETIMEDOUT; | ||
492 | finish_wait(&itv->vsync_waitq, &wait); | ||
493 | return rc; | ||
494 | |||
495 | case IVTVFB_IOC_DMA_FRAME: { | ||
496 | struct ivtvfb_dma_frame args; | ||
497 | |||
498 | IVTVFB_DEBUG_INFO("IVTVFB_IOC_DMA_FRAME\n"); | ||
499 | if (copy_from_user(&args, (void __user *)arg, sizeof(args))) | ||
500 | return -EFAULT; | ||
501 | |||
502 | return ivtvfb_prep_frame(itv, cmd, args.source, args.dest_offset, args.count); | ||
503 | } | ||
504 | |||
505 | default: | ||
506 | IVTVFB_DEBUG_INFO("Unknown ioctl %08x\n", cmd); | ||
507 | return -EINVAL; | ||
508 | } | ||
509 | return 0; | ||
510 | } | ||
511 | |||
512 | /* Framebuffer device handling */ | ||
513 | |||
514 | static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var) | ||
515 | { | ||
516 | struct osd_info *oi = itv->osd_info; | ||
517 | struct ivtv_osd_coords ivtv_osd; | ||
518 | struct v4l2_rect ivtv_window; | ||
519 | int osd_mode = -1; | ||
520 | |||
521 | IVTVFB_DEBUG_INFO("ivtvfb_set_var\n"); | ||
522 | |||
523 | /* Select color space */ | ||
524 | if (var->nonstd) /* YUV */ | ||
525 | write_reg(read_reg(0x02a00) | 0x0002000, 0x02a00); | ||
526 | else /* RGB */ | ||
527 | write_reg(read_reg(0x02a00) & ~0x0002000, 0x02a00); | ||
528 | |||
529 | /* Set the color mode */ | ||
530 | switch (var->bits_per_pixel) { | ||
531 | case 8: | ||
532 | osd_mode = IVTV_OSD_BPP_8; | ||
533 | break; | ||
534 | case 32: | ||
535 | osd_mode = IVTV_OSD_BPP_32; | ||
536 | break; | ||
537 | case 16: | ||
538 | switch (var->green.length) { | ||
539 | case 4: | ||
540 | osd_mode = IVTV_OSD_BPP_16_444; | ||
541 | break; | ||
542 | case 5: | ||
543 | osd_mode = IVTV_OSD_BPP_16_555; | ||
544 | break; | ||
545 | case 6: | ||
546 | osd_mode = IVTV_OSD_BPP_16_565; | ||
547 | break; | ||
548 | default: | ||
549 | IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n"); | ||
550 | } | ||
551 | break; | ||
552 | default: | ||
553 | IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n"); | ||
554 | } | ||
555 | |||
556 | /* Set video mode. Although rare, the display can become scrambled even | ||
557 | if we don't change mode. Always 'bounce' to osd_mode via mode 0 */ | ||
558 | if (osd_mode != -1) { | ||
559 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); | ||
560 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode); | ||
561 | } | ||
562 | |||
563 | oi->bits_per_pixel = var->bits_per_pixel; | ||
564 | oi->bytes_per_pixel = var->bits_per_pixel / 8; | ||
565 | |||
566 | /* Set the flicker filter */ | ||
567 | switch (var->vmode & FB_VMODE_MASK) { | ||
568 | case FB_VMODE_NONINTERLACED: /* Filter on */ | ||
569 | ivtv_vapi(itv, CX2341X_OSD_SET_FLICKER_STATE, 1, 1); | ||
570 | break; | ||
571 | case FB_VMODE_INTERLACED: /* Filter off */ | ||
572 | ivtv_vapi(itv, CX2341X_OSD_SET_FLICKER_STATE, 1, 0); | ||
573 | break; | ||
574 | default: | ||
575 | IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid video mode\n"); | ||
576 | } | ||
577 | |||
578 | /* Read the current osd info */ | ||
579 | ivtvfb_get_osd_coords(itv, &ivtv_osd); | ||
580 | |||
581 | /* Now set the OSD to the size we want */ | ||
582 | ivtv_osd.pixel_stride = var->xres_virtual; | ||
583 | ivtv_osd.lines = var->yres_virtual; | ||
584 | ivtv_osd.x = 0; | ||
585 | ivtv_osd.y = 0; | ||
586 | ivtvfb_set_osd_coords(itv, &ivtv_osd); | ||
587 | |||
588 | /* Can't seem to find the right API combo for this. | ||
589 | Use another function which does what we need through direct register access. */ | ||
590 | ivtv_window.width = var->xres; | ||
591 | ivtv_window.height = var->yres; | ||
592 | |||
593 | /* Minimum margin cannot be 0, as X won't allow such a mode */ | ||
594 | if (!var->upper_margin) | ||
595 | var->upper_margin++; | ||
596 | if (!var->left_margin) | ||
597 | var->left_margin++; | ||
598 | ivtv_window.top = var->upper_margin - 1; | ||
599 | ivtv_window.left = var->left_margin - 1; | ||
600 | |||
601 | ivtvfb_set_display_window(itv, &ivtv_window); | ||
602 | |||
603 | /* Pass screen size back to yuv handler */ | ||
604 | itv->yuv_info.osd_full_w = ivtv_osd.pixel_stride; | ||
605 | itv->yuv_info.osd_full_h = ivtv_osd.lines; | ||
606 | |||
607 | /* Force update of yuv registers */ | ||
608 | itv->yuv_info.yuv_forced_update = 1; | ||
609 | |||
610 | /* Keep a copy of these settings */ | ||
611 | memcpy(&oi->fbvar_cur, var, sizeof(oi->fbvar_cur)); | ||
612 | |||
613 | IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n", | ||
614 | var->xres, var->yres, | ||
615 | var->xres_virtual, var->yres_virtual, | ||
616 | var->bits_per_pixel); | ||
617 | |||
618 | IVTVFB_DEBUG_INFO("Display position: %d, %d\n", | ||
619 | var->left_margin, var->upper_margin); | ||
620 | |||
621 | IVTVFB_DEBUG_INFO("Display filter: %s\n", | ||
622 | (var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off"); | ||
623 | IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB"); | ||
624 | |||
625 | return 0; | ||
626 | } | ||
627 | |||
628 | static int ivtvfb_get_fix(struct ivtv *itv, struct fb_fix_screeninfo *fix) | ||
629 | { | ||
630 | struct osd_info *oi = itv->osd_info; | ||
631 | |||
632 | IVTVFB_DEBUG_INFO("ivtvfb_get_fix\n"); | ||
633 | memset(fix, 0, sizeof(struct fb_fix_screeninfo)); | ||
634 | strlcpy(fix->id, "cx23415 TV out", sizeof(fix->id)); | ||
635 | fix->smem_start = oi->video_pbase; | ||
636 | fix->smem_len = oi->video_buffer_size; | ||
637 | fix->type = FB_TYPE_PACKED_PIXELS; | ||
638 | fix->visual = (oi->bits_per_pixel == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; | ||
639 | fix->xpanstep = 1; | ||
640 | fix->ypanstep = 1; | ||
641 | fix->ywrapstep = 0; | ||
642 | fix->line_length = oi->display_byte_stride; | ||
643 | fix->accel = FB_ACCEL_NONE; | ||
644 | return 0; | ||
645 | } | ||
646 | |||
647 | /* Check the requested display mode, returning -EINVAL if we can't | ||
648 | handle it. */ | ||
649 | |||
650 | static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv) | ||
651 | { | ||
652 | struct osd_info *oi = itv->osd_info; | ||
653 | int osd_height_limit; | ||
654 | u32 pixclock, hlimit, vlimit; | ||
655 | |||
656 | IVTVFB_DEBUG_INFO("ivtvfb_check_var\n"); | ||
657 | |||
658 | /* Set base references for mode calcs. */ | ||
659 | if (itv->is_out_50hz) { | ||
660 | pixclock = 84316; | ||
661 | hlimit = 776; | ||
662 | vlimit = 591; | ||
663 | osd_height_limit = 576; | ||
664 | } | ||
665 | else { | ||
666 | pixclock = 83926; | ||
667 | hlimit = 776; | ||
668 | vlimit = 495; | ||
669 | osd_height_limit = 480; | ||
670 | } | ||
671 | |||
672 | if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) { | ||
673 | var->transp.offset = 24; | ||
674 | var->transp.length = 8; | ||
675 | var->red.offset = 16; | ||
676 | var->red.length = 8; | ||
677 | var->green.offset = 8; | ||
678 | var->green.length = 8; | ||
679 | var->blue.offset = 0; | ||
680 | var->blue.length = 8; | ||
681 | } | ||
682 | else if (var->bits_per_pixel == 16) { | ||
683 | /* To find out the true mode, check green length */ | ||
684 | switch (var->green.length) { | ||
685 | case 4: | ||
686 | var->red.offset = 8; | ||
687 | var->red.length = 4; | ||
688 | var->green.offset = 4; | ||
689 | var->green.length = 4; | ||
690 | var->blue.offset = 0; | ||
691 | var->blue.length = 4; | ||
692 | var->transp.offset = 12; | ||
693 | var->transp.length = 1; | ||
694 | break; | ||
695 | case 5: | ||
696 | var->red.offset = 10; | ||
697 | var->red.length = 5; | ||
698 | var->green.offset = 5; | ||
699 | var->green.length = 5; | ||
700 | var->blue.offset = 0; | ||
701 | var->blue.length = 5; | ||
702 | var->transp.offset = 15; | ||
703 | var->transp.length = 1; | ||
704 | break; | ||
705 | default: | ||
706 | var->red.offset = 11; | ||
707 | var->red.length = 5; | ||
708 | var->green.offset = 5; | ||
709 | var->green.length = 6; | ||
710 | var->blue.offset = 0; | ||
711 | var->blue.length = 5; | ||
712 | var->transp.offset = 0; | ||
713 | var->transp.length = 0; | ||
714 | break; | ||
715 | } | ||
716 | } | ||
717 | else { | ||
718 | IVTVFB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel); | ||
719 | return -EINVAL; | ||
720 | } | ||
721 | |||
722 | /* Check the resolution */ | ||
723 | if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) { | ||
724 | IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n", | ||
725 | var->xres, var->yres); | ||
726 | return -EINVAL; | ||
727 | } | ||
728 | |||
729 | /* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */ | ||
730 | if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) || | ||
731 | var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size || | ||
732 | var->xres_virtual < var->xres || | ||
733 | var->yres_virtual < var->yres) { | ||
734 | IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n", | ||
735 | var->xres_virtual, var->yres_virtual); | ||
736 | return -EINVAL; | ||
737 | } | ||
738 | |||
739 | /* Some extra checks if in 8 bit mode */ | ||
740 | if (var->bits_per_pixel == 8) { | ||
741 | /* Width must be a multiple of 4 */ | ||
742 | if (var->xres & 3) { | ||
743 | IVTVFB_DEBUG_WARN("Invalid resolution for 8bpp: %d\n", var->xres); | ||
744 | return -EINVAL; | ||
745 | } | ||
746 | if (var->xres_virtual & 3) { | ||
747 | IVTVFB_DEBUG_WARN("Invalid virtual resolution for 8bpp: %d)\n", var->xres_virtual); | ||
748 | return -EINVAL; | ||
749 | } | ||
750 | } | ||
751 | else if (var->bits_per_pixel == 16) { | ||
752 | /* Width must be a multiple of 2 */ | ||
753 | if (var->xres & 1) { | ||
754 | IVTVFB_DEBUG_WARN("Invalid resolution for 16bpp: %d\n", var->xres); | ||
755 | return -EINVAL; | ||
756 | } | ||
757 | if (var->xres_virtual & 1) { | ||
758 | IVTVFB_DEBUG_WARN("Invalid virtual resolution for 16bpp: %d)\n", var->xres_virtual); | ||
759 | return -EINVAL; | ||
760 | } | ||
761 | } | ||
762 | |||
763 | /* Now check the offsets */ | ||
764 | if (var->xoffset >= var->xres_virtual || var->yoffset >= var->yres_virtual) { | ||
765 | IVTVFB_DEBUG_WARN("Invalid offset: %d (%d) %d (%d)\n", | ||
766 | var->xoffset, var->xres_virtual, var->yoffset, var->yres_virtual); | ||
767 | return -EINVAL; | ||
768 | } | ||
769 | |||
770 | /* Check pixel format */ | ||
771 | if (var->nonstd > 1) { | ||
772 | IVTVFB_DEBUG_WARN("Invalid nonstd % d\n", var->nonstd); | ||
773 | return -EINVAL; | ||
774 | } | ||
775 | |||
776 | /* Check video mode */ | ||
777 | if (((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) && | ||
778 | ((var->vmode & FB_VMODE_MASK) != FB_VMODE_INTERLACED)) { | ||
779 | IVTVFB_DEBUG_WARN("Invalid video mode: %d\n", var->vmode & FB_VMODE_MASK); | ||
780 | return -EINVAL; | ||
781 | } | ||
782 | |||
783 | /* Check the left & upper margins | ||
784 | If the margins are too large, just center the screen | ||
785 | (enforcing margins causes too many problems) */ | ||
786 | |||
787 | if (var->left_margin + var->xres > IVTV_OSD_MAX_WIDTH + 1) | ||
788 | var->left_margin = 1 + ((IVTV_OSD_MAX_WIDTH - var->xres) / 2); | ||
789 | |||
790 | if (var->upper_margin + var->yres > (itv->is_out_50hz ? 577 : 481)) | ||
791 | var->upper_margin = 1 + (((itv->is_out_50hz ? 576 : 480) - | ||
792 | var->yres) / 2); | ||
793 | |||
794 | /* Maintain overall 'size' for a constant refresh rate */ | ||
795 | var->right_margin = hlimit - var->left_margin - var->xres; | ||
796 | var->lower_margin = vlimit - var->upper_margin - var->yres; | ||
797 | |||
798 | /* Fixed sync times */ | ||
799 | var->hsync_len = 24; | ||
800 | var->vsync_len = 2; | ||
801 | |||
802 | /* Non-interlaced / interlaced mode is used to switch the OSD filter | ||
803 | on or off. Adjust the clock timings to maintain a constant | ||
804 | vertical refresh rate. */ | ||
805 | if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) | ||
806 | var->pixclock = pixclock / 2; | ||
807 | else | ||
808 | var->pixclock = pixclock; | ||
809 | |||
810 | itv->osd_rect.width = var->xres; | ||
811 | itv->osd_rect.height = var->yres; | ||
812 | |||
813 | IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n", | ||
814 | var->xres, var->yres, | ||
815 | var->xres_virtual, var->yres_virtual, | ||
816 | var->bits_per_pixel); | ||
817 | |||
818 | IVTVFB_DEBUG_INFO("Display position: %d, %d\n", | ||
819 | var->left_margin, var->upper_margin); | ||
820 | |||
821 | IVTVFB_DEBUG_INFO("Display filter: %s\n", | ||
822 | (var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off"); | ||
823 | IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB"); | ||
824 | return 0; | ||
825 | } | ||
826 | |||
827 | static int ivtvfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | ||
828 | { | ||
829 | struct ivtv *itv = (struct ivtv *) info->par; | ||
830 | IVTVFB_DEBUG_INFO("ivtvfb_check_var\n"); | ||
831 | return _ivtvfb_check_var(var, itv); | ||
832 | } | ||
833 | |||
834 | static int ivtvfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | ||
835 | { | ||
836 | u32 osd_pan_index; | ||
837 | struct ivtv *itv = (struct ivtv *) info->par; | ||
838 | |||
839 | if (var->yoffset + info->var.yres > info->var.yres_virtual || | ||
840 | var->xoffset + info->var.xres > info->var.xres_virtual) | ||
841 | return -EINVAL; | ||
842 | |||
843 | osd_pan_index = var->yoffset * info->fix.line_length | ||
844 | + var->xoffset * info->var.bits_per_pixel / 8; | ||
845 | write_reg(osd_pan_index, 0x02A0C); | ||
846 | |||
847 | /* Pass this info back the yuv handler */ | ||
848 | itv->yuv_info.osd_x_pan = var->xoffset; | ||
849 | itv->yuv_info.osd_y_pan = var->yoffset; | ||
850 | /* Force update of yuv registers */ | ||
851 | itv->yuv_info.yuv_forced_update = 1; | ||
852 | /* Remember this value */ | ||
853 | itv->osd_info->pan_cur = osd_pan_index; | ||
854 | return 0; | ||
855 | } | ||
856 | |||
857 | static int ivtvfb_set_par(struct fb_info *info) | ||
858 | { | ||
859 | int rc = 0; | ||
860 | struct ivtv *itv = (struct ivtv *) info->par; | ||
861 | |||
862 | IVTVFB_DEBUG_INFO("ivtvfb_set_par\n"); | ||
863 | |||
864 | rc = ivtvfb_set_var(itv, &info->var); | ||
865 | ivtvfb_pan_display(&info->var, info); | ||
866 | ivtvfb_get_fix(itv, &info->fix); | ||
867 | ivtv_firmware_check(itv, "ivtvfb_set_par"); | ||
868 | return rc; | ||
869 | } | ||
870 | |||
871 | static int ivtvfb_setcolreg(unsigned regno, unsigned red, unsigned green, | ||
872 | unsigned blue, unsigned transp, | ||
873 | struct fb_info *info) | ||
874 | { | ||
875 | u32 color, *palette; | ||
876 | struct ivtv *itv = (struct ivtv *)info->par; | ||
877 | |||
878 | if (regno >= info->cmap.len) | ||
879 | return -EINVAL; | ||
880 | |||
881 | color = ((transp & 0xFF00) << 16) |((red & 0xFF00) << 8) | (green & 0xFF00) | ((blue & 0xFF00) >> 8); | ||
882 | if (info->var.bits_per_pixel <= 8) { | ||
883 | write_reg(regno, 0x02a30); | ||
884 | write_reg(color, 0x02a34); | ||
885 | itv->osd_info->palette_cur[regno] = color; | ||
886 | return 0; | ||
887 | } | ||
888 | if (regno >= 16) | ||
889 | return -EINVAL; | ||
890 | |||
891 | palette = info->pseudo_palette; | ||
892 | if (info->var.bits_per_pixel == 16) { | ||
893 | switch (info->var.green.length) { | ||
894 | case 4: | ||
895 | color = ((red & 0xf000) >> 4) | | ||
896 | ((green & 0xf000) >> 8) | | ||
897 | ((blue & 0xf000) >> 12); | ||
898 | break; | ||
899 | case 5: | ||
900 | color = ((red & 0xf800) >> 1) | | ||
901 | ((green & 0xf800) >> 6) | | ||
902 | ((blue & 0xf800) >> 11); | ||
903 | break; | ||
904 | case 6: | ||
905 | color = (red & 0xf800 ) | | ||
906 | ((green & 0xfc00) >> 5) | | ||
907 | ((blue & 0xf800) >> 11); | ||
908 | break; | ||
909 | } | ||
910 | } | ||
911 | palette[regno] = color; | ||
912 | return 0; | ||
913 | } | ||
914 | |||
915 | /* We don't really support blanking. All this does is enable or | ||
916 | disable the OSD. */ | ||
917 | static int ivtvfb_blank(int blank_mode, struct fb_info *info) | ||
918 | { | ||
919 | struct ivtv *itv = (struct ivtv *)info->par; | ||
920 | |||
921 | IVTVFB_DEBUG_INFO("Set blanking mode : %d\n", blank_mode); | ||
922 | switch (blank_mode) { | ||
923 | case FB_BLANK_UNBLANK: | ||
924 | ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 1); | ||
925 | ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1); | ||
926 | break; | ||
927 | case FB_BLANK_NORMAL: | ||
928 | case FB_BLANK_HSYNC_SUSPEND: | ||
929 | case FB_BLANK_VSYNC_SUSPEND: | ||
930 | ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0); | ||
931 | ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1); | ||
932 | break; | ||
933 | case FB_BLANK_POWERDOWN: | ||
934 | ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 0); | ||
935 | ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0); | ||
936 | break; | ||
937 | } | ||
938 | itv->osd_info->blank_cur = blank_mode; | ||
939 | return 0; | ||
940 | } | ||
941 | |||
942 | static struct fb_ops ivtvfb_ops = { | ||
943 | .owner = THIS_MODULE, | ||
944 | .fb_write = ivtvfb_write, | ||
945 | .fb_check_var = ivtvfb_check_var, | ||
946 | .fb_set_par = ivtvfb_set_par, | ||
947 | .fb_setcolreg = ivtvfb_setcolreg, | ||
948 | .fb_fillrect = cfb_fillrect, | ||
949 | .fb_copyarea = cfb_copyarea, | ||
950 | .fb_imageblit = cfb_imageblit, | ||
951 | .fb_cursor = NULL, | ||
952 | .fb_ioctl = ivtvfb_ioctl, | ||
953 | .fb_pan_display = ivtvfb_pan_display, | ||
954 | .fb_blank = ivtvfb_blank, | ||
955 | }; | ||
956 | |||
957 | /* Restore hardware after firmware restart */ | ||
958 | static void ivtvfb_restore(struct ivtv *itv) | ||
959 | { | ||
960 | struct osd_info *oi = itv->osd_info; | ||
961 | int i; | ||
962 | |||
963 | ivtvfb_set_var(itv, &oi->fbvar_cur); | ||
964 | ivtvfb_blank(oi->blank_cur, &oi->ivtvfb_info); | ||
965 | for (i = 0; i < 256; i++) { | ||
966 | write_reg(i, 0x02a30); | ||
967 | write_reg(oi->palette_cur[i], 0x02a34); | ||
968 | } | ||
969 | write_reg(oi->pan_cur, 0x02a0c); | ||
970 | } | ||
971 | |||
972 | /* Initialization */ | ||
973 | |||
974 | |||
975 | /* Setup our initial video mode */ | ||
976 | static int ivtvfb_init_vidmode(struct ivtv *itv) | ||
977 | { | ||
978 | struct osd_info *oi = itv->osd_info; | ||
979 | struct v4l2_rect start_window; | ||
980 | int max_height; | ||
981 | |||
982 | /* Color mode */ | ||
983 | |||
984 | if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32) | ||
985 | osd_depth = 8; | ||
986 | oi->bits_per_pixel = osd_depth; | ||
987 | oi->bytes_per_pixel = oi->bits_per_pixel / 8; | ||
988 | |||
989 | /* Horizontal size & position */ | ||
990 | |||
991 | if (osd_xres > 720) | ||
992 | osd_xres = 720; | ||
993 | |||
994 | /* Must be a multiple of 4 for 8bpp & 2 for 16bpp */ | ||
995 | if (osd_depth == 8) | ||
996 | osd_xres &= ~3; | ||
997 | else if (osd_depth == 16) | ||
998 | osd_xres &= ~1; | ||
999 | |||
1000 | start_window.width = osd_xres ? osd_xres : 640; | ||
1001 | |||
1002 | /* Check horizontal start (osd_left). */ | ||
1003 | if (osd_left && osd_left + start_window.width > 721) { | ||
1004 | IVTVFB_ERR("Invalid osd_left - assuming default\n"); | ||
1005 | osd_left = 0; | ||
1006 | } | ||
1007 | |||
1008 | /* Hardware coords start at 0, user coords start at 1. */ | ||
1009 | osd_left--; | ||
1010 | |||
1011 | start_window.left = osd_left >= 0 ? | ||
1012 | osd_left : ((IVTV_OSD_MAX_WIDTH - start_window.width) / 2); | ||
1013 | |||
1014 | oi->display_byte_stride = | ||
1015 | start_window.width * oi->bytes_per_pixel; | ||
1016 | |||
1017 | /* Vertical size & position */ | ||
1018 | |||
1019 | max_height = itv->is_out_50hz ? 576 : 480; | ||
1020 | |||
1021 | if (osd_yres > max_height) | ||
1022 | osd_yres = max_height; | ||
1023 | |||
1024 | start_window.height = osd_yres ? | ||
1025 | osd_yres : itv->is_out_50hz ? 480 : 400; | ||
1026 | |||
1027 | /* Check vertical start (osd_upper). */ | ||
1028 | if (osd_upper + start_window.height > max_height + 1) { | ||
1029 | IVTVFB_ERR("Invalid osd_upper - assuming default\n"); | ||
1030 | osd_upper = 0; | ||
1031 | } | ||
1032 | |||
1033 | /* Hardware coords start at 0, user coords start at 1. */ | ||
1034 | osd_upper--; | ||
1035 | |||
1036 | start_window.top = osd_upper >= 0 ? osd_upper : ((max_height - start_window.height) / 2); | ||
1037 | |||
1038 | oi->display_width = start_window.width; | ||
1039 | oi->display_height = start_window.height; | ||
1040 | |||
1041 | /* Generate a valid fb_var_screeninfo */ | ||
1042 | |||
1043 | oi->ivtvfb_defined.xres = oi->display_width; | ||
1044 | oi->ivtvfb_defined.yres = oi->display_height; | ||
1045 | oi->ivtvfb_defined.xres_virtual = oi->display_width; | ||
1046 | oi->ivtvfb_defined.yres_virtual = oi->display_height; | ||
1047 | oi->ivtvfb_defined.bits_per_pixel = oi->bits_per_pixel; | ||
1048 | oi->ivtvfb_defined.vmode = (osd_laced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED); | ||
1049 | oi->ivtvfb_defined.left_margin = start_window.left + 1; | ||
1050 | oi->ivtvfb_defined.upper_margin = start_window.top + 1; | ||
1051 | oi->ivtvfb_defined.accel_flags = FB_ACCEL_NONE; | ||
1052 | oi->ivtvfb_defined.nonstd = 0; | ||
1053 | |||
1054 | /* We've filled in the most data, let the usual mode check | ||
1055 | routine fill in the rest. */ | ||
1056 | _ivtvfb_check_var(&oi->ivtvfb_defined, itv); | ||
1057 | |||
1058 | /* Generate valid fb_fix_screeninfo */ | ||
1059 | |||
1060 | ivtvfb_get_fix(itv, &oi->ivtvfb_fix); | ||
1061 | |||
1062 | /* Generate valid fb_info */ | ||
1063 | |||
1064 | oi->ivtvfb_info.node = -1; | ||
1065 | oi->ivtvfb_info.flags = FBINFO_FLAG_DEFAULT; | ||
1066 | oi->ivtvfb_info.fbops = &ivtvfb_ops; | ||
1067 | oi->ivtvfb_info.par = itv; | ||
1068 | oi->ivtvfb_info.var = oi->ivtvfb_defined; | ||
1069 | oi->ivtvfb_info.fix = oi->ivtvfb_fix; | ||
1070 | oi->ivtvfb_info.screen_base = (u8 __iomem *)oi->video_vbase; | ||
1071 | oi->ivtvfb_info.fbops = &ivtvfb_ops; | ||
1072 | |||
1073 | /* Supply some monitor specs. Bogus values will do for now */ | ||
1074 | oi->ivtvfb_info.monspecs.hfmin = 8000; | ||
1075 | oi->ivtvfb_info.monspecs.hfmax = 70000; | ||
1076 | oi->ivtvfb_info.monspecs.vfmin = 10; | ||
1077 | oi->ivtvfb_info.monspecs.vfmax = 100; | ||
1078 | |||
1079 | /* Allocate color map */ | ||
1080 | if (fb_alloc_cmap(&oi->ivtvfb_info.cmap, 256, 1)) { | ||
1081 | IVTVFB_ERR("abort, unable to alloc cmap\n"); | ||
1082 | return -ENOMEM; | ||
1083 | } | ||
1084 | |||
1085 | /* Allocate the pseudo palette */ | ||
1086 | oi->ivtvfb_info.pseudo_palette = | ||
1087 | kmalloc(sizeof(u32) * 16, GFP_KERNEL|__GFP_NOWARN); | ||
1088 | |||
1089 | if (!oi->ivtvfb_info.pseudo_palette) { | ||
1090 | IVTVFB_ERR("abort, unable to alloc pseudo palette\n"); | ||
1091 | return -ENOMEM; | ||
1092 | } | ||
1093 | |||
1094 | return 0; | ||
1095 | } | ||
1096 | |||
1097 | /* Find OSD buffer base & size. Add to mtrr. Zero osd buffer. */ | ||
1098 | |||
1099 | static int ivtvfb_init_io(struct ivtv *itv) | ||
1100 | { | ||
1101 | struct osd_info *oi = itv->osd_info; | ||
1102 | |||
1103 | mutex_lock(&itv->serialize_lock); | ||
1104 | if (ivtv_init_on_first_open(itv)) { | ||
1105 | mutex_unlock(&itv->serialize_lock); | ||
1106 | IVTVFB_ERR("Failed to initialize ivtv\n"); | ||
1107 | return -ENXIO; | ||
1108 | } | ||
1109 | mutex_unlock(&itv->serialize_lock); | ||
1110 | |||
1111 | if (ivtvfb_get_framebuffer(itv, &oi->video_rbase, | ||
1112 | &oi->video_buffer_size) < 0) { | ||
1113 | IVTVFB_ERR("Firmware failed to respond\n"); | ||
1114 | return -EIO; | ||
1115 | } | ||
1116 | |||
1117 | /* The osd buffer size depends on the number of video buffers allocated | ||
1118 | on the PVR350 itself. For now we'll hardcode the smallest osd buffer | ||
1119 | size to prevent any overlap. */ | ||
1120 | oi->video_buffer_size = 1704960; | ||
1121 | |||
1122 | oi->video_pbase = itv->base_addr + IVTV_DECODER_OFFSET + oi->video_rbase; | ||
1123 | oi->video_vbase = itv->dec_mem + oi->video_rbase; | ||
1124 | |||
1125 | if (!oi->video_vbase) { | ||
1126 | IVTVFB_ERR("abort, video memory 0x%x @ 0x%lx isn't mapped!\n", | ||
1127 | oi->video_buffer_size, oi->video_pbase); | ||
1128 | return -EIO; | ||
1129 | } | ||
1130 | |||
1131 | IVTVFB_INFO("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n", | ||
1132 | oi->video_pbase, oi->video_vbase, | ||
1133 | oi->video_buffer_size / 1024); | ||
1134 | |||
1135 | #ifdef CONFIG_MTRR | ||
1136 | { | ||
1137 | /* Find the largest power of two that maps the whole buffer */ | ||
1138 | int size_shift = 31; | ||
1139 | |||
1140 | while (!(oi->video_buffer_size & (1 << size_shift))) { | ||
1141 | size_shift--; | ||
1142 | } | ||
1143 | size_shift++; | ||
1144 | oi->fb_start_aligned_physaddr = oi->video_pbase & ~((1 << size_shift) - 1); | ||
1145 | oi->fb_end_aligned_physaddr = oi->video_pbase + oi->video_buffer_size; | ||
1146 | oi->fb_end_aligned_physaddr += (1 << size_shift) - 1; | ||
1147 | oi->fb_end_aligned_physaddr &= ~((1 << size_shift) - 1); | ||
1148 | if (mtrr_add(oi->fb_start_aligned_physaddr, | ||
1149 | oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr, | ||
1150 | MTRR_TYPE_WRCOMB, 1) < 0) { | ||
1151 | IVTVFB_INFO("disabled mttr\n"); | ||
1152 | oi->fb_start_aligned_physaddr = 0; | ||
1153 | oi->fb_end_aligned_physaddr = 0; | ||
1154 | } | ||
1155 | } | ||
1156 | #endif | ||
1157 | |||
1158 | /* Blank the entire osd. */ | ||
1159 | memset_io(oi->video_vbase, 0, oi->video_buffer_size); | ||
1160 | |||
1161 | return 0; | ||
1162 | } | ||
1163 | |||
1164 | /* Release any memory we've grabbed & remove mtrr entry */ | ||
1165 | static void ivtvfb_release_buffers (struct ivtv *itv) | ||
1166 | { | ||
1167 | struct osd_info *oi = itv->osd_info; | ||
1168 | |||
1169 | /* Release cmap */ | ||
1170 | if (oi->ivtvfb_info.cmap.len) | ||
1171 | fb_dealloc_cmap(&oi->ivtvfb_info.cmap); | ||
1172 | |||
1173 | /* Release pseudo palette */ | ||
1174 | if (oi->ivtvfb_info.pseudo_palette) | ||
1175 | kfree(oi->ivtvfb_info.pseudo_palette); | ||
1176 | |||
1177 | #ifdef CONFIG_MTRR | ||
1178 | if (oi->fb_end_aligned_physaddr) { | ||
1179 | mtrr_del(-1, oi->fb_start_aligned_physaddr, | ||
1180 | oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr); | ||
1181 | } | ||
1182 | #endif | ||
1183 | |||
1184 | kfree(oi); | ||
1185 | itv->osd_info = NULL; | ||
1186 | } | ||
1187 | |||
1188 | /* Initialize the specified card */ | ||
1189 | |||
1190 | static int ivtvfb_init_card(struct ivtv *itv) | ||
1191 | { | ||
1192 | int rc; | ||
1193 | |||
1194 | if (itv->osd_info) { | ||
1195 | IVTVFB_ERR("Card %d already initialised\n", ivtvfb_card_id); | ||
1196 | return -EBUSY; | ||
1197 | } | ||
1198 | |||
1199 | itv->osd_info = kzalloc(sizeof(struct osd_info), | ||
1200 | GFP_ATOMIC|__GFP_NOWARN); | ||
1201 | if (itv->osd_info == NULL) { | ||
1202 | IVTVFB_ERR("Failed to allocate memory for osd_info\n"); | ||
1203 | return -ENOMEM; | ||
1204 | } | ||
1205 | |||
1206 | /* Find & setup the OSD buffer */ | ||
1207 | rc = ivtvfb_init_io(itv); | ||
1208 | if (rc) { | ||
1209 | ivtvfb_release_buffers(itv); | ||
1210 | return rc; | ||
1211 | } | ||
1212 | |||
1213 | /* Set the startup video mode information */ | ||
1214 | if ((rc = ivtvfb_init_vidmode(itv))) { | ||
1215 | ivtvfb_release_buffers(itv); | ||
1216 | return rc; | ||
1217 | } | ||
1218 | |||
1219 | /* Register the framebuffer */ | ||
1220 | if (register_framebuffer(&itv->osd_info->ivtvfb_info) < 0) { | ||
1221 | ivtvfb_release_buffers(itv); | ||
1222 | return -EINVAL; | ||
1223 | } | ||
1224 | |||
1225 | itv->osd_video_pbase = itv->osd_info->video_pbase; | ||
1226 | |||
1227 | /* Set the card to the requested mode */ | ||
1228 | ivtvfb_set_par(&itv->osd_info->ivtvfb_info); | ||
1229 | |||
1230 | /* Set color 0 to black */ | ||
1231 | write_reg(0, 0x02a30); | ||
1232 | write_reg(0, 0x02a34); | ||
1233 | |||
1234 | /* Enable the osd */ | ||
1235 | ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info); | ||
1236 | |||
1237 | /* Enable restart */ | ||
1238 | itv->ivtvfb_restore = ivtvfb_restore; | ||
1239 | |||
1240 | /* Allocate DMA */ | ||
1241 | ivtv_udma_alloc(itv); | ||
1242 | return 0; | ||
1243 | |||
1244 | } | ||
1245 | |||
1246 | static int __init ivtvfb_callback_init(struct device *dev, void *p) | ||
1247 | { | ||
1248 | struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); | ||
1249 | struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev); | ||
1250 | |||
1251 | if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { | ||
1252 | if (ivtvfb_init_card(itv) == 0) { | ||
1253 | IVTVFB_INFO("Framebuffer registered on %s\n", | ||
1254 | itv->v4l2_dev.name); | ||
1255 | (*(int *)p)++; | ||
1256 | } | ||
1257 | } | ||
1258 | return 0; | ||
1259 | } | ||
1260 | |||
1261 | static int ivtvfb_callback_cleanup(struct device *dev, void *p) | ||
1262 | { | ||
1263 | struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); | ||
1264 | struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev); | ||
1265 | struct osd_info *oi = itv->osd_info; | ||
1266 | |||
1267 | if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { | ||
1268 | if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) { | ||
1269 | IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n", | ||
1270 | itv->instance); | ||
1271 | return 0; | ||
1272 | } | ||
1273 | IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance); | ||
1274 | itv->ivtvfb_restore = NULL; | ||
1275 | ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info); | ||
1276 | ivtvfb_release_buffers(itv); | ||
1277 | itv->osd_video_pbase = 0; | ||
1278 | } | ||
1279 | return 0; | ||
1280 | } | ||
1281 | |||
1282 | static int __init ivtvfb_init(void) | ||
1283 | { | ||
1284 | struct device_driver *drv; | ||
1285 | int registered = 0; | ||
1286 | int err; | ||
1287 | |||
1288 | if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) { | ||
1289 | printk(KERN_ERR "ivtvfb: ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n", | ||
1290 | IVTV_MAX_CARDS - 1); | ||
1291 | return -EINVAL; | ||
1292 | } | ||
1293 | |||
1294 | drv = driver_find("ivtv", &pci_bus_type); | ||
1295 | err = driver_for_each_device(drv, NULL, ®istered, ivtvfb_callback_init); | ||
1296 | put_driver(drv); | ||
1297 | if (!registered) { | ||
1298 | printk(KERN_ERR "ivtvfb: no cards found\n"); | ||
1299 | return -ENODEV; | ||
1300 | } | ||
1301 | return 0; | ||
1302 | } | ||
1303 | |||
1304 | static void ivtvfb_cleanup(void) | ||
1305 | { | ||
1306 | struct device_driver *drv; | ||
1307 | int err; | ||
1308 | |||
1309 | printk(KERN_INFO "ivtvfb: Unloading framebuffer module\n"); | ||
1310 | |||
1311 | drv = driver_find("ivtv", &pci_bus_type); | ||
1312 | err = driver_for_each_device(drv, NULL, NULL, ivtvfb_callback_cleanup); | ||
1313 | put_driver(drv); | ||
1314 | } | ||
1315 | |||
1316 | module_init(ivtvfb_init); | ||
1317 | module_exit(ivtvfb_cleanup); | ||