diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2013-04-14 11:10:32 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-04-16 17:11:58 -0400 |
commit | 7087d31b0c9dddbca71b8e33d3f0a3b719afa397 (patch) | |
tree | 6ad09261fa0e6884132f40200f3efc6eea9f11aa /drivers/media | |
parent | e90878ab151f733b67d725a1e1e5aee04f431ce5 (diff) |
[media] cx25821: drop cx25821-video-upstream-ch2.c/h
cx25821-video-upstream_ch2.c/h is practically identical to cx25821-video-upstream.c/h
so add support for ch2 into cx25821-video-upstream.c instead.
After this we can replace the custom ioctls with a proper write() interface.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/pci/cx25821/Makefile | 1 | ||||
-rw-r--r-- | drivers/media/pci/cx25821/cx25821-core.c | 4 | ||||
-rw-r--r-- | drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c | 800 | ||||
-rw-r--r-- | drivers/media/pci/cx25821/cx25821-video-upstream-ch2.h | 138 | ||||
-rw-r--r-- | drivers/media/pci/cx25821/cx25821-video-upstream.c | 349 | ||||
-rw-r--r-- | drivers/media/pci/cx25821/cx25821-video.c | 19 | ||||
-rw-r--r-- | drivers/media/pci/cx25821/cx25821.h | 127 |
7 files changed, 243 insertions, 1195 deletions
diff --git a/drivers/media/pci/cx25821/Makefile b/drivers/media/pci/cx25821/Makefile index b54a32e88bd0..407830c89df4 100644 --- a/drivers/media/pci/cx25821/Makefile +++ b/drivers/media/pci/cx25821/Makefile | |||
@@ -1,7 +1,6 @@ | |||
1 | cx25821-y := cx25821-core.o cx25821-cards.o cx25821-i2c.o \ | 1 | cx25821-y := cx25821-core.o cx25821-cards.o cx25821-i2c.o \ |
2 | cx25821-gpio.o cx25821-medusa-video.o \ | 2 | cx25821-gpio.o cx25821-medusa-video.o \ |
3 | cx25821-video.o cx25821-video-upstream.o \ | 3 | cx25821-video.o cx25821-video-upstream.o \ |
4 | cx25821-video-upstream-ch2.o \ | ||
5 | cx25821-audio-upstream.o | 4 | cx25821-audio-upstream.o |
6 | 5 | ||
7 | obj-$(CONFIG_VIDEO_CX25821) += cx25821.o | 6 | obj-$(CONFIG_VIDEO_CX25821) += cx25821.o |
diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index 9068d53a5b8f..230bd8641576 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c | |||
@@ -963,8 +963,6 @@ void cx25821_dev_unregister(struct cx25821_dev *dev) | |||
963 | if (!dev->base_io_addr) | 963 | if (!dev->base_io_addr) |
964 | return; | 964 | return; |
965 | 965 | ||
966 | cx25821_free_mem_upstream_ch1(dev); | ||
967 | cx25821_free_mem_upstream_ch2(dev); | ||
968 | cx25821_free_mem_upstream_audio(dev); | 966 | cx25821_free_mem_upstream_audio(dev); |
969 | 967 | ||
970 | release_mem_region(dev->base_io_addr, pci_resource_len(dev->pci, 0)); | 968 | release_mem_region(dev->base_io_addr, pci_resource_len(dev->pci, 0)); |
@@ -972,6 +970,8 @@ void cx25821_dev_unregister(struct cx25821_dev *dev) | |||
972 | for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; i++) { | 970 | for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; i++) { |
973 | if (i == SRAM_CH08) /* audio channel */ | 971 | if (i == SRAM_CH08) /* audio channel */ |
974 | continue; | 972 | continue; |
973 | if (i == SRAM_CH09 || i == SRAM_CH10) | ||
974 | cx25821_free_mem_upstream(&dev->channels[i]); | ||
975 | cx25821_video_unregister(dev, i); | 975 | cx25821_video_unregister(dev, i); |
976 | } | 976 | } |
977 | 977 | ||
diff --git a/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c b/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c deleted file mode 100644 index 2381bdce99fd..000000000000 --- a/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c +++ /dev/null | |||
@@ -1,800 +0,0 @@ | |||
1 | /* | ||
2 | * Driver for the Conexant CX25821 PCIe bridge | ||
3 | * | ||
4 | * Copyright (C) 2009 Conexant Systems Inc. | ||
5 | * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com> | ||
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 | * | ||
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., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
24 | |||
25 | #include "cx25821-video.h" | ||
26 | #include "cx25821-video-upstream-ch2.h" | ||
27 | |||
28 | #include <linux/fs.h> | ||
29 | #include <linux/errno.h> | ||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/syscalls.h> | ||
34 | #include <linux/file.h> | ||
35 | #include <linux/fcntl.h> | ||
36 | #include <linux/slab.h> | ||
37 | #include <linux/uaccess.h> | ||
38 | |||
39 | MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards"); | ||
40 | MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>"); | ||
41 | MODULE_LICENSE("GPL"); | ||
42 | |||
43 | static int _intr_msk = FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | | ||
44 | FLD_VID_SRC_OPC_ERR; | ||
45 | |||
46 | static __le32 *cx25821_update_riscprogram_ch2(struct cx25821_dev *dev, | ||
47 | __le32 *rp, unsigned int offset, | ||
48 | unsigned int bpl, u32 sync_line, | ||
49 | unsigned int lines, | ||
50 | int fifo_enable, int field_type) | ||
51 | { | ||
52 | unsigned int line, i; | ||
53 | int dist_betwn_starts = bpl * 2; | ||
54 | |||
55 | *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); | ||
56 | |||
57 | if (USE_RISC_NOOP_VIDEO) { | ||
58 | for (i = 0; i < NUM_NO_OPS; i++) | ||
59 | *(rp++) = cpu_to_le32(RISC_NOOP); | ||
60 | } | ||
61 | |||
62 | /* scan lines */ | ||
63 | for (line = 0; line < lines; line++) { | ||
64 | *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl); | ||
65 | *(rp++) = cpu_to_le32(dev->_data_buf_phys_addr_ch2 + offset); | ||
66 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | ||
67 | |||
68 | if ((lines <= NTSC_FIELD_HEIGHT) || | ||
69 | (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC_ch2)) { | ||
70 | offset += dist_betwn_starts; | ||
71 | } | ||
72 | } | ||
73 | |||
74 | return rp; | ||
75 | } | ||
76 | |||
77 | static __le32 *cx25821_risc_field_upstream_ch2(struct cx25821_dev *dev, | ||
78 | __le32 *rp, | ||
79 | dma_addr_t databuf_phys_addr, | ||
80 | unsigned int offset, | ||
81 | u32 sync_line, unsigned int bpl, | ||
82 | unsigned int lines, | ||
83 | int fifo_enable, int field_type) | ||
84 | { | ||
85 | unsigned int line, i; | ||
86 | const struct sram_channel *sram_ch = | ||
87 | dev->channels[dev->_channel2_upstream_select].sram_channels; | ||
88 | int dist_betwn_starts = bpl * 2; | ||
89 | |||
90 | /* sync instruction */ | ||
91 | if (sync_line != NO_SYNC_LINE) | ||
92 | *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); | ||
93 | |||
94 | if (USE_RISC_NOOP_VIDEO) { | ||
95 | for (i = 0; i < NUM_NO_OPS; i++) | ||
96 | *(rp++) = cpu_to_le32(RISC_NOOP); | ||
97 | } | ||
98 | |||
99 | /* scan lines */ | ||
100 | for (line = 0; line < lines; line++) { | ||
101 | *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl); | ||
102 | *(rp++) = cpu_to_le32(databuf_phys_addr + offset); | ||
103 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | ||
104 | |||
105 | if ((lines <= NTSC_FIELD_HEIGHT) || | ||
106 | (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC_ch2)) { | ||
107 | offset += dist_betwn_starts; | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | check if we need to enable the FIFO after the first 4 lines | ||
112 | For the upstream video channel, the risc engine will enable | ||
113 | the FIFO. | ||
114 | */ | ||
115 | if (fifo_enable && line == 3) { | ||
116 | *(rp++) = RISC_WRITECR; | ||
117 | *(rp++) = sram_ch->dma_ctl; | ||
118 | *(rp++) = FLD_VID_FIFO_EN; | ||
119 | *(rp++) = 0x00000001; | ||
120 | } | ||
121 | } | ||
122 | |||
123 | return rp; | ||
124 | } | ||
125 | |||
126 | static int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev, | ||
127 | struct pci_dev *pci, | ||
128 | unsigned int top_offset, | ||
129 | unsigned int bpl, | ||
130 | unsigned int lines) | ||
131 | { | ||
132 | __le32 *rp; | ||
133 | int fifo_enable = 0; | ||
134 | int singlefield_lines = lines >> 1; /*get line count for single field */ | ||
135 | int odd_num_lines = singlefield_lines; | ||
136 | int frame = 0; | ||
137 | int frame_size = 0; | ||
138 | int databuf_offset = 0; | ||
139 | int risc_program_size = 0; | ||
140 | int risc_flag = RISC_CNT_RESET; | ||
141 | unsigned int bottom_offset = bpl; | ||
142 | dma_addr_t risc_phys_jump_addr; | ||
143 | |||
144 | if (dev->_isNTSC_ch2) { | ||
145 | odd_num_lines = singlefield_lines + 1; | ||
146 | risc_program_size = FRAME1_VID_PROG_SIZE; | ||
147 | if (bpl == Y411_LINE_SZ) | ||
148 | frame_size = FRAME_SIZE_NTSC_Y411; | ||
149 | else | ||
150 | frame_size = FRAME_SIZE_NTSC_Y422; | ||
151 | } else { | ||
152 | risc_program_size = PAL_VID_PROG_SIZE; | ||
153 | if (bpl == Y411_LINE_SZ) | ||
154 | frame_size = FRAME_SIZE_PAL_Y411; | ||
155 | else | ||
156 | frame_size = FRAME_SIZE_PAL_Y422; | ||
157 | } | ||
158 | |||
159 | /* Virtual address of Risc buffer program */ | ||
160 | rp = dev->_dma_virt_addr_ch2; | ||
161 | |||
162 | for (frame = 0; frame < NUM_FRAMES; frame++) { | ||
163 | databuf_offset = frame_size * frame; | ||
164 | |||
165 | if (UNSET != top_offset) { | ||
166 | fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE; | ||
167 | rp = cx25821_risc_field_upstream_ch2(dev, rp, | ||
168 | dev->_data_buf_phys_addr_ch2 + databuf_offset, | ||
169 | top_offset, 0, bpl, odd_num_lines, fifo_enable, | ||
170 | ODD_FIELD); | ||
171 | } | ||
172 | |||
173 | fifo_enable = FIFO_DISABLE; | ||
174 | |||
175 | /* Even field */ | ||
176 | rp = cx25821_risc_field_upstream_ch2(dev, rp, | ||
177 | dev->_data_buf_phys_addr_ch2 + databuf_offset, | ||
178 | bottom_offset, 0x200, bpl, singlefield_lines, | ||
179 | fifo_enable, EVEN_FIELD); | ||
180 | |||
181 | if (frame == 0) { | ||
182 | risc_flag = RISC_CNT_RESET; | ||
183 | risc_phys_jump_addr = dev->_dma_phys_start_addr_ch2 + | ||
184 | risc_program_size; | ||
185 | } else { | ||
186 | risc_flag = RISC_CNT_INC; | ||
187 | risc_phys_jump_addr = dev->_dma_phys_start_addr_ch2; | ||
188 | } | ||
189 | |||
190 | /* | ||
191 | * Loop to 2ndFrameRISC or to Start of | ||
192 | * Risc program & generate IRQ | ||
193 | */ | ||
194 | *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag); | ||
195 | *(rp++) = cpu_to_le32(risc_phys_jump_addr); | ||
196 | *(rp++) = cpu_to_le32(0); | ||
197 | } | ||
198 | |||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev) | ||
203 | { | ||
204 | const struct sram_channel *sram_ch = | ||
205 | dev->channels[VID_UPSTREAM_SRAM_CHANNEL_J].sram_channels; | ||
206 | u32 tmp = 0; | ||
207 | |||
208 | if (!dev->_is_running_ch2) { | ||
209 | pr_info("No video file is currently running so return!\n"); | ||
210 | return; | ||
211 | } | ||
212 | /* Disable RISC interrupts */ | ||
213 | tmp = cx_read(sram_ch->int_msk); | ||
214 | cx_write(sram_ch->int_msk, tmp & ~_intr_msk); | ||
215 | |||
216 | /* Turn OFF risc and fifo */ | ||
217 | tmp = cx_read(sram_ch->dma_ctl); | ||
218 | cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN)); | ||
219 | |||
220 | /* Clear data buffer memory */ | ||
221 | if (dev->_data_buf_virt_addr_ch2) | ||
222 | memset(dev->_data_buf_virt_addr_ch2, 0, | ||
223 | dev->_data_buf_size_ch2); | ||
224 | |||
225 | dev->_is_running_ch2 = 0; | ||
226 | dev->_is_first_frame_ch2 = 0; | ||
227 | dev->_frame_count_ch2 = 0; | ||
228 | dev->_file_status_ch2 = END_OF_FILE; | ||
229 | |||
230 | kfree(dev->_irq_queues_ch2); | ||
231 | dev->_irq_queues_ch2 = NULL; | ||
232 | |||
233 | kfree(dev->_filename_ch2); | ||
234 | |||
235 | tmp = cx_read(VID_CH_MODE_SEL); | ||
236 | cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00); | ||
237 | } | ||
238 | |||
239 | void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev) | ||
240 | { | ||
241 | if (dev->_is_running_ch2) | ||
242 | cx25821_stop_upstream_video_ch2(dev); | ||
243 | |||
244 | if (dev->_dma_virt_addr_ch2) { | ||
245 | pci_free_consistent(dev->pci, dev->_risc_size_ch2, | ||
246 | dev->_dma_virt_addr_ch2, | ||
247 | dev->_dma_phys_addr_ch2); | ||
248 | dev->_dma_virt_addr_ch2 = NULL; | ||
249 | } | ||
250 | |||
251 | if (dev->_data_buf_virt_addr_ch2) { | ||
252 | pci_free_consistent(dev->pci, dev->_data_buf_size_ch2, | ||
253 | dev->_data_buf_virt_addr_ch2, | ||
254 | dev->_data_buf_phys_addr_ch2); | ||
255 | dev->_data_buf_virt_addr_ch2 = NULL; | ||
256 | } | ||
257 | } | ||
258 | |||
259 | static int cx25821_get_frame_ch2(struct cx25821_dev *dev, | ||
260 | const struct sram_channel *sram_ch) | ||
261 | { | ||
262 | struct file *myfile; | ||
263 | int frame_index_temp = dev->_frame_index_ch2; | ||
264 | int i = 0; | ||
265 | int line_size = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ? | ||
266 | Y411_LINE_SZ : Y422_LINE_SZ; | ||
267 | int frame_size = 0; | ||
268 | int frame_offset = 0; | ||
269 | ssize_t vfs_read_retval = 0; | ||
270 | char mybuf[line_size]; | ||
271 | loff_t file_offset; | ||
272 | loff_t pos; | ||
273 | mm_segment_t old_fs; | ||
274 | |||
275 | if (dev->_file_status_ch2 == END_OF_FILE) | ||
276 | return 0; | ||
277 | |||
278 | if (dev->_isNTSC_ch2) { | ||
279 | frame_size = (line_size == Y411_LINE_SZ) ? | ||
280 | FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422; | ||
281 | } else { | ||
282 | frame_size = (line_size == Y411_LINE_SZ) ? | ||
283 | FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; | ||
284 | } | ||
285 | |||
286 | frame_offset = (frame_index_temp > 0) ? frame_size : 0; | ||
287 | file_offset = dev->_frame_count_ch2 * frame_size; | ||
288 | |||
289 | myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0); | ||
290 | if (IS_ERR(myfile)) { | ||
291 | const int open_errno = -PTR_ERR(myfile); | ||
292 | pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", | ||
293 | __func__, dev->_filename_ch2, open_errno); | ||
294 | return PTR_ERR(myfile); | ||
295 | } else { | ||
296 | if (!(myfile->f_op)) { | ||
297 | pr_err("%s(): File has no file operations registered!\n", | ||
298 | __func__); | ||
299 | filp_close(myfile, NULL); | ||
300 | return -EIO; | ||
301 | } | ||
302 | |||
303 | if (!myfile->f_op->read) { | ||
304 | pr_err("%s(): File has no READ operations registered!\n", | ||
305 | __func__); | ||
306 | filp_close(myfile, NULL); | ||
307 | return -EIO; | ||
308 | } | ||
309 | |||
310 | pos = myfile->f_pos; | ||
311 | old_fs = get_fs(); | ||
312 | set_fs(KERNEL_DS); | ||
313 | |||
314 | for (i = 0; i < dev->_lines_count_ch2; i++) { | ||
315 | pos = file_offset; | ||
316 | |||
317 | vfs_read_retval = vfs_read(myfile, mybuf, line_size, | ||
318 | &pos); | ||
319 | |||
320 | if (vfs_read_retval > 0 && vfs_read_retval == line_size | ||
321 | && dev->_data_buf_virt_addr_ch2 != NULL) { | ||
322 | memcpy((void *)(dev->_data_buf_virt_addr_ch2 + | ||
323 | frame_offset / 4), mybuf, | ||
324 | vfs_read_retval); | ||
325 | } | ||
326 | |||
327 | file_offset += vfs_read_retval; | ||
328 | frame_offset += vfs_read_retval; | ||
329 | |||
330 | if (vfs_read_retval < line_size) { | ||
331 | pr_info("Done: exit %s() since no more bytes to read from Video file\n", | ||
332 | __func__); | ||
333 | break; | ||
334 | } | ||
335 | } | ||
336 | |||
337 | if (i > 0) | ||
338 | dev->_frame_count_ch2++; | ||
339 | |||
340 | dev->_file_status_ch2 = (vfs_read_retval == line_size) ? | ||
341 | IN_PROGRESS : END_OF_FILE; | ||
342 | |||
343 | set_fs(old_fs); | ||
344 | filp_close(myfile, NULL); | ||
345 | } | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static void cx25821_vidups_handler_ch2(struct work_struct *work) | ||
351 | { | ||
352 | struct cx25821_dev *dev = container_of(work, struct cx25821_dev, | ||
353 | _irq_work_entry_ch2); | ||
354 | |||
355 | if (!dev) { | ||
356 | pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n", | ||
357 | __func__); | ||
358 | return; | ||
359 | } | ||
360 | |||
361 | cx25821_get_frame_ch2(dev, dev->channels[dev-> | ||
362 | _channel2_upstream_select].sram_channels); | ||
363 | } | ||
364 | |||
365 | static int cx25821_openfile_ch2(struct cx25821_dev *dev, | ||
366 | const struct sram_channel *sram_ch) | ||
367 | { | ||
368 | struct file *myfile; | ||
369 | int i = 0, j = 0; | ||
370 | int line_size = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ? | ||
371 | Y411_LINE_SZ : Y422_LINE_SZ; | ||
372 | ssize_t vfs_read_retval = 0; | ||
373 | char mybuf[line_size]; | ||
374 | loff_t pos; | ||
375 | loff_t offset = (unsigned long)0; | ||
376 | mm_segment_t old_fs; | ||
377 | |||
378 | myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0); | ||
379 | |||
380 | if (IS_ERR(myfile)) { | ||
381 | const int open_errno = -PTR_ERR(myfile); | ||
382 | pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", | ||
383 | __func__, dev->_filename_ch2, open_errno); | ||
384 | return PTR_ERR(myfile); | ||
385 | } else { | ||
386 | if (!(myfile->f_op)) { | ||
387 | pr_err("%s(): File has no file operations registered!\n", | ||
388 | __func__); | ||
389 | filp_close(myfile, NULL); | ||
390 | return -EIO; | ||
391 | } | ||
392 | |||
393 | if (!myfile->f_op->read) { | ||
394 | pr_err("%s(): File has no READ operations registered! Returning\n", | ||
395 | __func__); | ||
396 | filp_close(myfile, NULL); | ||
397 | return -EIO; | ||
398 | } | ||
399 | |||
400 | pos = myfile->f_pos; | ||
401 | old_fs = get_fs(); | ||
402 | set_fs(KERNEL_DS); | ||
403 | |||
404 | for (j = 0; j < NUM_FRAMES; j++) { | ||
405 | for (i = 0; i < dev->_lines_count_ch2; i++) { | ||
406 | pos = offset; | ||
407 | |||
408 | vfs_read_retval = vfs_read(myfile, mybuf, | ||
409 | line_size, &pos); | ||
410 | |||
411 | if (vfs_read_retval > 0 && | ||
412 | vfs_read_retval == line_size && | ||
413 | dev->_data_buf_virt_addr_ch2 != NULL) { | ||
414 | memcpy((void *)(dev-> | ||
415 | _data_buf_virt_addr_ch2 | ||
416 | + offset / 4), mybuf, | ||
417 | vfs_read_retval); | ||
418 | } | ||
419 | |||
420 | offset += vfs_read_retval; | ||
421 | |||
422 | if (vfs_read_retval < line_size) { | ||
423 | pr_info("Done: exit %s() since no more bytes to read from Video file\n", | ||
424 | __func__); | ||
425 | break; | ||
426 | } | ||
427 | } | ||
428 | |||
429 | if (i > 0) | ||
430 | dev->_frame_count_ch2++; | ||
431 | |||
432 | if (vfs_read_retval < line_size) | ||
433 | break; | ||
434 | } | ||
435 | |||
436 | dev->_file_status_ch2 = (vfs_read_retval == line_size) ? | ||
437 | IN_PROGRESS : END_OF_FILE; | ||
438 | |||
439 | set_fs(old_fs); | ||
440 | myfile->f_pos = 0; | ||
441 | filp_close(myfile, NULL); | ||
442 | } | ||
443 | |||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev, | ||
448 | const struct sram_channel *sram_ch, | ||
449 | int bpl) | ||
450 | { | ||
451 | int ret = 0; | ||
452 | dma_addr_t dma_addr; | ||
453 | dma_addr_t data_dma_addr; | ||
454 | |||
455 | if (dev->_dma_virt_addr_ch2 != NULL) { | ||
456 | pci_free_consistent(dev->pci, dev->upstream_riscbuf_size_ch2, | ||
457 | dev->_dma_virt_addr_ch2, | ||
458 | dev->_dma_phys_addr_ch2); | ||
459 | } | ||
460 | |||
461 | dev->_dma_virt_addr_ch2 = pci_alloc_consistent(dev->pci, | ||
462 | dev->upstream_riscbuf_size_ch2, &dma_addr); | ||
463 | dev->_dma_virt_start_addr_ch2 = dev->_dma_virt_addr_ch2; | ||
464 | dev->_dma_phys_start_addr_ch2 = dma_addr; | ||
465 | dev->_dma_phys_addr_ch2 = dma_addr; | ||
466 | dev->_risc_size_ch2 = dev->upstream_riscbuf_size_ch2; | ||
467 | |||
468 | if (!dev->_dma_virt_addr_ch2) { | ||
469 | pr_err("FAILED to allocate memory for Risc buffer! Returning\n"); | ||
470 | return -ENOMEM; | ||
471 | } | ||
472 | |||
473 | /* Iniitize at this address until n bytes to 0 */ | ||
474 | memset(dev->_dma_virt_addr_ch2, 0, dev->_risc_size_ch2); | ||
475 | |||
476 | if (dev->_data_buf_virt_addr_ch2 != NULL) { | ||
477 | pci_free_consistent(dev->pci, dev->upstream_databuf_size_ch2, | ||
478 | dev->_data_buf_virt_addr_ch2, | ||
479 | dev->_data_buf_phys_addr_ch2); | ||
480 | } | ||
481 | /* For Video Data buffer allocation */ | ||
482 | dev->_data_buf_virt_addr_ch2 = pci_alloc_consistent(dev->pci, | ||
483 | dev->upstream_databuf_size_ch2, &data_dma_addr); | ||
484 | dev->_data_buf_phys_addr_ch2 = data_dma_addr; | ||
485 | dev->_data_buf_size_ch2 = dev->upstream_databuf_size_ch2; | ||
486 | |||
487 | if (!dev->_data_buf_virt_addr_ch2) { | ||
488 | pr_err("FAILED to allocate memory for data buffer! Returning\n"); | ||
489 | return -ENOMEM; | ||
490 | } | ||
491 | |||
492 | /* Initialize at this address until n bytes to 0 */ | ||
493 | memset(dev->_data_buf_virt_addr_ch2, 0, dev->_data_buf_size_ch2); | ||
494 | |||
495 | ret = cx25821_openfile_ch2(dev, sram_ch); | ||
496 | if (ret < 0) | ||
497 | return ret; | ||
498 | |||
499 | /* Creating RISC programs */ | ||
500 | ret = cx25821_risc_buffer_upstream_ch2(dev, dev->pci, 0, bpl, | ||
501 | dev->_lines_count_ch2); | ||
502 | if (ret < 0) { | ||
503 | pr_info("Failed creating Video Upstream Risc programs!\n"); | ||
504 | goto error; | ||
505 | } | ||
506 | |||
507 | return 0; | ||
508 | |||
509 | error: | ||
510 | return ret; | ||
511 | } | ||
512 | |||
513 | static int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, | ||
514 | int chan_num, | ||
515 | u32 status) | ||
516 | { | ||
517 | u32 int_msk_tmp; | ||
518 | const struct sram_channel *channel = dev->channels[chan_num].sram_channels; | ||
519 | int singlefield_lines = NTSC_FIELD_HEIGHT; | ||
520 | int line_size_in_bytes = Y422_LINE_SZ; | ||
521 | int odd_risc_prog_size = 0; | ||
522 | dma_addr_t risc_phys_jump_addr; | ||
523 | __le32 *rp; | ||
524 | |||
525 | if (status & FLD_VID_SRC_RISC1) { | ||
526 | /* We should only process one program per call */ | ||
527 | u32 prog_cnt = cx_read(channel->gpcnt); | ||
528 | |||
529 | /* | ||
530 | * Since we've identified our IRQ, clear our bits from the | ||
531 | * interrupt mask and interrupt status registers | ||
532 | */ | ||
533 | int_msk_tmp = cx_read(channel->int_msk); | ||
534 | cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk); | ||
535 | cx_write(channel->int_stat, _intr_msk); | ||
536 | |||
537 | spin_lock(&dev->slock); | ||
538 | |||
539 | dev->_frame_index_ch2 = prog_cnt; | ||
540 | |||
541 | queue_work(dev->_irq_queues_ch2, &dev->_irq_work_entry_ch2); | ||
542 | |||
543 | if (dev->_is_first_frame_ch2) { | ||
544 | dev->_is_first_frame_ch2 = 0; | ||
545 | |||
546 | if (dev->_isNTSC_ch2) { | ||
547 | singlefield_lines += 1; | ||
548 | odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE; | ||
549 | } else { | ||
550 | singlefield_lines = PAL_FIELD_HEIGHT; | ||
551 | odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE; | ||
552 | } | ||
553 | |||
554 | if (dev->_dma_virt_start_addr_ch2 != NULL) { | ||
555 | if (dev->_pixel_format_ch2 == PIXEL_FRMT_411) | ||
556 | line_size_in_bytes = Y411_LINE_SZ; | ||
557 | else | ||
558 | line_size_in_bytes = Y422_LINE_SZ; | ||
559 | risc_phys_jump_addr = | ||
560 | dev->_dma_phys_start_addr_ch2 + | ||
561 | odd_risc_prog_size; | ||
562 | |||
563 | rp = cx25821_update_riscprogram_ch2(dev, | ||
564 | dev->_dma_virt_start_addr_ch2, | ||
565 | TOP_OFFSET, line_size_in_bytes, | ||
566 | 0x0, singlefield_lines, | ||
567 | FIFO_DISABLE, ODD_FIELD); | ||
568 | |||
569 | /* Jump to Even Risc program of 1st Frame */ | ||
570 | *(rp++) = cpu_to_le32(RISC_JUMP); | ||
571 | *(rp++) = cpu_to_le32(risc_phys_jump_addr); | ||
572 | *(rp++) = cpu_to_le32(0); | ||
573 | } | ||
574 | } | ||
575 | |||
576 | spin_unlock(&dev->slock); | ||
577 | } | ||
578 | |||
579 | if (dev->_file_status_ch2 == END_OF_FILE) { | ||
580 | pr_info("EOF Channel 2 Framecount = %d\n", | ||
581 | dev->_frame_count_ch2); | ||
582 | return -1; | ||
583 | } | ||
584 | /* ElSE, set the interrupt mask register, re-enable irq. */ | ||
585 | int_msk_tmp = cx_read(channel->int_msk); | ||
586 | cx_write(channel->int_msk, int_msk_tmp |= _intr_msk); | ||
587 | |||
588 | return 0; | ||
589 | } | ||
590 | |||
591 | static irqreturn_t cx25821_upstream_irq_ch2(int irq, void *dev_id) | ||
592 | { | ||
593 | struct cx25821_dev *dev = dev_id; | ||
594 | u32 vid_status; | ||
595 | int handled = 0; | ||
596 | int channel_num = 0; | ||
597 | const struct sram_channel *sram_ch; | ||
598 | |||
599 | if (!dev) | ||
600 | return -1; | ||
601 | |||
602 | channel_num = VID_UPSTREAM_SRAM_CHANNEL_J; | ||
603 | sram_ch = dev->channels[channel_num].sram_channels; | ||
604 | |||
605 | vid_status = cx_read(sram_ch->int_stat); | ||
606 | |||
607 | /* Only deal with our interrupt */ | ||
608 | if (vid_status) | ||
609 | handled = cx25821_video_upstream_irq_ch2(dev, channel_num, | ||
610 | vid_status); | ||
611 | |||
612 | if (handled < 0) | ||
613 | cx25821_stop_upstream_video_ch2(dev); | ||
614 | else | ||
615 | handled += handled; | ||
616 | |||
617 | return IRQ_RETVAL(handled); | ||
618 | } | ||
619 | |||
620 | static void cx25821_set_pixelengine_ch2(struct cx25821_dev *dev, | ||
621 | const struct sram_channel *ch, int pix_format) | ||
622 | { | ||
623 | int width = WIDTH_D1; | ||
624 | int height = dev->_lines_count_ch2; | ||
625 | int num_lines, odd_num_lines; | ||
626 | u32 value; | ||
627 | int vip_mode = PIXEL_ENGINE_VIP1; | ||
628 | |||
629 | value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7); | ||
630 | value &= 0xFFFFFFEF; | ||
631 | value |= dev->_isNTSC_ch2 ? 0 : 0x10; | ||
632 | cx_write(ch->vid_fmt_ctl, value); | ||
633 | |||
634 | /* | ||
635 | * set number of active pixels in each line. Default is 720 | ||
636 | * pixels in both NTSC and PAL format | ||
637 | */ | ||
638 | cx_write(ch->vid_active_ctl1, width); | ||
639 | |||
640 | num_lines = (height / 2) & 0x3FF; | ||
641 | odd_num_lines = num_lines; | ||
642 | |||
643 | if (dev->_isNTSC_ch2) | ||
644 | odd_num_lines += 1; | ||
645 | |||
646 | value = (num_lines << 16) | odd_num_lines; | ||
647 | |||
648 | /* set number of active lines in field 0 (top) and field 1 (bottom) */ | ||
649 | cx_write(ch->vid_active_ctl2, value); | ||
650 | |||
651 | cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3); | ||
652 | } | ||
653 | |||
654 | static int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev, | ||
655 | const struct sram_channel *sram_ch) | ||
656 | { | ||
657 | u32 tmp = 0; | ||
658 | int err = 0; | ||
659 | |||
660 | /* | ||
661 | * 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface | ||
662 | * for channel A-C | ||
663 | */ | ||
664 | tmp = cx_read(VID_CH_MODE_SEL); | ||
665 | cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); | ||
666 | |||
667 | /* | ||
668 | * Set the physical start address of the RISC program in the initial | ||
669 | * program counter(IPC) member of the cmds. | ||
670 | */ | ||
671 | cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr_ch2); | ||
672 | cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */ | ||
673 | |||
674 | /* reset counter */ | ||
675 | cx_write(sram_ch->gpcnt_ctl, 3); | ||
676 | |||
677 | /* Clear our bits from the interrupt status register. */ | ||
678 | cx_write(sram_ch->int_stat, _intr_msk); | ||
679 | |||
680 | /* Set the interrupt mask register, enable irq. */ | ||
681 | cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit)); | ||
682 | tmp = cx_read(sram_ch->int_msk); | ||
683 | cx_write(sram_ch->int_msk, tmp |= _intr_msk); | ||
684 | |||
685 | err = request_irq(dev->pci->irq, cx25821_upstream_irq_ch2, | ||
686 | IRQF_SHARED, dev->name, dev); | ||
687 | if (err < 0) { | ||
688 | pr_err("%s: can't get upstream IRQ %d\n", | ||
689 | dev->name, dev->pci->irq); | ||
690 | goto fail_irq; | ||
691 | } | ||
692 | /* Start the DMA engine */ | ||
693 | tmp = cx_read(sram_ch->dma_ctl); | ||
694 | cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN); | ||
695 | |||
696 | dev->_is_running_ch2 = 1; | ||
697 | dev->_is_first_frame_ch2 = 1; | ||
698 | |||
699 | return 0; | ||
700 | |||
701 | fail_irq: | ||
702 | cx25821_dev_unregister(dev); | ||
703 | return err; | ||
704 | } | ||
705 | |||
706 | int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select, | ||
707 | int pixel_format) | ||
708 | { | ||
709 | const struct sram_channel *sram_ch; | ||
710 | u32 tmp; | ||
711 | int err = 0; | ||
712 | int data_frame_size = 0; | ||
713 | int risc_buffer_size = 0; | ||
714 | |||
715 | if (dev->_is_running_ch2) { | ||
716 | pr_info("Video Channel is still running so return!\n"); | ||
717 | return 0; | ||
718 | } | ||
719 | |||
720 | dev->_channel2_upstream_select = channel_select; | ||
721 | sram_ch = dev->channels[channel_select].sram_channels; | ||
722 | |||
723 | INIT_WORK(&dev->_irq_work_entry_ch2, cx25821_vidups_handler_ch2); | ||
724 | dev->_irq_queues_ch2 = | ||
725 | create_singlethread_workqueue("cx25821_workqueue2"); | ||
726 | |||
727 | if (!dev->_irq_queues_ch2) { | ||
728 | pr_err("create_singlethread_workqueue() for Video FAILED!\n"); | ||
729 | return -ENOMEM; | ||
730 | } | ||
731 | /* | ||
732 | * 656/VIP SRC Upstream Channel I & J and 7 - | ||
733 | * Host Bus Interface for channel A-C | ||
734 | */ | ||
735 | tmp = cx_read(VID_CH_MODE_SEL); | ||
736 | cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); | ||
737 | |||
738 | dev->_is_running_ch2 = 0; | ||
739 | dev->_frame_count_ch2 = 0; | ||
740 | dev->_file_status_ch2 = RESET_STATUS; | ||
741 | dev->_lines_count_ch2 = dev->_isNTSC_ch2 ? 480 : 576; | ||
742 | dev->_pixel_format_ch2 = pixel_format; | ||
743 | dev->_line_size_ch2 = (dev->_pixel_format_ch2 == PIXEL_FRMT_422) ? | ||
744 | (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; | ||
745 | data_frame_size = dev->_isNTSC_ch2 ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ; | ||
746 | risc_buffer_size = dev->_isNTSC_ch2 ? | ||
747 | NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; | ||
748 | |||
749 | if (dev->input_filename_ch2) | ||
750 | dev->_filename_ch2 = kstrdup(dev->input_filename_ch2, | ||
751 | GFP_KERNEL); | ||
752 | else | ||
753 | dev->_filename_ch2 = kstrdup(dev->_defaultname_ch2, | ||
754 | GFP_KERNEL); | ||
755 | |||
756 | if (!dev->_filename_ch2) { | ||
757 | err = -ENOENT; | ||
758 | goto error; | ||
759 | } | ||
760 | |||
761 | /* Default if filename is empty string */ | ||
762 | if (strcmp(dev->_filename_ch2, "") == 0) { | ||
763 | if (dev->_isNTSC_ch2) { | ||
764 | dev->_filename_ch2 = (dev->_pixel_format_ch2 == | ||
765 | PIXEL_FRMT_411) ? "/root/vid411.yuv" : | ||
766 | "/root/vidtest.yuv"; | ||
767 | } else { | ||
768 | dev->_filename_ch2 = (dev->_pixel_format_ch2 == | ||
769 | PIXEL_FRMT_411) ? "/root/pal411.yuv" : | ||
770 | "/root/pal422.yuv"; | ||
771 | } | ||
772 | } | ||
773 | |||
774 | err = cx25821_sram_channel_setup_upstream(dev, sram_ch, | ||
775 | dev->_line_size_ch2, 0); | ||
776 | |||
777 | /* setup fifo + format */ | ||
778 | cx25821_set_pixelengine_ch2(dev, sram_ch, dev->_pixel_format_ch2); | ||
779 | |||
780 | dev->upstream_riscbuf_size_ch2 = risc_buffer_size * 2; | ||
781 | dev->upstream_databuf_size_ch2 = data_frame_size * 2; | ||
782 | |||
783 | /* Allocating buffers and prepare RISC program */ | ||
784 | err = cx25821_upstream_buffer_prepare_ch2(dev, sram_ch, | ||
785 | dev->_line_size_ch2); | ||
786 | if (err < 0) { | ||
787 | pr_err("%s: Failed to set up Video upstream buffers!\n", | ||
788 | dev->name); | ||
789 | goto error; | ||
790 | } | ||
791 | |||
792 | cx25821_start_video_dma_upstream_ch2(dev, sram_ch); | ||
793 | |||
794 | return 0; | ||
795 | |||
796 | error: | ||
797 | cx25821_dev_unregister(dev); | ||
798 | |||
799 | return err; | ||
800 | } | ||
diff --git a/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.h b/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.h deleted file mode 100644 index d42dab59b663..000000000000 --- a/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.h +++ /dev/null | |||
@@ -1,138 +0,0 @@ | |||
1 | /* | ||
2 | * Driver for the Conexant CX25821 PCIe bridge | ||
3 | * | ||
4 | * Copyright (C) 2009 Conexant Systems Inc. | ||
5 | * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com> | ||
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 | * | ||
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., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #include <linux/mutex.h> | ||
24 | #include <linux/workqueue.h> | ||
25 | |||
26 | #define OPEN_FILE_1 0 | ||
27 | #define NUM_PROGS 8 | ||
28 | #define NUM_FRAMES 2 | ||
29 | #define ODD_FIELD 0 | ||
30 | #define EVEN_FIELD 1 | ||
31 | #define TOP_OFFSET 0 | ||
32 | #define FIFO_DISABLE 0 | ||
33 | #define FIFO_ENABLE 1 | ||
34 | #define TEST_FRAMES 5 | ||
35 | #define END_OF_FILE 0 | ||
36 | #define IN_PROGRESS 1 | ||
37 | #define RESET_STATUS -1 | ||
38 | #define NUM_NO_OPS 5 | ||
39 | |||
40 | /* PAL and NTSC line sizes and number of lines. */ | ||
41 | #define WIDTH_D1 720 | ||
42 | #define NTSC_LINES_PER_FRAME 480 | ||
43 | #define PAL_LINES_PER_FRAME 576 | ||
44 | #define PAL_LINE_SZ 1440 | ||
45 | #define Y422_LINE_SZ 1440 | ||
46 | #define Y411_LINE_SZ 1080 | ||
47 | #define NTSC_FIELD_HEIGHT 240 | ||
48 | #define NTSC_ODD_FLD_LINES 241 | ||
49 | #define PAL_FIELD_HEIGHT 288 | ||
50 | |||
51 | #define FRAME_SIZE_NTSC_Y422 (NTSC_LINES_PER_FRAME * Y422_LINE_SZ) | ||
52 | #define FRAME_SIZE_NTSC_Y411 (NTSC_LINES_PER_FRAME * Y411_LINE_SZ) | ||
53 | #define FRAME_SIZE_PAL_Y422 (PAL_LINES_PER_FRAME * Y422_LINE_SZ) | ||
54 | #define FRAME_SIZE_PAL_Y411 (PAL_LINES_PER_FRAME * Y411_LINE_SZ) | ||
55 | |||
56 | #define NTSC_DATA_BUF_SZ (Y422_LINE_SZ * NTSC_LINES_PER_FRAME) | ||
57 | #define PAL_DATA_BUF_SZ (Y422_LINE_SZ * PAL_LINES_PER_FRAME) | ||
58 | |||
59 | #define RISC_WRITECR_INSTRUCTION_SIZE 16 | ||
60 | #define RISC_SYNC_INSTRUCTION_SIZE 4 | ||
61 | #define JUMP_INSTRUCTION_SIZE 12 | ||
62 | #define MAXSIZE_NO_OPS 36 | ||
63 | #define DWORD_SIZE 4 | ||
64 | |||
65 | #define USE_RISC_NOOP_VIDEO 1 | ||
66 | |||
67 | #ifdef USE_RISC_NOOP_VIDEO | ||
68 | #define PAL_US_VID_PROG_SIZE \ | ||
69 | (PAL_FIELD_HEIGHT * 3 * DWORD_SIZE + \ | ||
70 | RISC_WRITECR_INSTRUCTION_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \ | ||
71 | NUM_NO_OPS * DWORD_SIZE) | ||
72 | |||
73 | #define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE) | ||
74 | |||
75 | #define PAL_VID_PROG_SIZE \ | ||
76 | ((PAL_FIELD_HEIGHT * 2) * 3 * DWORD_SIZE + \ | ||
77 | 2 * RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \ | ||
78 | JUMP_INSTRUCTION_SIZE + 2 * NUM_NO_OPS * DWORD_SIZE) | ||
79 | |||
80 | #define ODD_FLD_PAL_PROG_SIZE \ | ||
81 | (PAL_FIELD_HEIGHT * 3 * DWORD_SIZE + \ | ||
82 | RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \ | ||
83 | NUM_NO_OPS * DWORD_SIZE) | ||
84 | |||
85 | #define NTSC_US_VID_PROG_SIZE \ | ||
86 | ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + \ | ||
87 | RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + \ | ||
88 | NUM_NO_OPS * DWORD_SIZE) | ||
89 | |||
90 | #define NTSC_RISC_BUF_SIZE \ | ||
91 | (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE)) | ||
92 | |||
93 | #define FRAME1_VID_PROG_SIZE \ | ||
94 | ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * \ | ||
95 | 3 * DWORD_SIZE + 2 * RISC_SYNC_INSTRUCTION_SIZE + \ | ||
96 | RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + \ | ||
97 | 2 * NUM_NO_OPS * DWORD_SIZE) | ||
98 | |||
99 | #define ODD_FLD_NTSC_PROG_SIZE \ | ||
100 | (NTSC_ODD_FLD_LINES * 3 * DWORD_SIZE + \ | ||
101 | RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \ | ||
102 | NUM_NO_OPS * DWORD_SIZE) | ||
103 | #endif | ||
104 | |||
105 | #ifndef USE_RISC_NOOP_VIDEO | ||
106 | #define PAL_US_VID_PROG_SIZE \ | ||
107 | ((PAL_FIELD_HEIGHT + 1) * 3 * DWORD_SIZE + \ | ||
108 | RISC_WRITECR_INSTRUCTION_SIZE) | ||
109 | |||
110 | #define PAL_RISC_BUF_SIZE \ | ||
111 | (2 * (RISC_SYNC_INSTRUCTION_SIZE + PAL_US_VID_PROG_SIZE)) | ||
112 | |||
113 | #define PAL_VID_PROG_SIZE \ | ||
114 | ((PAL_FIELD_HEIGHT * 2) * 3 * DWORD_SIZE + \ | ||
115 | 2 * RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \ | ||
116 | JUMP_INSTRUCTION_SIZE) | ||
117 | |||
118 | #define ODD_FLD_PAL_PROG_SIZE \ | ||
119 | (PAL_FIELD_HEIGHT * 3 * DWORD_SIZE + \ | ||
120 | RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE) | ||
121 | |||
122 | #define ODD_FLD_NTSC_PROG_SIZE \ | ||
123 | (NTSC_ODD_FLD_LINES * 3 * DWORD_SIZE + \ | ||
124 | RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE) | ||
125 | |||
126 | #define NTSC_US_VID_PROG_SIZE \ | ||
127 | ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + \ | ||
128 | RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE) | ||
129 | |||
130 | #define NTSC_RISC_BUF_SIZE \ | ||
131 | (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE)) | ||
132 | |||
133 | #define FRAME1_VID_PROG_SIZE \ | ||
134 | ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * \ | ||
135 | 3 * DWORD_SIZE + 2 * RISC_SYNC_INSTRUCTION_SIZE + \ | ||
136 | RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE) | ||
137 | |||
138 | #endif | ||
diff --git a/drivers/media/pci/cx25821/cx25821-video-upstream.c b/drivers/media/pci/cx25821/cx25821-video-upstream.c index 223aae77c7eb..37cfc834e5c0 100644 --- a/drivers/media/pci/cx25821/cx25821-video-upstream.c +++ b/drivers/media/pci/cx25821/cx25821-video-upstream.c | |||
@@ -97,12 +97,13 @@ int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev, | |||
97 | return 0; | 97 | return 0; |
98 | } | 98 | } |
99 | 99 | ||
100 | static __le32 *cx25821_update_riscprogram(struct cx25821_dev *dev, | 100 | static __le32 *cx25821_update_riscprogram(struct cx25821_channel *chan, |
101 | __le32 *rp, unsigned int offset, | 101 | __le32 *rp, unsigned int offset, |
102 | unsigned int bpl, u32 sync_line, | 102 | unsigned int bpl, u32 sync_line, |
103 | unsigned int lines, int fifo_enable, | 103 | unsigned int lines, int fifo_enable, |
104 | int field_type) | 104 | int field_type) |
105 | { | 105 | { |
106 | struct cx25821_video_out_data *out = chan->out; | ||
106 | unsigned int line, i; | 107 | unsigned int line, i; |
107 | int dist_betwn_starts = bpl * 2; | 108 | int dist_betwn_starts = bpl * 2; |
108 | 109 | ||
@@ -116,11 +117,11 @@ static __le32 *cx25821_update_riscprogram(struct cx25821_dev *dev, | |||
116 | /* scan lines */ | 117 | /* scan lines */ |
117 | for (line = 0; line < lines; line++) { | 118 | for (line = 0; line < lines; line++) { |
118 | *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl); | 119 | *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl); |
119 | *(rp++) = cpu_to_le32(dev->_data_buf_phys_addr + offset); | 120 | *(rp++) = cpu_to_le32(out->_data_buf_phys_addr + offset); |
120 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | 121 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ |
121 | 122 | ||
122 | if ((lines <= NTSC_FIELD_HEIGHT) | 123 | if ((lines <= NTSC_FIELD_HEIGHT) |
123 | || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC)) { | 124 | || (line < (NTSC_FIELD_HEIGHT - 1)) || !(out->is_60hz)) { |
124 | offset += dist_betwn_starts; | 125 | offset += dist_betwn_starts; |
125 | } | 126 | } |
126 | } | 127 | } |
@@ -128,15 +129,15 @@ static __le32 *cx25821_update_riscprogram(struct cx25821_dev *dev, | |||
128 | return rp; | 129 | return rp; |
129 | } | 130 | } |
130 | 131 | ||
131 | static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp, | 132 | static __le32 *cx25821_risc_field_upstream(struct cx25821_channel *chan, __le32 *rp, |
132 | dma_addr_t databuf_phys_addr, | 133 | dma_addr_t databuf_phys_addr, |
133 | unsigned int offset, u32 sync_line, | 134 | unsigned int offset, u32 sync_line, |
134 | unsigned int bpl, unsigned int lines, | 135 | unsigned int bpl, unsigned int lines, |
135 | int fifo_enable, int field_type) | 136 | int fifo_enable, int field_type) |
136 | { | 137 | { |
138 | struct cx25821_video_out_data *out = chan->out; | ||
137 | unsigned int line, i; | 139 | unsigned int line, i; |
138 | const struct sram_channel *sram_ch = | 140 | const struct sram_channel *sram_ch = chan->sram_channels; |
139 | dev->channels[dev->_channel_upstream_select].sram_channels; | ||
140 | int dist_betwn_starts = bpl * 2; | 141 | int dist_betwn_starts = bpl * 2; |
141 | 142 | ||
142 | /* sync instruction */ | 143 | /* sync instruction */ |
@@ -155,7 +156,7 @@ static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp, | |||
155 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | 156 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ |
156 | 157 | ||
157 | if ((lines <= NTSC_FIELD_HEIGHT) | 158 | if ((lines <= NTSC_FIELD_HEIGHT) |
158 | || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC)) | 159 | || (line < (NTSC_FIELD_HEIGHT - 1)) || !(out->is_60hz)) |
159 | /* to skip the other field line */ | 160 | /* to skip the other field line */ |
160 | offset += dist_betwn_starts; | 161 | offset += dist_betwn_starts; |
161 | 162 | ||
@@ -173,11 +174,12 @@ static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp, | |||
173 | return rp; | 174 | return rp; |
174 | } | 175 | } |
175 | 176 | ||
176 | static int cx25821_risc_buffer_upstream(struct cx25821_dev *dev, | 177 | static int cx25821_risc_buffer_upstream(struct cx25821_channel *chan, |
177 | struct pci_dev *pci, | 178 | struct pci_dev *pci, |
178 | unsigned int top_offset, | 179 | unsigned int top_offset, |
179 | unsigned int bpl, unsigned int lines) | 180 | unsigned int bpl, unsigned int lines) |
180 | { | 181 | { |
182 | struct cx25821_video_out_data *out = chan->out; | ||
181 | __le32 *rp; | 183 | __le32 *rp; |
182 | int fifo_enable = 0; | 184 | int fifo_enable = 0; |
183 | /* get line count for single field */ | 185 | /* get line count for single field */ |
@@ -191,7 +193,7 @@ static int cx25821_risc_buffer_upstream(struct cx25821_dev *dev, | |||
191 | unsigned int bottom_offset = bpl; | 193 | unsigned int bottom_offset = bpl; |
192 | dma_addr_t risc_phys_jump_addr; | 194 | dma_addr_t risc_phys_jump_addr; |
193 | 195 | ||
194 | if (dev->_isNTSC) { | 196 | if (out->is_60hz) { |
195 | odd_num_lines = singlefield_lines + 1; | 197 | odd_num_lines = singlefield_lines + 1; |
196 | risc_program_size = FRAME1_VID_PROG_SIZE; | 198 | risc_program_size = FRAME1_VID_PROG_SIZE; |
197 | frame_size = (bpl == Y411_LINE_SZ) ? | 199 | frame_size = (bpl == Y411_LINE_SZ) ? |
@@ -203,15 +205,15 @@ static int cx25821_risc_buffer_upstream(struct cx25821_dev *dev, | |||
203 | } | 205 | } |
204 | 206 | ||
205 | /* Virtual address of Risc buffer program */ | 207 | /* Virtual address of Risc buffer program */ |
206 | rp = dev->_dma_virt_addr; | 208 | rp = out->_dma_virt_addr; |
207 | 209 | ||
208 | for (frame = 0; frame < NUM_FRAMES; frame++) { | 210 | for (frame = 0; frame < NUM_FRAMES; frame++) { |
209 | databuf_offset = frame_size * frame; | 211 | databuf_offset = frame_size * frame; |
210 | 212 | ||
211 | if (UNSET != top_offset) { | 213 | if (UNSET != top_offset) { |
212 | fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE; | 214 | fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE; |
213 | rp = cx25821_risc_field_upstream(dev, rp, | 215 | rp = cx25821_risc_field_upstream(chan, rp, |
214 | dev->_data_buf_phys_addr + | 216 | out->_data_buf_phys_addr + |
215 | databuf_offset, top_offset, 0, bpl, | 217 | databuf_offset, top_offset, 0, bpl, |
216 | odd_num_lines, fifo_enable, ODD_FIELD); | 218 | odd_num_lines, fifo_enable, ODD_FIELD); |
217 | } | 219 | } |
@@ -219,18 +221,18 @@ static int cx25821_risc_buffer_upstream(struct cx25821_dev *dev, | |||
219 | fifo_enable = FIFO_DISABLE; | 221 | fifo_enable = FIFO_DISABLE; |
220 | 222 | ||
221 | /* Even Field */ | 223 | /* Even Field */ |
222 | rp = cx25821_risc_field_upstream(dev, rp, | 224 | rp = cx25821_risc_field_upstream(chan, rp, |
223 | dev->_data_buf_phys_addr + | 225 | out->_data_buf_phys_addr + |
224 | databuf_offset, bottom_offset, | 226 | databuf_offset, bottom_offset, |
225 | 0x200, bpl, singlefield_lines, | 227 | 0x200, bpl, singlefield_lines, |
226 | fifo_enable, EVEN_FIELD); | 228 | fifo_enable, EVEN_FIELD); |
227 | 229 | ||
228 | if (frame == 0) { | 230 | if (frame == 0) { |
229 | risc_flag = RISC_CNT_RESET; | 231 | risc_flag = RISC_CNT_RESET; |
230 | risc_phys_jump_addr = dev->_dma_phys_start_addr + | 232 | risc_phys_jump_addr = out->_dma_phys_start_addr + |
231 | risc_program_size; | 233 | risc_program_size; |
232 | } else { | 234 | } else { |
233 | risc_phys_jump_addr = dev->_dma_phys_start_addr; | 235 | risc_phys_jump_addr = out->_dma_phys_start_addr; |
234 | risc_flag = RISC_CNT_INC; | 236 | risc_flag = RISC_CNT_INC; |
235 | } | 237 | } |
236 | 238 | ||
@@ -245,13 +247,14 @@ static int cx25821_risc_buffer_upstream(struct cx25821_dev *dev, | |||
245 | return 0; | 247 | return 0; |
246 | } | 248 | } |
247 | 249 | ||
248 | void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev) | 250 | void cx25821_stop_upstream_video(struct cx25821_channel *chan) |
249 | { | 251 | { |
250 | const struct sram_channel *sram_ch = | 252 | struct cx25821_video_out_data *out = chan->out; |
251 | dev->channels[VID_UPSTREAM_SRAM_CHANNEL_I].sram_channels; | 253 | struct cx25821_dev *dev = chan->dev; |
254 | const struct sram_channel *sram_ch = chan->sram_channels; | ||
252 | u32 tmp = 0; | 255 | u32 tmp = 0; |
253 | 256 | ||
254 | if (!dev->_is_running) { | 257 | if (!out->_is_running) { |
255 | pr_info("No video file is currently running so return!\n"); | 258 | pr_info("No video file is currently running so return!\n"); |
256 | return; | 259 | return; |
257 | } | 260 | } |
@@ -264,49 +267,53 @@ void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev) | |||
264 | cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN)); | 267 | cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN)); |
265 | 268 | ||
266 | /* Clear data buffer memory */ | 269 | /* Clear data buffer memory */ |
267 | if (dev->_data_buf_virt_addr) | 270 | if (out->_data_buf_virt_addr) |
268 | memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size); | 271 | memset(out->_data_buf_virt_addr, 0, out->_data_buf_size); |
269 | 272 | ||
270 | dev->_is_running = 0; | 273 | out->_is_running = 0; |
271 | dev->_is_first_frame = 0; | 274 | out->_is_first_frame = 0; |
272 | dev->_frame_count = 0; | 275 | out->_frame_count = 0; |
273 | dev->_file_status = END_OF_FILE; | 276 | out->_file_status = END_OF_FILE; |
274 | 277 | ||
275 | kfree(dev->_irq_queues); | 278 | destroy_workqueue(out->_irq_queues); |
276 | dev->_irq_queues = NULL; | 279 | out->_irq_queues = NULL; |
277 | 280 | ||
278 | kfree(dev->_filename); | 281 | kfree(out->_filename); |
279 | 282 | ||
280 | tmp = cx_read(VID_CH_MODE_SEL); | 283 | tmp = cx_read(VID_CH_MODE_SEL); |
281 | cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00); | 284 | cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00); |
282 | } | 285 | } |
283 | 286 | ||
284 | void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev) | 287 | void cx25821_free_mem_upstream(struct cx25821_channel *chan) |
285 | { | 288 | { |
286 | if (dev->_is_running) | 289 | struct cx25821_video_out_data *out = chan->out; |
287 | cx25821_stop_upstream_video_ch1(dev); | 290 | struct cx25821_dev *dev = chan->dev; |
288 | 291 | ||
289 | if (dev->_dma_virt_addr) { | 292 | if (out->_is_running) |
290 | pci_free_consistent(dev->pci, dev->_risc_size, | 293 | cx25821_stop_upstream_video(chan); |
291 | dev->_dma_virt_addr, dev->_dma_phys_addr); | 294 | |
292 | dev->_dma_virt_addr = NULL; | 295 | if (out->_dma_virt_addr) { |
296 | pci_free_consistent(dev->pci, out->_risc_size, | ||
297 | out->_dma_virt_addr, out->_dma_phys_addr); | ||
298 | out->_dma_virt_addr = NULL; | ||
293 | } | 299 | } |
294 | 300 | ||
295 | if (dev->_data_buf_virt_addr) { | 301 | if (out->_data_buf_virt_addr) { |
296 | pci_free_consistent(dev->pci, dev->_data_buf_size, | 302 | pci_free_consistent(dev->pci, out->_data_buf_size, |
297 | dev->_data_buf_virt_addr, | 303 | out->_data_buf_virt_addr, |
298 | dev->_data_buf_phys_addr); | 304 | out->_data_buf_phys_addr); |
299 | dev->_data_buf_virt_addr = NULL; | 305 | out->_data_buf_virt_addr = NULL; |
300 | } | 306 | } |
301 | } | 307 | } |
302 | 308 | ||
303 | static int cx25821_get_frame(struct cx25821_dev *dev, | 309 | static int cx25821_get_frame(struct cx25821_channel *chan, |
304 | const struct sram_channel *sram_ch) | 310 | const struct sram_channel *sram_ch) |
305 | { | 311 | { |
312 | struct cx25821_video_out_data *out = chan->out; | ||
306 | struct file *myfile; | 313 | struct file *myfile; |
307 | int frame_index_temp = dev->_frame_index; | 314 | int frame_index_temp = out->_frame_index; |
308 | int i = 0; | 315 | int i = 0; |
309 | int line_size = (dev->_pixel_format == PIXEL_FRMT_411) ? | 316 | int line_size = (out->_pixel_format == PIXEL_FRMT_411) ? |
310 | Y411_LINE_SZ : Y422_LINE_SZ; | 317 | Y411_LINE_SZ : Y422_LINE_SZ; |
311 | int frame_size = 0; | 318 | int frame_size = 0; |
312 | int frame_offset = 0; | 319 | int frame_offset = 0; |
@@ -316,10 +323,10 @@ static int cx25821_get_frame(struct cx25821_dev *dev, | |||
316 | loff_t pos; | 323 | loff_t pos; |
317 | mm_segment_t old_fs; | 324 | mm_segment_t old_fs; |
318 | 325 | ||
319 | if (dev->_file_status == END_OF_FILE) | 326 | if (out->_file_status == END_OF_FILE) |
320 | return 0; | 327 | return 0; |
321 | 328 | ||
322 | if (dev->_isNTSC) | 329 | if (out->is_60hz) |
323 | frame_size = (line_size == Y411_LINE_SZ) ? | 330 | frame_size = (line_size == Y411_LINE_SZ) ? |
324 | FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422; | 331 | FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422; |
325 | else | 332 | else |
@@ -327,14 +334,14 @@ static int cx25821_get_frame(struct cx25821_dev *dev, | |||
327 | FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; | 334 | FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; |
328 | 335 | ||
329 | frame_offset = (frame_index_temp > 0) ? frame_size : 0; | 336 | frame_offset = (frame_index_temp > 0) ? frame_size : 0; |
330 | file_offset = dev->_frame_count * frame_size; | 337 | file_offset = out->_frame_count * frame_size; |
331 | 338 | ||
332 | myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0); | 339 | myfile = filp_open(out->_filename, O_RDONLY | O_LARGEFILE, 0); |
333 | 340 | ||
334 | if (IS_ERR(myfile)) { | 341 | if (IS_ERR(myfile)) { |
335 | const int open_errno = -PTR_ERR(myfile); | 342 | const int open_errno = -PTR_ERR(myfile); |
336 | pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", | 343 | pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", |
337 | __func__, dev->_filename, open_errno); | 344 | __func__, out->_filename, open_errno); |
338 | return PTR_ERR(myfile); | 345 | return PTR_ERR(myfile); |
339 | } else { | 346 | } else { |
340 | if (!(myfile->f_op)) { | 347 | if (!(myfile->f_op)) { |
@@ -355,15 +362,15 @@ static int cx25821_get_frame(struct cx25821_dev *dev, | |||
355 | old_fs = get_fs(); | 362 | old_fs = get_fs(); |
356 | set_fs(KERNEL_DS); | 363 | set_fs(KERNEL_DS); |
357 | 364 | ||
358 | for (i = 0; i < dev->_lines_count; i++) { | 365 | for (i = 0; i < out->_lines_count; i++) { |
359 | pos = file_offset; | 366 | pos = file_offset; |
360 | 367 | ||
361 | vfs_read_retval = vfs_read(myfile, mybuf, line_size, | 368 | vfs_read_retval = vfs_read(myfile, mybuf, line_size, |
362 | &pos); | 369 | &pos); |
363 | 370 | ||
364 | if (vfs_read_retval > 0 && vfs_read_retval == line_size | 371 | if (vfs_read_retval > 0 && vfs_read_retval == line_size |
365 | && dev->_data_buf_virt_addr != NULL) { | 372 | && out->_data_buf_virt_addr != NULL) { |
366 | memcpy((void *)(dev->_data_buf_virt_addr + | 373 | memcpy((void *)(out->_data_buf_virt_addr + |
367 | frame_offset / 4), mybuf, | 374 | frame_offset / 4), mybuf, |
368 | vfs_read_retval); | 375 | vfs_read_retval); |
369 | } | 376 | } |
@@ -379,9 +386,9 @@ static int cx25821_get_frame(struct cx25821_dev *dev, | |||
379 | } | 386 | } |
380 | 387 | ||
381 | if (i > 0) | 388 | if (i > 0) |
382 | dev->_frame_count++; | 389 | out->_frame_count++; |
383 | 390 | ||
384 | dev->_file_status = (vfs_read_retval == line_size) ? | 391 | out->_file_status = (vfs_read_retval == line_size) ? |
385 | IN_PROGRESS : END_OF_FILE; | 392 | IN_PROGRESS : END_OF_FILE; |
386 | 393 | ||
387 | set_fs(old_fs); | 394 | set_fs(old_fs); |
@@ -393,25 +400,19 @@ static int cx25821_get_frame(struct cx25821_dev *dev, | |||
393 | 400 | ||
394 | static void cx25821_vidups_handler(struct work_struct *work) | 401 | static void cx25821_vidups_handler(struct work_struct *work) |
395 | { | 402 | { |
396 | struct cx25821_dev *dev = container_of(work, struct cx25821_dev, | 403 | struct cx25821_video_out_data *out = |
397 | _irq_work_entry); | 404 | container_of(work, struct cx25821_video_out_data, _irq_work_entry); |
398 | |||
399 | if (!dev) { | ||
400 | pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n", | ||
401 | __func__); | ||
402 | return; | ||
403 | } | ||
404 | 405 | ||
405 | cx25821_get_frame(dev, dev->channels[dev->_channel_upstream_select]. | 406 | cx25821_get_frame(out->chan, out->chan->sram_channels); |
406 | sram_channels); | ||
407 | } | 407 | } |
408 | 408 | ||
409 | static int cx25821_openfile(struct cx25821_dev *dev, | 409 | static int cx25821_openfile(struct cx25821_channel *chan, |
410 | const struct sram_channel *sram_ch) | 410 | const struct sram_channel *sram_ch) |
411 | { | 411 | { |
412 | struct cx25821_video_out_data *out = chan->out; | ||
412 | struct file *myfile; | 413 | struct file *myfile; |
413 | int i = 0, j = 0; | 414 | int i = 0, j = 0; |
414 | int line_size = (dev->_pixel_format == PIXEL_FRMT_411) ? | 415 | int line_size = (out->_pixel_format == PIXEL_FRMT_411) ? |
415 | Y411_LINE_SZ : Y422_LINE_SZ; | 416 | Y411_LINE_SZ : Y422_LINE_SZ; |
416 | ssize_t vfs_read_retval = 0; | 417 | ssize_t vfs_read_retval = 0; |
417 | char mybuf[line_size]; | 418 | char mybuf[line_size]; |
@@ -419,12 +420,12 @@ static int cx25821_openfile(struct cx25821_dev *dev, | |||
419 | loff_t offset = (unsigned long)0; | 420 | loff_t offset = (unsigned long)0; |
420 | mm_segment_t old_fs; | 421 | mm_segment_t old_fs; |
421 | 422 | ||
422 | myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0); | 423 | myfile = filp_open(out->_filename, O_RDONLY | O_LARGEFILE, 0); |
423 | 424 | ||
424 | if (IS_ERR(myfile)) { | 425 | if (IS_ERR(myfile)) { |
425 | const int open_errno = -PTR_ERR(myfile); | 426 | const int open_errno = -PTR_ERR(myfile); |
426 | pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", | 427 | pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", |
427 | __func__, dev->_filename, open_errno); | 428 | __func__, out->_filename, open_errno); |
428 | return PTR_ERR(myfile); | 429 | return PTR_ERR(myfile); |
429 | } else { | 430 | } else { |
430 | if (!(myfile->f_op)) { | 431 | if (!(myfile->f_op)) { |
@@ -446,7 +447,7 @@ static int cx25821_openfile(struct cx25821_dev *dev, | |||
446 | set_fs(KERNEL_DS); | 447 | set_fs(KERNEL_DS); |
447 | 448 | ||
448 | for (j = 0; j < NUM_FRAMES; j++) { | 449 | for (j = 0; j < NUM_FRAMES; j++) { |
449 | for (i = 0; i < dev->_lines_count; i++) { | 450 | for (i = 0; i < out->_lines_count; i++) { |
450 | pos = offset; | 451 | pos = offset; |
451 | 452 | ||
452 | vfs_read_retval = vfs_read(myfile, mybuf, | 453 | vfs_read_retval = vfs_read(myfile, mybuf, |
@@ -454,8 +455,8 @@ static int cx25821_openfile(struct cx25821_dev *dev, | |||
454 | 455 | ||
455 | if (vfs_read_retval > 0 | 456 | if (vfs_read_retval > 0 |
456 | && vfs_read_retval == line_size | 457 | && vfs_read_retval == line_size |
457 | && dev->_data_buf_virt_addr != NULL) { | 458 | && out->_data_buf_virt_addr != NULL) { |
458 | memcpy((void *)(dev-> | 459 | memcpy((void *)(out-> |
459 | _data_buf_virt_addr + | 460 | _data_buf_virt_addr + |
460 | offset / 4), mybuf, | 461 | offset / 4), mybuf, |
461 | vfs_read_retval); | 462 | vfs_read_retval); |
@@ -471,13 +472,13 @@ static int cx25821_openfile(struct cx25821_dev *dev, | |||
471 | } | 472 | } |
472 | 473 | ||
473 | if (i > 0) | 474 | if (i > 0) |
474 | dev->_frame_count++; | 475 | out->_frame_count++; |
475 | 476 | ||
476 | if (vfs_read_retval < line_size) | 477 | if (vfs_read_retval < line_size) |
477 | break; | 478 | break; |
478 | } | 479 | } |
479 | 480 | ||
480 | dev->_file_status = (vfs_read_retval == line_size) ? | 481 | out->_file_status = (vfs_read_retval == line_size) ? |
481 | IN_PROGRESS : END_OF_FILE; | 482 | IN_PROGRESS : END_OF_FILE; |
482 | 483 | ||
483 | set_fs(old_fs); | 484 | set_fs(old_fs); |
@@ -488,58 +489,60 @@ static int cx25821_openfile(struct cx25821_dev *dev, | |||
488 | return 0; | 489 | return 0; |
489 | } | 490 | } |
490 | 491 | ||
491 | static int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev, | 492 | static int cx25821_upstream_buffer_prepare(struct cx25821_channel *chan, |
492 | const struct sram_channel *sram_ch, | 493 | const struct sram_channel *sram_ch, |
493 | int bpl) | 494 | int bpl) |
494 | { | 495 | { |
496 | struct cx25821_video_out_data *out = chan->out; | ||
497 | struct cx25821_dev *dev = chan->dev; | ||
495 | int ret = 0; | 498 | int ret = 0; |
496 | dma_addr_t dma_addr; | 499 | dma_addr_t dma_addr; |
497 | dma_addr_t data_dma_addr; | 500 | dma_addr_t data_dma_addr; |
498 | 501 | ||
499 | if (dev->_dma_virt_addr != NULL) | 502 | if (out->_dma_virt_addr != NULL) |
500 | pci_free_consistent(dev->pci, dev->upstream_riscbuf_size, | 503 | pci_free_consistent(dev->pci, out->upstream_riscbuf_size, |
501 | dev->_dma_virt_addr, dev->_dma_phys_addr); | 504 | out->_dma_virt_addr, out->_dma_phys_addr); |
502 | 505 | ||
503 | dev->_dma_virt_addr = pci_alloc_consistent(dev->pci, | 506 | out->_dma_virt_addr = pci_alloc_consistent(dev->pci, |
504 | dev->upstream_riscbuf_size, &dma_addr); | 507 | out->upstream_riscbuf_size, &dma_addr); |
505 | dev->_dma_virt_start_addr = dev->_dma_virt_addr; | 508 | out->_dma_virt_start_addr = out->_dma_virt_addr; |
506 | dev->_dma_phys_start_addr = dma_addr; | 509 | out->_dma_phys_start_addr = dma_addr; |
507 | dev->_dma_phys_addr = dma_addr; | 510 | out->_dma_phys_addr = dma_addr; |
508 | dev->_risc_size = dev->upstream_riscbuf_size; | 511 | out->_risc_size = out->upstream_riscbuf_size; |
509 | 512 | ||
510 | if (!dev->_dma_virt_addr) { | 513 | if (!out->_dma_virt_addr) { |
511 | pr_err("FAILED to allocate memory for Risc buffer! Returning\n"); | 514 | pr_err("FAILED to allocate memory for Risc buffer! Returning\n"); |
512 | return -ENOMEM; | 515 | return -ENOMEM; |
513 | } | 516 | } |
514 | 517 | ||
515 | /* Clear memory at address */ | 518 | /* Clear memory at address */ |
516 | memset(dev->_dma_virt_addr, 0, dev->_risc_size); | 519 | memset(out->_dma_virt_addr, 0, out->_risc_size); |
517 | 520 | ||
518 | if (dev->_data_buf_virt_addr != NULL) | 521 | if (out->_data_buf_virt_addr != NULL) |
519 | pci_free_consistent(dev->pci, dev->upstream_databuf_size, | 522 | pci_free_consistent(dev->pci, out->upstream_databuf_size, |
520 | dev->_data_buf_virt_addr, | 523 | out->_data_buf_virt_addr, |
521 | dev->_data_buf_phys_addr); | 524 | out->_data_buf_phys_addr); |
522 | /* For Video Data buffer allocation */ | 525 | /* For Video Data buffer allocation */ |
523 | dev->_data_buf_virt_addr = pci_alloc_consistent(dev->pci, | 526 | out->_data_buf_virt_addr = pci_alloc_consistent(dev->pci, |
524 | dev->upstream_databuf_size, &data_dma_addr); | 527 | out->upstream_databuf_size, &data_dma_addr); |
525 | dev->_data_buf_phys_addr = data_dma_addr; | 528 | out->_data_buf_phys_addr = data_dma_addr; |
526 | dev->_data_buf_size = dev->upstream_databuf_size; | 529 | out->_data_buf_size = out->upstream_databuf_size; |
527 | 530 | ||
528 | if (!dev->_data_buf_virt_addr) { | 531 | if (!out->_data_buf_virt_addr) { |
529 | pr_err("FAILED to allocate memory for data buffer! Returning\n"); | 532 | pr_err("FAILED to allocate memory for data buffer! Returning\n"); |
530 | return -ENOMEM; | 533 | return -ENOMEM; |
531 | } | 534 | } |
532 | 535 | ||
533 | /* Clear memory at address */ | 536 | /* Clear memory at address */ |
534 | memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size); | 537 | memset(out->_data_buf_virt_addr, 0, out->_data_buf_size); |
535 | 538 | ||
536 | ret = cx25821_openfile(dev, sram_ch); | 539 | ret = cx25821_openfile(chan, sram_ch); |
537 | if (ret < 0) | 540 | if (ret < 0) |
538 | return ret; | 541 | return ret; |
539 | 542 | ||
540 | /* Create RISC programs */ | 543 | /* Create RISC programs */ |
541 | ret = cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl, | 544 | ret = cx25821_risc_buffer_upstream(chan, dev->pci, 0, bpl, |
542 | dev->_lines_count); | 545 | out->_lines_count); |
543 | if (ret < 0) { | 546 | if (ret < 0) { |
544 | pr_info("Failed creating Video Upstream Risc programs!\n"); | 547 | pr_info("Failed creating Video Upstream Risc programs!\n"); |
545 | goto error; | 548 | goto error; |
@@ -551,11 +554,12 @@ error: | |||
551 | return ret; | 554 | return ret; |
552 | } | 555 | } |
553 | 556 | ||
554 | static int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num, | 557 | static int cx25821_video_upstream_irq(struct cx25821_channel *chan, u32 status) |
555 | u32 status) | ||
556 | { | 558 | { |
559 | struct cx25821_video_out_data *out = chan->out; | ||
560 | struct cx25821_dev *dev = chan->dev; | ||
557 | u32 int_msk_tmp; | 561 | u32 int_msk_tmp; |
558 | const struct sram_channel *channel = dev->channels[chan_num].sram_channels; | 562 | const struct sram_channel *channel = chan->sram_channels; |
559 | int singlefield_lines = NTSC_FIELD_HEIGHT; | 563 | int singlefield_lines = NTSC_FIELD_HEIGHT; |
560 | int line_size_in_bytes = Y422_LINE_SZ; | 564 | int line_size_in_bytes = Y422_LINE_SZ; |
561 | int odd_risc_prog_size = 0; | 565 | int odd_risc_prog_size = 0; |
@@ -574,14 +578,14 @@ static int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num, | |||
574 | 578 | ||
575 | spin_lock(&dev->slock); | 579 | spin_lock(&dev->slock); |
576 | 580 | ||
577 | dev->_frame_index = prog_cnt; | 581 | out->_frame_index = prog_cnt; |
578 | 582 | ||
579 | queue_work(dev->_irq_queues, &dev->_irq_work_entry); | 583 | queue_work(out->_irq_queues, &out->_irq_work_entry); |
580 | 584 | ||
581 | if (dev->_is_first_frame) { | 585 | if (out->_is_first_frame) { |
582 | dev->_is_first_frame = 0; | 586 | out->_is_first_frame = 0; |
583 | 587 | ||
584 | if (dev->_isNTSC) { | 588 | if (out->is_60hz) { |
585 | singlefield_lines += 1; | 589 | singlefield_lines += 1; |
586 | odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE; | 590 | odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE; |
587 | } else { | 591 | } else { |
@@ -589,17 +593,17 @@ static int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num, | |||
589 | odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE; | 593 | odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE; |
590 | } | 594 | } |
591 | 595 | ||
592 | if (dev->_dma_virt_start_addr != NULL) { | 596 | if (out->_dma_virt_start_addr != NULL) { |
593 | line_size_in_bytes = | 597 | line_size_in_bytes = |
594 | (dev->_pixel_format == | 598 | (out->_pixel_format == |
595 | PIXEL_FRMT_411) ? Y411_LINE_SZ : | 599 | PIXEL_FRMT_411) ? Y411_LINE_SZ : |
596 | Y422_LINE_SZ; | 600 | Y422_LINE_SZ; |
597 | risc_phys_jump_addr = | 601 | risc_phys_jump_addr = |
598 | dev->_dma_phys_start_addr + | 602 | out->_dma_phys_start_addr + |
599 | odd_risc_prog_size; | 603 | odd_risc_prog_size; |
600 | 604 | ||
601 | rp = cx25821_update_riscprogram(dev, | 605 | rp = cx25821_update_riscprogram(chan, |
602 | dev->_dma_virt_start_addr, TOP_OFFSET, | 606 | out->_dma_virt_start_addr, TOP_OFFSET, |
603 | line_size_in_bytes, 0x0, | 607 | line_size_in_bytes, 0x0, |
604 | singlefield_lines, FIFO_DISABLE, | 608 | singlefield_lines, FIFO_DISABLE, |
605 | ODD_FIELD); | 609 | ODD_FIELD); |
@@ -626,8 +630,8 @@ static int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num, | |||
626 | __func__); | 630 | __func__); |
627 | } | 631 | } |
628 | 632 | ||
629 | if (dev->_file_status == END_OF_FILE) { | 633 | if (out->_file_status == END_OF_FILE) { |
630 | pr_err("EOF Channel 1 Framecount = %d\n", dev->_frame_count); | 634 | pr_err("EOF Channel 1 Framecount = %d\n", out->_frame_count); |
631 | return -1; | 635 | return -1; |
632 | } | 636 | } |
633 | /* ElSE, set the interrupt mask register, re-enable irq. */ | 637 | /* ElSE, set the interrupt mask register, re-enable irq. */ |
@@ -639,47 +643,41 @@ static int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num, | |||
639 | 643 | ||
640 | static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id) | 644 | static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id) |
641 | { | 645 | { |
642 | struct cx25821_dev *dev = dev_id; | 646 | struct cx25821_channel *chan = dev_id; |
647 | struct cx25821_dev *dev = chan->dev; | ||
643 | u32 vid_status; | 648 | u32 vid_status; |
644 | int handled = 0; | 649 | int handled = 0; |
645 | int channel_num = 0; | ||
646 | const struct sram_channel *sram_ch; | 650 | const struct sram_channel *sram_ch; |
647 | 651 | ||
648 | if (!dev) | 652 | if (!dev) |
649 | return -1; | 653 | return -1; |
650 | 654 | ||
651 | channel_num = VID_UPSTREAM_SRAM_CHANNEL_I; | 655 | sram_ch = chan->sram_channels; |
652 | |||
653 | sram_ch = dev->channels[channel_num].sram_channels; | ||
654 | 656 | ||
655 | vid_status = cx_read(sram_ch->int_stat); | 657 | vid_status = cx_read(sram_ch->int_stat); |
656 | 658 | ||
657 | /* Only deal with our interrupt */ | 659 | /* Only deal with our interrupt */ |
658 | if (vid_status) | 660 | if (vid_status) |
659 | handled = cx25821_video_upstream_irq(dev, channel_num, | 661 | handled = cx25821_video_upstream_irq(chan, vid_status); |
660 | vid_status); | ||
661 | |||
662 | if (handled < 0) | ||
663 | cx25821_stop_upstream_video_ch1(dev); | ||
664 | else | ||
665 | handled += handled; | ||
666 | 662 | ||
667 | return IRQ_RETVAL(handled); | 663 | return IRQ_RETVAL(handled); |
668 | } | 664 | } |
669 | 665 | ||
670 | static void cx25821_set_pixelengine(struct cx25821_dev *dev, | 666 | static void cx25821_set_pixelengine(struct cx25821_channel *chan, |
671 | const struct sram_channel *ch, | 667 | const struct sram_channel *ch, |
672 | int pix_format) | 668 | int pix_format) |
673 | { | 669 | { |
670 | struct cx25821_video_out_data *out = chan->out; | ||
671 | struct cx25821_dev *dev = chan->dev; | ||
674 | int width = WIDTH_D1; | 672 | int width = WIDTH_D1; |
675 | int height = dev->_lines_count; | 673 | int height = out->_lines_count; |
676 | int num_lines, odd_num_lines; | 674 | int num_lines, odd_num_lines; |
677 | u32 value; | 675 | u32 value; |
678 | int vip_mode = OUTPUT_FRMT_656; | 676 | int vip_mode = OUTPUT_FRMT_656; |
679 | 677 | ||
680 | value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7); | 678 | value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7); |
681 | value &= 0xFFFFFFEF; | 679 | value &= 0xFFFFFFEF; |
682 | value |= dev->_isNTSC ? 0 : 0x10; | 680 | value |= out->is_60hz ? 0 : 0x10; |
683 | cx_write(ch->vid_fmt_ctl, value); | 681 | cx_write(ch->vid_fmt_ctl, value); |
684 | 682 | ||
685 | /* set number of active pixels in each line. | 683 | /* set number of active pixels in each line. |
@@ -689,7 +687,7 @@ static void cx25821_set_pixelengine(struct cx25821_dev *dev, | |||
689 | num_lines = (height / 2) & 0x3FF; | 687 | num_lines = (height / 2) & 0x3FF; |
690 | odd_num_lines = num_lines; | 688 | odd_num_lines = num_lines; |
691 | 689 | ||
692 | if (dev->_isNTSC) | 690 | if (out->is_60hz) |
693 | odd_num_lines += 1; | 691 | odd_num_lines += 1; |
694 | 692 | ||
695 | value = (num_lines << 16) | odd_num_lines; | 693 | value = (num_lines << 16) | odd_num_lines; |
@@ -700,9 +698,11 @@ static void cx25821_set_pixelengine(struct cx25821_dev *dev, | |||
700 | cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3); | 698 | cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3); |
701 | } | 699 | } |
702 | 700 | ||
703 | static int cx25821_start_video_dma_upstream(struct cx25821_dev *dev, | 701 | static int cx25821_start_video_dma_upstream(struct cx25821_channel *chan, |
704 | const struct sram_channel *sram_ch) | 702 | const struct sram_channel *sram_ch) |
705 | { | 703 | { |
704 | struct cx25821_video_out_data *out = chan->out; | ||
705 | struct cx25821_dev *dev = chan->dev; | ||
706 | u32 tmp = 0; | 706 | u32 tmp = 0; |
707 | int err = 0; | 707 | int err = 0; |
708 | 708 | ||
@@ -715,7 +715,7 @@ static int cx25821_start_video_dma_upstream(struct cx25821_dev *dev, | |||
715 | /* Set the physical start address of the RISC program in the initial | 715 | /* Set the physical start address of the RISC program in the initial |
716 | * program counter(IPC) member of the cmds. | 716 | * program counter(IPC) member of the cmds. |
717 | */ | 717 | */ |
718 | cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr); | 718 | cx_write(sram_ch->cmds_start + 0, out->_dma_phys_addr); |
719 | /* Risc IPC High 64 bits 63-32 */ | 719 | /* Risc IPC High 64 bits 63-32 */ |
720 | cx_write(sram_ch->cmds_start + 4, 0); | 720 | cx_write(sram_ch->cmds_start + 4, 0); |
721 | 721 | ||
@@ -731,7 +731,7 @@ static int cx25821_start_video_dma_upstream(struct cx25821_dev *dev, | |||
731 | cx_write(sram_ch->int_msk, tmp |= _intr_msk); | 731 | cx_write(sram_ch->int_msk, tmp |= _intr_msk); |
732 | 732 | ||
733 | err = request_irq(dev->pci->irq, cx25821_upstream_irq, | 733 | err = request_irq(dev->pci->irq, cx25821_upstream_irq, |
734 | IRQF_SHARED, dev->name, dev); | 734 | IRQF_SHARED, dev->name, chan); |
735 | if (err < 0) { | 735 | if (err < 0) { |
736 | pr_err("%s: can't get upstream IRQ %d\n", | 736 | pr_err("%s: can't get upstream IRQ %d\n", |
737 | dev->name, dev->pci->irq); | 737 | dev->name, dev->pci->irq); |
@@ -742,8 +742,8 @@ static int cx25821_start_video_dma_upstream(struct cx25821_dev *dev, | |||
742 | tmp = cx_read(sram_ch->dma_ctl); | 742 | tmp = cx_read(sram_ch->dma_ctl); |
743 | cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN); | 743 | cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN); |
744 | 744 | ||
745 | dev->_is_running = 1; | 745 | out->_is_running = 1; |
746 | dev->_is_first_frame = 1; | 746 | out->_is_first_frame = 1; |
747 | 747 | ||
748 | return 0; | 748 | return 0; |
749 | 749 | ||
@@ -752,9 +752,11 @@ fail_irq: | |||
752 | return err; | 752 | return err; |
753 | } | 753 | } |
754 | 754 | ||
755 | int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select, | 755 | int cx25821_vidupstream_init(struct cx25821_channel *chan, |
756 | int pixel_format) | 756 | int pixel_format) |
757 | { | 757 | { |
758 | struct cx25821_video_out_data *out = chan->out; | ||
759 | struct cx25821_dev *dev = chan->dev; | ||
758 | const struct sram_channel *sram_ch; | 760 | const struct sram_channel *sram_ch; |
759 | u32 tmp; | 761 | u32 tmp; |
760 | int err = 0; | 762 | int err = 0; |
@@ -762,18 +764,17 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select, | |||
762 | int risc_buffer_size = 0; | 764 | int risc_buffer_size = 0; |
763 | int str_length = 0; | 765 | int str_length = 0; |
764 | 766 | ||
765 | if (dev->_is_running) { | 767 | if (out->_is_running) { |
766 | pr_info("Video Channel is still running so return!\n"); | 768 | pr_info("Video Channel is still running so return!\n"); |
767 | return 0; | 769 | return 0; |
768 | } | 770 | } |
769 | 771 | ||
770 | dev->_channel_upstream_select = channel_select; | 772 | sram_ch = chan->sram_channels; |
771 | sram_ch = dev->channels[channel_select].sram_channels; | ||
772 | 773 | ||
773 | INIT_WORK(&dev->_irq_work_entry, cx25821_vidups_handler); | 774 | INIT_WORK(&out->_irq_work_entry, cx25821_vidups_handler); |
774 | dev->_irq_queues = create_singlethread_workqueue("cx25821_workqueue"); | 775 | out->_irq_queues = create_singlethread_workqueue("cx25821_workqueue"); |
775 | 776 | ||
776 | if (!dev->_irq_queues) { | 777 | if (!out->_irq_queues) { |
777 | pr_err("create_singlethread_workqueue() for Video FAILED!\n"); | 778 | pr_err("create_singlethread_workqueue() for Video FAILED!\n"); |
778 | return -ENOMEM; | 779 | return -ENOMEM; |
779 | } | 780 | } |
@@ -783,76 +784,76 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select, | |||
783 | tmp = cx_read(VID_CH_MODE_SEL); | 784 | tmp = cx_read(VID_CH_MODE_SEL); |
784 | cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); | 785 | cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); |
785 | 786 | ||
786 | dev->_is_running = 0; | 787 | out->_is_running = 0; |
787 | dev->_frame_count = 0; | 788 | out->_frame_count = 0; |
788 | dev->_file_status = RESET_STATUS; | 789 | out->_file_status = RESET_STATUS; |
789 | dev->_lines_count = dev->_isNTSC ? 480 : 576; | 790 | out->_lines_count = out->is_60hz ? 480 : 576; |
790 | dev->_pixel_format = pixel_format; | 791 | out->_pixel_format = pixel_format; |
791 | dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ? | 792 | out->_line_size = (out->_pixel_format == PIXEL_FRMT_422) ? |
792 | (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; | 793 | (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; |
793 | data_frame_size = dev->_isNTSC ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ; | 794 | data_frame_size = out->is_60hz ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ; |
794 | risc_buffer_size = dev->_isNTSC ? | 795 | risc_buffer_size = out->is_60hz ? |
795 | NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; | 796 | NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; |
796 | 797 | ||
797 | if (dev->input_filename) { | 798 | if (out->input_filename) { |
798 | str_length = strlen(dev->input_filename); | 799 | str_length = strlen(out->input_filename); |
799 | dev->_filename = kmemdup(dev->input_filename, str_length + 1, | 800 | out->_filename = kmemdup(out->input_filename, str_length + 1, |
800 | GFP_KERNEL); | 801 | GFP_KERNEL); |
801 | 802 | ||
802 | if (!dev->_filename) { | 803 | if (!out->_filename) { |
803 | err = -ENOENT; | 804 | err = -ENOENT; |
804 | goto error; | 805 | goto error; |
805 | } | 806 | } |
806 | } else { | 807 | } else { |
807 | str_length = strlen(dev->_defaultname); | 808 | str_length = strlen(out->_defaultname); |
808 | dev->_filename = kmemdup(dev->_defaultname, str_length + 1, | 809 | out->_filename = kmemdup(out->_defaultname, str_length + 1, |
809 | GFP_KERNEL); | 810 | GFP_KERNEL); |
810 | 811 | ||
811 | if (!dev->_filename) { | 812 | if (!out->_filename) { |
812 | err = -ENOENT; | 813 | err = -ENOENT; |
813 | goto error; | 814 | goto error; |
814 | } | 815 | } |
815 | } | 816 | } |
816 | 817 | ||
817 | /* Default if filename is empty string */ | 818 | /* Default if filename is empty string */ |
818 | if (strcmp(dev->_filename, "") == 0) { | 819 | if (strcmp(out->_filename, "") == 0) { |
819 | if (dev->_isNTSC) { | 820 | if (out->is_60hz) { |
820 | dev->_filename = | 821 | out->_filename = |
821 | (dev->_pixel_format == PIXEL_FRMT_411) ? | 822 | (out->_pixel_format == PIXEL_FRMT_411) ? |
822 | "/root/vid411.yuv" : "/root/vidtest.yuv"; | 823 | "/root/vid411.yuv" : "/root/vidtest.yuv"; |
823 | } else { | 824 | } else { |
824 | dev->_filename = | 825 | out->_filename = |
825 | (dev->_pixel_format == PIXEL_FRMT_411) ? | 826 | (out->_pixel_format == PIXEL_FRMT_411) ? |
826 | "/root/pal411.yuv" : "/root/pal422.yuv"; | 827 | "/root/pal411.yuv" : "/root/pal422.yuv"; |
827 | } | 828 | } |
828 | } | 829 | } |
829 | 830 | ||
830 | dev->_is_running = 0; | 831 | out->_is_running = 0; |
831 | dev->_frame_count = 0; | 832 | out->_frame_count = 0; |
832 | dev->_file_status = RESET_STATUS; | 833 | out->_file_status = RESET_STATUS; |
833 | dev->_lines_count = dev->_isNTSC ? 480 : 576; | 834 | out->_lines_count = out->is_60hz ? 480 : 576; |
834 | dev->_pixel_format = pixel_format; | 835 | out->_pixel_format = pixel_format; |
835 | dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ? | 836 | out->_line_size = (out->_pixel_format == PIXEL_FRMT_422) ? |
836 | (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; | 837 | (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; |
837 | 838 | ||
838 | err = cx25821_sram_channel_setup_upstream(dev, sram_ch, | 839 | err = cx25821_sram_channel_setup_upstream(dev, sram_ch, |
839 | dev->_line_size, 0); | 840 | out->_line_size, 0); |
840 | 841 | ||
841 | /* setup fifo + format */ | 842 | /* setup fifo + format */ |
842 | cx25821_set_pixelengine(dev, sram_ch, dev->_pixel_format); | 843 | cx25821_set_pixelengine(chan, sram_ch, out->_pixel_format); |
843 | 844 | ||
844 | dev->upstream_riscbuf_size = risc_buffer_size * 2; | 845 | out->upstream_riscbuf_size = risc_buffer_size * 2; |
845 | dev->upstream_databuf_size = data_frame_size * 2; | 846 | out->upstream_databuf_size = data_frame_size * 2; |
846 | 847 | ||
847 | /* Allocating buffers and prepare RISC program */ | 848 | /* Allocating buffers and prepare RISC program */ |
848 | err = cx25821_upstream_buffer_prepare(dev, sram_ch, dev->_line_size); | 849 | err = cx25821_upstream_buffer_prepare(chan, sram_ch, out->_line_size); |
849 | if (err < 0) { | 850 | if (err < 0) { |
850 | pr_err("%s: Failed to set up Video upstream buffers!\n", | 851 | pr_err("%s: Failed to set up Video upstream buffers!\n", |
851 | dev->name); | 852 | dev->name); |
852 | goto error; | 853 | goto error; |
853 | } | 854 | } |
854 | 855 | ||
855 | cx25821_start_video_dma_upstream(dev, sram_ch); | 856 | cx25821_start_video_dma_upstream(chan, sram_ch); |
856 | 857 | ||
857 | return 0; | 858 | return 0; |
858 | 859 | ||
diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index 70e33b125969..dde0ba3d3401 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c | |||
@@ -893,6 +893,20 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *priv, | |||
893 | return 0; | 893 | return 0; |
894 | } | 894 | } |
895 | 895 | ||
896 | static int video_out_release(struct file *file) | ||
897 | { | ||
898 | struct cx25821_channel *chan = video_drvdata(file); | ||
899 | struct cx25821_video_out_data *out = chan->out; | ||
900 | struct cx25821_dev *dev = chan->dev; | ||
901 | |||
902 | mutex_lock(&dev->lock); | ||
903 | if ((chan->id == SRAM_CH09 || chan->id == SRAM_CH10) && out->_is_running) | ||
904 | cx25821_stop_upstream_video(chan); | ||
905 | mutex_unlock(&dev->lock); | ||
906 | |||
907 | return v4l2_fh_release(file); | ||
908 | } | ||
909 | |||
896 | static const struct v4l2_ctrl_ops cx25821_ctrl_ops = { | 910 | static const struct v4l2_ctrl_ops cx25821_ctrl_ops = { |
897 | .s_ctrl = cx25821_s_ctrl, | 911 | .s_ctrl = cx25821_s_ctrl, |
898 | }; | 912 | }; |
@@ -941,7 +955,7 @@ static const struct video_device cx25821_video_device = { | |||
941 | static const struct v4l2_file_operations video_out_fops = { | 955 | static const struct v4l2_file_operations video_out_fops = { |
942 | .owner = THIS_MODULE, | 956 | .owner = THIS_MODULE, |
943 | .open = v4l2_fh_open, | 957 | .open = v4l2_fh_open, |
944 | .release = v4l2_fh_release, | 958 | .release = video_out_release, |
945 | .unlocked_ioctl = video_ioctl2, | 959 | .unlocked_ioctl = video_ioctl2, |
946 | }; | 960 | }; |
947 | 961 | ||
@@ -1017,6 +1031,9 @@ int cx25821_video_register(struct cx25821_dev *dev) | |||
1017 | err = v4l2_ctrl_handler_setup(hdl); | 1031 | err = v4l2_ctrl_handler_setup(hdl); |
1018 | if (err) | 1032 | if (err) |
1019 | goto fail_unreg; | 1033 | goto fail_unreg; |
1034 | } else { | ||
1035 | chan->out = &dev->vid_out_data[i - SRAM_CH09]; | ||
1036 | chan->out->chan = chan; | ||
1020 | } | 1037 | } |
1021 | 1038 | ||
1022 | cx25821_risc_stopper(dev->pci, &chan->dma_vidq.stopper, | 1039 | cx25821_risc_stopper(dev->pci, &chan->dma_vidq.stopper, |
diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index 156ad6f2c634..b0bc2e626ae7 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h | |||
@@ -172,6 +172,42 @@ struct cx25821_data { | |||
172 | 172 | ||
173 | struct cx25821_dev; | 173 | struct cx25821_dev; |
174 | 174 | ||
175 | struct cx25821_channel; | ||
176 | |||
177 | struct cx25821_video_out_data { | ||
178 | struct cx25821_channel *chan; | ||
179 | int _line_size; | ||
180 | int _prog_cnt; | ||
181 | int _pixel_format; | ||
182 | int _is_first_frame; | ||
183 | int _is_running; | ||
184 | int _file_status; | ||
185 | int _lines_count; | ||
186 | int _frame_count; | ||
187 | unsigned int _risc_size; | ||
188 | |||
189 | __le32 *_dma_virt_start_addr; | ||
190 | __le32 *_dma_virt_addr; | ||
191 | dma_addr_t _dma_phys_addr; | ||
192 | dma_addr_t _dma_phys_start_addr; | ||
193 | |||
194 | unsigned int _data_buf_size; | ||
195 | __le32 *_data_buf_virt_addr; | ||
196 | dma_addr_t _data_buf_phys_addr; | ||
197 | |||
198 | u32 upstream_riscbuf_size; | ||
199 | u32 upstream_databuf_size; | ||
200 | struct workqueue_struct *_irq_queues; | ||
201 | struct work_struct _irq_work_entry; | ||
202 | int is_60hz; | ||
203 | int _frame_index; | ||
204 | char *input_filename; | ||
205 | char *vid_stdname; | ||
206 | int pixel_format; | ||
207 | char *_filename; | ||
208 | char *_defaultname; | ||
209 | }; | ||
210 | |||
175 | struct cx25821_channel { | 211 | struct cx25821_channel { |
176 | unsigned id; | 212 | unsigned id; |
177 | struct cx25821_dev *dev; | 213 | struct cx25821_dev *dev; |
@@ -191,6 +227,9 @@ struct cx25821_channel { | |||
191 | int pixel_formats; | 227 | int pixel_formats; |
192 | int use_cif_resolution; | 228 | int use_cif_resolution; |
193 | int cif_width; | 229 | int cif_width; |
230 | |||
231 | /* video output data for the video output channel */ | ||
232 | struct cx25821_video_out_data *out; | ||
194 | }; | 233 | }; |
195 | 234 | ||
196 | struct snd_card; | 235 | struct snd_card; |
@@ -250,83 +289,18 @@ struct cx25821_dev { | |||
250 | __le32 *_audiodata_buf_virt_addr; | 289 | __le32 *_audiodata_buf_virt_addr; |
251 | dma_addr_t _audiodata_buf_phys_addr; | 290 | dma_addr_t _audiodata_buf_phys_addr; |
252 | char *_audiofilename; | 291 | char *_audiofilename; |
253 | |||
254 | /* V4l */ | ||
255 | spinlock_t slock; | ||
256 | |||
257 | /* Video Upstream */ | ||
258 | int _line_size; | ||
259 | int _prog_cnt; | ||
260 | int _pixel_format; | ||
261 | int _is_first_frame; | ||
262 | int _is_running; | ||
263 | int _file_status; | ||
264 | int _lines_count; | ||
265 | int _frame_count; | ||
266 | int _channel_upstream_select; | ||
267 | unsigned int _risc_size; | ||
268 | |||
269 | __le32 *_dma_virt_start_addr; | ||
270 | __le32 *_dma_virt_addr; | ||
271 | dma_addr_t _dma_phys_addr; | ||
272 | dma_addr_t _dma_phys_start_addr; | ||
273 | |||
274 | unsigned int _data_buf_size; | ||
275 | __le32 *_data_buf_virt_addr; | ||
276 | dma_addr_t _data_buf_phys_addr; | ||
277 | char *_filename; | ||
278 | char *_defaultname; | ||
279 | |||
280 | int _line_size_ch2; | ||
281 | int _prog_cnt_ch2; | ||
282 | int _pixel_format_ch2; | ||
283 | int _is_first_frame_ch2; | ||
284 | int _is_running_ch2; | ||
285 | int _file_status_ch2; | ||
286 | int _lines_count_ch2; | ||
287 | int _frame_count_ch2; | ||
288 | int _channel2_upstream_select; | ||
289 | unsigned int _risc_size_ch2; | ||
290 | |||
291 | __le32 *_dma_virt_start_addr_ch2; | ||
292 | __le32 *_dma_virt_addr_ch2; | ||
293 | dma_addr_t _dma_phys_addr_ch2; | ||
294 | dma_addr_t _dma_phys_start_addr_ch2; | ||
295 | |||
296 | unsigned int _data_buf_size_ch2; | ||
297 | __le32 *_data_buf_virt_addr_ch2; | ||
298 | dma_addr_t _data_buf_phys_addr_ch2; | ||
299 | char *_filename_ch2; | ||
300 | char *_defaultname_ch2; | ||
301 | |||
302 | u32 upstream_riscbuf_size; | ||
303 | u32 upstream_databuf_size; | ||
304 | u32 upstream_riscbuf_size_ch2; | ||
305 | u32 upstream_databuf_size_ch2; | ||
306 | u32 audio_upstream_riscbuf_size; | 292 | u32 audio_upstream_riscbuf_size; |
307 | u32 audio_upstream_databuf_size; | 293 | u32 audio_upstream_databuf_size; |
308 | int _isNTSC; | ||
309 | int _frame_index; | ||
310 | int _audioframe_index; | 294 | int _audioframe_index; |
311 | struct workqueue_struct *_irq_queues; | ||
312 | struct work_struct _irq_work_entry; | ||
313 | struct workqueue_struct *_irq_queues_ch2; | ||
314 | struct work_struct _irq_work_entry_ch2; | ||
315 | struct workqueue_struct *_irq_audio_queues; | 295 | struct workqueue_struct *_irq_audio_queues; |
316 | struct work_struct _audio_work_entry; | 296 | struct work_struct _audio_work_entry; |
317 | char *input_filename; | ||
318 | char *input_filename_ch2; | ||
319 | int _frame_index_ch2; | ||
320 | int _isNTSC_ch2; | ||
321 | char *vid_stdname_ch2; | ||
322 | int pixel_format_ch2; | ||
323 | int channel_select_ch2; | ||
324 | int command_ch2; | ||
325 | char *input_audiofilename; | 297 | char *input_audiofilename; |
326 | char *vid_stdname; | 298 | |
327 | int pixel_format; | 299 | /* V4l */ |
328 | int channel_select; | 300 | spinlock_t slock; |
329 | int command; | 301 | |
302 | /* Video Upstream */ | ||
303 | struct cx25821_video_out_data vid_out_data[2]; | ||
330 | }; | 304 | }; |
331 | 305 | ||
332 | static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev) | 306 | static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev) |
@@ -463,17 +437,12 @@ extern int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev, | |||
463 | const struct sram_channel *ch, | 437 | const struct sram_channel *ch, |
464 | unsigned int bpl, u32 risc); | 438 | unsigned int bpl, u32 risc); |
465 | 439 | ||
466 | extern int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, | 440 | extern int cx25821_vidupstream_init(struct cx25821_channel *chan, int pixel_format); |
467 | int channel_select, int pixel_format); | ||
468 | extern int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, | ||
469 | int channel_select, int pixel_format); | ||
470 | extern int cx25821_audio_upstream_init(struct cx25821_dev *dev, | 441 | extern int cx25821_audio_upstream_init(struct cx25821_dev *dev, |
471 | int channel_select); | 442 | int channel_select); |
472 | extern void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev); | 443 | extern void cx25821_free_mem_upstream(struct cx25821_channel *chan); |
473 | extern void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev); | ||
474 | extern void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev); | 444 | extern void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev); |
475 | extern void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev); | 445 | extern void cx25821_stop_upstream_video(struct cx25821_channel *chan); |
476 | extern void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev); | ||
477 | extern void cx25821_stop_upstream_audio(struct cx25821_dev *dev); | 446 | extern void cx25821_stop_upstream_audio(struct cx25821_dev *dev); |
478 | extern int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev, | 447 | extern int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev, |
479 | const struct sram_channel *ch, | 448 | const struct sram_channel *ch, |