diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/media/video/zoran_device.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/media/video/zoran_device.c')
-rw-r--r-- | drivers/media/video/zoran_device.c | 1785 |
1 files changed, 1785 insertions, 0 deletions
diff --git a/drivers/media/video/zoran_device.c b/drivers/media/video/zoran_device.c new file mode 100644 index 000000000000..4e15afdec4c9 --- /dev/null +++ b/drivers/media/video/zoran_device.c | |||
@@ -0,0 +1,1785 @@ | |||
1 | /* | ||
2 | * Zoran zr36057/zr36067 PCI controller driver, for the | ||
3 | * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux | ||
4 | * Media Labs LML33/LML33R10. | ||
5 | * | ||
6 | * This part handles device access (PCI/I2C/codec/...) | ||
7 | * | ||
8 | * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx> | ||
9 | * | ||
10 | * Currently maintained by: | ||
11 | * Ronald Bultje <rbultje@ronald.bitfreak.net> | ||
12 | * Laurent Pinchart <laurent.pinchart@skynet.be> | ||
13 | * Mailinglist <mjpeg-users@lists.sf.net> | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or modify | ||
16 | * it under the terms of the GNU General Public License as published by | ||
17 | * the Free Software Foundation; either version 2 of the License, or | ||
18 | * (at your option) any later version. | ||
19 | * | ||
20 | * This program is distributed in the hope that it will be useful, | ||
21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
23 | * GNU General Public License for more details. | ||
24 | * | ||
25 | * You should have received a copy of the GNU General Public License | ||
26 | * along with this program; if not, write to the Free Software | ||
27 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
28 | */ | ||
29 | |||
30 | #include <linux/config.h> | ||
31 | #include <linux/types.h> | ||
32 | #include <linux/kernel.h> | ||
33 | #include <linux/module.h> | ||
34 | #include <linux/vmalloc.h> | ||
35 | #include <linux/byteorder/generic.h> | ||
36 | |||
37 | #include <linux/interrupt.h> | ||
38 | #include <linux/proc_fs.h> | ||
39 | #include <linux/i2c.h> | ||
40 | #include <linux/i2c-algo-bit.h> | ||
41 | #include <linux/videodev.h> | ||
42 | #include <linux/spinlock.h> | ||
43 | #include <linux/sem.h> | ||
44 | |||
45 | #include <linux/pci.h> | ||
46 | #include <linux/video_decoder.h> | ||
47 | #include <linux/video_encoder.h> | ||
48 | #include <linux/delay.h> | ||
49 | #include <linux/wait.h> | ||
50 | |||
51 | #include <asm/io.h> | ||
52 | |||
53 | #include "videocodec.h" | ||
54 | #include "zoran.h" | ||
55 | #include "zoran_device.h" | ||
56 | |||
57 | #define IRQ_MASK ( ZR36057_ISR_GIRQ0 | \ | ||
58 | ZR36057_ISR_GIRQ1 | \ | ||
59 | ZR36057_ISR_JPEGRepIRQ ) | ||
60 | |||
61 | extern const struct zoran_format zoran_formats[]; | ||
62 | |||
63 | extern int *zr_debug; | ||
64 | |||
65 | #define dprintk(num, format, args...) \ | ||
66 | do { \ | ||
67 | if (*zr_debug >= num) \ | ||
68 | printk(format, ##args); \ | ||
69 | } while (0) | ||
70 | |||
71 | static int lml33dpath = 0; /* 1 will use digital path in capture | ||
72 | * mode instead of analog. It can be | ||
73 | * used for picture adjustments using | ||
74 | * tool like xawtv while watching image | ||
75 | * on TV monitor connected to the output. | ||
76 | * However, due to absence of 75 Ohm | ||
77 | * load on Bt819 input, there will be | ||
78 | * some image imperfections */ | ||
79 | |||
80 | module_param(lml33dpath, bool, 0); | ||
81 | MODULE_PARM_DESC(lml33dpath, | ||
82 | "Use digital path capture mode (on LML33 cards)"); | ||
83 | |||
84 | static void | ||
85 | zr36057_init_vfe (struct zoran *zr); | ||
86 | |||
87 | /* | ||
88 | * General Purpose I/O and Guest bus access | ||
89 | */ | ||
90 | |||
91 | /* | ||
92 | * This is a bit tricky. When a board lacks a GPIO function, the corresponding | ||
93 | * GPIO bit number in the card_info structure is set to 0. | ||
94 | */ | ||
95 | |||
96 | void | ||
97 | GPIO (struct zoran *zr, | ||
98 | int bit, | ||
99 | unsigned int value) | ||
100 | { | ||
101 | u32 reg; | ||
102 | u32 mask; | ||
103 | |||
104 | /* Make sure the bit number is legal | ||
105 | * A bit number of -1 (lacking) gives a mask of 0, | ||
106 | * making it harmless */ | ||
107 | mask = (1 << (24 + bit)) & 0xff000000; | ||
108 | reg = btread(ZR36057_GPPGCR1) & ~mask; | ||
109 | if (value) { | ||
110 | reg |= mask; | ||
111 | } | ||
112 | btwrite(reg, ZR36057_GPPGCR1); | ||
113 | udelay(1); | ||
114 | } | ||
115 | |||
116 | /* | ||
117 | * Wait til post office is no longer busy | ||
118 | */ | ||
119 | |||
120 | int | ||
121 | post_office_wait (struct zoran *zr) | ||
122 | { | ||
123 | u32 por; | ||
124 | |||
125 | // while (((por = btread(ZR36057_POR)) & (ZR36057_POR_POPen | ZR36057_POR_POTime)) == ZR36057_POR_POPen) { | ||
126 | while ((por = btread(ZR36057_POR)) & ZR36057_POR_POPen) { | ||
127 | /* wait for something to happen */ | ||
128 | } | ||
129 | if ((por & ZR36057_POR_POTime) && !zr->card.gws_not_connected) { | ||
130 | /* In LML33/BUZ \GWS line is not connected, so it has always timeout set */ | ||
131 | dprintk(1, KERN_INFO "%s: pop timeout %08x\n", ZR_DEVNAME(zr), | ||
132 | por); | ||
133 | return -1; | ||
134 | } | ||
135 | |||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | int | ||
140 | post_office_write (struct zoran *zr, | ||
141 | unsigned int guest, | ||
142 | unsigned int reg, | ||
143 | unsigned int value) | ||
144 | { | ||
145 | u32 por; | ||
146 | |||
147 | por = | ||
148 | ZR36057_POR_PODir | ZR36057_POR_POTime | ((guest & 7) << 20) | | ||
149 | ((reg & 7) << 16) | (value & 0xFF); | ||
150 | btwrite(por, ZR36057_POR); | ||
151 | |||
152 | return post_office_wait(zr); | ||
153 | } | ||
154 | |||
155 | int | ||
156 | post_office_read (struct zoran *zr, | ||
157 | unsigned int guest, | ||
158 | unsigned int reg) | ||
159 | { | ||
160 | u32 por; | ||
161 | |||
162 | por = ZR36057_POR_POTime | ((guest & 7) << 20) | ((reg & 7) << 16); | ||
163 | btwrite(por, ZR36057_POR); | ||
164 | if (post_office_wait(zr) < 0) { | ||
165 | return -1; | ||
166 | } | ||
167 | |||
168 | return btread(ZR36057_POR) & 0xFF; | ||
169 | } | ||
170 | |||
171 | /* | ||
172 | * detect guests | ||
173 | */ | ||
174 | |||
175 | static void | ||
176 | dump_guests (struct zoran *zr) | ||
177 | { | ||
178 | if (*zr_debug > 2) { | ||
179 | int i, guest[8]; | ||
180 | |||
181 | for (i = 1; i < 8; i++) { // Don't read jpeg codec here | ||
182 | guest[i] = post_office_read(zr, i, 0); | ||
183 | } | ||
184 | |||
185 | printk(KERN_INFO "%s: Guests:", ZR_DEVNAME(zr)); | ||
186 | |||
187 | for (i = 1; i < 8; i++) { | ||
188 | printk(" 0x%02x", guest[i]); | ||
189 | } | ||
190 | printk("\n"); | ||
191 | } | ||
192 | } | ||
193 | |||
194 | static inline unsigned long | ||
195 | get_time (void) | ||
196 | { | ||
197 | struct timeval tv; | ||
198 | |||
199 | do_gettimeofday(&tv); | ||
200 | return (1000000 * tv.tv_sec + tv.tv_usec); | ||
201 | } | ||
202 | |||
203 | void | ||
204 | detect_guest_activity (struct zoran *zr) | ||
205 | { | ||
206 | int timeout, i, j, res, guest[8], guest0[8], change[8][3]; | ||
207 | unsigned long t0, t1; | ||
208 | |||
209 | dump_guests(zr); | ||
210 | printk(KERN_INFO "%s: Detecting guests activity, please wait...\n", | ||
211 | ZR_DEVNAME(zr)); | ||
212 | for (i = 1; i < 8; i++) { // Don't read jpeg codec here | ||
213 | guest0[i] = guest[i] = post_office_read(zr, i, 0); | ||
214 | } | ||
215 | |||
216 | timeout = 0; | ||
217 | j = 0; | ||
218 | t0 = get_time(); | ||
219 | while (timeout < 10000) { | ||
220 | udelay(10); | ||
221 | timeout++; | ||
222 | for (i = 1; (i < 8) && (j < 8); i++) { | ||
223 | res = post_office_read(zr, i, 0); | ||
224 | if (res != guest[i]) { | ||
225 | t1 = get_time(); | ||
226 | change[j][0] = (t1 - t0); | ||
227 | t0 = t1; | ||
228 | change[j][1] = i; | ||
229 | change[j][2] = res; | ||
230 | j++; | ||
231 | guest[i] = res; | ||
232 | } | ||
233 | } | ||
234 | if (j >= 8) | ||
235 | break; | ||
236 | } | ||
237 | printk(KERN_INFO "%s: Guests:", ZR_DEVNAME(zr)); | ||
238 | |||
239 | for (i = 1; i < 8; i++) { | ||
240 | printk(" 0x%02x", guest0[i]); | ||
241 | } | ||
242 | printk("\n"); | ||
243 | if (j == 0) { | ||
244 | printk(KERN_INFO "%s: No activity detected.\n", ZR_DEVNAME(zr)); | ||
245 | return; | ||
246 | } | ||
247 | for (i = 0; i < j; i++) { | ||
248 | printk(KERN_INFO "%s: %6d: %d => 0x%02x\n", ZR_DEVNAME(zr), | ||
249 | change[i][0], change[i][1], change[i][2]); | ||
250 | } | ||
251 | } | ||
252 | |||
253 | /* | ||
254 | * JPEG Codec access | ||
255 | */ | ||
256 | |||
257 | void | ||
258 | jpeg_codec_sleep (struct zoran *zr, | ||
259 | int sleep) | ||
260 | { | ||
261 | GPIO(zr, zr->card.gpio[GPIO_JPEG_SLEEP], !sleep); | ||
262 | if (!sleep) { | ||
263 | dprintk(3, | ||
264 | KERN_DEBUG | ||
265 | "%s: jpeg_codec_sleep() - wake GPIO=0x%08x\n", | ||
266 | ZR_DEVNAME(zr), btread(ZR36057_GPPGCR1)); | ||
267 | udelay(500); | ||
268 | } else { | ||
269 | dprintk(3, | ||
270 | KERN_DEBUG | ||
271 | "%s: jpeg_codec_sleep() - sleep GPIO=0x%08x\n", | ||
272 | ZR_DEVNAME(zr), btread(ZR36057_GPPGCR1)); | ||
273 | udelay(2); | ||
274 | } | ||
275 | } | ||
276 | |||
277 | int | ||
278 | jpeg_codec_reset (struct zoran *zr) | ||
279 | { | ||
280 | /* Take the codec out of sleep */ | ||
281 | jpeg_codec_sleep(zr, 0); | ||
282 | |||
283 | if (zr->card.gpcs[GPCS_JPEG_RESET] != 0xff) { | ||
284 | post_office_write(zr, zr->card.gpcs[GPCS_JPEG_RESET], 0, | ||
285 | 0); | ||
286 | udelay(2); | ||
287 | } else { | ||
288 | GPIO(zr, zr->card.gpio[GPIO_JPEG_RESET], 0); | ||
289 | udelay(2); | ||
290 | GPIO(zr, zr->card.gpio[GPIO_JPEG_RESET], 1); | ||
291 | udelay(2); | ||
292 | } | ||
293 | |||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | /* | ||
298 | * Set the registers for the size we have specified. Don't bother | ||
299 | * trying to understand this without the ZR36057 manual in front of | ||
300 | * you [AC]. | ||
301 | * | ||
302 | * PS: The manual is free for download in .pdf format from | ||
303 | * www.zoran.com - nicely done those folks. | ||
304 | */ | ||
305 | |||
306 | static void | ||
307 | zr36057_adjust_vfe (struct zoran *zr, | ||
308 | enum zoran_codec_mode mode) | ||
309 | { | ||
310 | u32 reg; | ||
311 | |||
312 | switch (mode) { | ||
313 | case BUZ_MODE_MOTION_DECOMPRESS: | ||
314 | btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR); | ||
315 | reg = btread(ZR36057_VFEHCR); | ||
316 | if ((reg & (1 << 10)) && zr->card.type != LML33R10) { | ||
317 | reg += ((1 << 10) | 1); | ||
318 | } | ||
319 | btwrite(reg, ZR36057_VFEHCR); | ||
320 | break; | ||
321 | case BUZ_MODE_MOTION_COMPRESS: | ||
322 | case BUZ_MODE_IDLE: | ||
323 | default: | ||
324 | if (zr->norm == VIDEO_MODE_NTSC || | ||
325 | (zr->card.type == LML33R10 && | ||
326 | zr->norm == VIDEO_MODE_PAL)) | ||
327 | btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR); | ||
328 | else | ||
329 | btor(ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR); | ||
330 | reg = btread(ZR36057_VFEHCR); | ||
331 | if (!(reg & (1 << 10)) && zr->card.type != LML33R10) { | ||
332 | reg -= ((1 << 10) | 1); | ||
333 | } | ||
334 | btwrite(reg, ZR36057_VFEHCR); | ||
335 | break; | ||
336 | } | ||
337 | } | ||
338 | |||
339 | /* | ||
340 | * set geometry | ||
341 | */ | ||
342 | |||
343 | static void | ||
344 | zr36057_set_vfe (struct zoran *zr, | ||
345 | int video_width, | ||
346 | int video_height, | ||
347 | const struct zoran_format *format) | ||
348 | { | ||
349 | struct tvnorm *tvn; | ||
350 | unsigned HStart, HEnd, VStart, VEnd; | ||
351 | unsigned DispMode; | ||
352 | unsigned VidWinWid, VidWinHt; | ||
353 | unsigned hcrop1, hcrop2, vcrop1, vcrop2; | ||
354 | unsigned Wa, We, Ha, He; | ||
355 | unsigned X, Y, HorDcm, VerDcm; | ||
356 | u32 reg; | ||
357 | unsigned mask_line_size; | ||
358 | |||
359 | tvn = zr->timing; | ||
360 | |||
361 | Wa = tvn->Wa; | ||
362 | Ha = tvn->Ha; | ||
363 | |||
364 | dprintk(2, KERN_INFO "%s: set_vfe() - width = %d, height = %d\n", | ||
365 | ZR_DEVNAME(zr), video_width, video_height); | ||
366 | |||
367 | if (zr->norm != VIDEO_MODE_PAL && | ||
368 | zr->norm != VIDEO_MODE_NTSC && | ||
369 | zr->norm != VIDEO_MODE_SECAM) { | ||
370 | dprintk(1, | ||
371 | KERN_ERR "%s: set_vfe() - norm = %d not valid\n", | ||
372 | ZR_DEVNAME(zr), zr->norm); | ||
373 | return; | ||
374 | } | ||
375 | if (video_width < BUZ_MIN_WIDTH || | ||
376 | video_height < BUZ_MIN_HEIGHT || | ||
377 | video_width > Wa || video_height > Ha) { | ||
378 | dprintk(1, KERN_ERR "%s: set_vfe: w=%d h=%d not valid\n", | ||
379 | ZR_DEVNAME(zr), video_width, video_height); | ||
380 | return; | ||
381 | } | ||
382 | |||
383 | /**** zr36057 ****/ | ||
384 | |||
385 | /* horizontal */ | ||
386 | VidWinWid = video_width; | ||
387 | X = (VidWinWid * 64 + tvn->Wa - 1) / tvn->Wa; | ||
388 | We = (VidWinWid * 64) / X; | ||
389 | HorDcm = 64 - X; | ||
390 | hcrop1 = 2 * ((tvn->Wa - We) / 4); | ||
391 | hcrop2 = tvn->Wa - We - hcrop1; | ||
392 | HStart = tvn->HStart ? tvn->HStart : 1; | ||
393 | /* (Ronald) Original comment: | ||
394 | * "| 1 Doesn't have any effect, tested on both a DC10 and a DC10+" | ||
395 | * this is false. It inverses chroma values on the LML33R10 (so Cr | ||
396 | * suddenly is shown as Cb and reverse, really cool effect if you | ||
397 | * want to see blue faces, not useful otherwise). So don't use |1. | ||
398 | * However, the DC10 has '0' as HStart, but does need |1, so we | ||
399 | * use a dirty check... | ||
400 | */ | ||
401 | HEnd = HStart + tvn->Wa - 1; | ||
402 | HStart += hcrop1; | ||
403 | HEnd -= hcrop2; | ||
404 | reg = ((HStart & ZR36057_VFEHCR_Hmask) << ZR36057_VFEHCR_HStart) | ||
405 | | ((HEnd & ZR36057_VFEHCR_Hmask) << ZR36057_VFEHCR_HEnd); | ||
406 | if (zr->card.vfe_pol.hsync_pol) | ||
407 | reg |= ZR36057_VFEHCR_HSPol; | ||
408 | btwrite(reg, ZR36057_VFEHCR); | ||
409 | |||
410 | /* Vertical */ | ||
411 | DispMode = !(video_height > BUZ_MAX_HEIGHT / 2); | ||
412 | VidWinHt = DispMode ? video_height : video_height / 2; | ||
413 | Y = (VidWinHt * 64 * 2 + tvn->Ha - 1) / tvn->Ha; | ||
414 | He = (VidWinHt * 64) / Y; | ||
415 | VerDcm = 64 - Y; | ||
416 | vcrop1 = (tvn->Ha / 2 - He) / 2; | ||
417 | vcrop2 = tvn->Ha / 2 - He - vcrop1; | ||
418 | VStart = tvn->VStart; | ||
419 | VEnd = VStart + tvn->Ha / 2; // - 1; FIXME SnapShot times out with -1 in 768*576 on the DC10 - LP | ||
420 | VStart += vcrop1; | ||
421 | VEnd -= vcrop2; | ||
422 | reg = ((VStart & ZR36057_VFEVCR_Vmask) << ZR36057_VFEVCR_VStart) | ||
423 | | ((VEnd & ZR36057_VFEVCR_Vmask) << ZR36057_VFEVCR_VEnd); | ||
424 | if (zr->card.vfe_pol.vsync_pol) | ||
425 | reg |= ZR36057_VFEVCR_VSPol; | ||
426 | btwrite(reg, ZR36057_VFEVCR); | ||
427 | |||
428 | /* scaler and pixel format */ | ||
429 | reg = 0; | ||
430 | reg |= (HorDcm << ZR36057_VFESPFR_HorDcm); | ||
431 | reg |= (VerDcm << ZR36057_VFESPFR_VerDcm); | ||
432 | reg |= (DispMode << ZR36057_VFESPFR_DispMode); | ||
433 | if (format->palette != VIDEO_PALETTE_YUV422) | ||
434 | reg |= ZR36057_VFESPFR_LittleEndian; | ||
435 | /* RJ: I don't know, why the following has to be the opposite | ||
436 | * of the corresponding ZR36060 setting, but only this way | ||
437 | * we get the correct colors when uncompressing to the screen */ | ||
438 | //reg |= ZR36057_VFESPFR_VCLKPol; /**/ | ||
439 | /* RJ: Don't know if that is needed for NTSC also */ | ||
440 | if (zr->norm != VIDEO_MODE_NTSC) | ||
441 | reg |= ZR36057_VFESPFR_ExtFl; // NEEDED!!!!!!! Wolfgang | ||
442 | reg |= ZR36057_VFESPFR_TopField; | ||
443 | switch (format->palette) { | ||
444 | |||
445 | case VIDEO_PALETTE_YUV422: | ||
446 | reg |= ZR36057_VFESPFR_YUV422; | ||
447 | break; | ||
448 | |||
449 | case VIDEO_PALETTE_RGB555: | ||
450 | reg |= ZR36057_VFESPFR_RGB555 | ZR36057_VFESPFR_ErrDif; | ||
451 | break; | ||
452 | |||
453 | case VIDEO_PALETTE_RGB565: | ||
454 | reg |= ZR36057_VFESPFR_RGB565 | ZR36057_VFESPFR_ErrDif; | ||
455 | break; | ||
456 | |||
457 | case VIDEO_PALETTE_RGB24: | ||
458 | reg |= ZR36057_VFESPFR_RGB888 | ZR36057_VFESPFR_Pack24; | ||
459 | break; | ||
460 | |||
461 | case VIDEO_PALETTE_RGB32: | ||
462 | reg |= ZR36057_VFESPFR_RGB888; | ||
463 | break; | ||
464 | |||
465 | default: | ||
466 | dprintk(1, | ||
467 | KERN_INFO "%s: set_vfe() - unknown color_fmt=%x\n", | ||
468 | ZR_DEVNAME(zr), format->palette); | ||
469 | return; | ||
470 | |||
471 | } | ||
472 | if (HorDcm >= 48) { | ||
473 | reg |= 3 << ZR36057_VFESPFR_HFilter; /* 5 tap filter */ | ||
474 | } else if (HorDcm >= 32) { | ||
475 | reg |= 2 << ZR36057_VFESPFR_HFilter; /* 4 tap filter */ | ||
476 | } else if (HorDcm >= 16) { | ||
477 | reg |= 1 << ZR36057_VFESPFR_HFilter; /* 3 tap filter */ | ||
478 | } | ||
479 | btwrite(reg, ZR36057_VFESPFR); | ||
480 | |||
481 | /* display configuration */ | ||
482 | reg = (16 << ZR36057_VDCR_MinPix) | ||
483 | | (VidWinHt << ZR36057_VDCR_VidWinHt) | ||
484 | | (VidWinWid << ZR36057_VDCR_VidWinWid); | ||
485 | if (pci_pci_problems & PCIPCI_TRITON) | ||
486 | // || zr->revision < 1) // Revision 1 has also Triton support | ||
487 | reg &= ~ZR36057_VDCR_Triton; | ||
488 | else | ||
489 | reg |= ZR36057_VDCR_Triton; | ||
490 | btwrite(reg, ZR36057_VDCR); | ||
491 | |||
492 | /* (Ronald) don't write this if overlay_mask = NULL */ | ||
493 | if (zr->overlay_mask) { | ||
494 | /* Write overlay clipping mask data, but don't enable overlay clipping */ | ||
495 | /* RJ: since this makes only sense on the screen, we use | ||
496 | * zr->overlay_settings.width instead of video_width */ | ||
497 | |||
498 | mask_line_size = (BUZ_MAX_WIDTH + 31) / 32; | ||
499 | reg = virt_to_bus(zr->overlay_mask); | ||
500 | btwrite(reg, ZR36057_MMTR); | ||
501 | reg = virt_to_bus(zr->overlay_mask + mask_line_size); | ||
502 | btwrite(reg, ZR36057_MMBR); | ||
503 | reg = | ||
504 | mask_line_size - (zr->overlay_settings.width + | ||
505 | 31) / 32; | ||
506 | if (DispMode == 0) | ||
507 | reg += mask_line_size; | ||
508 | reg <<= ZR36057_OCR_MaskStride; | ||
509 | btwrite(reg, ZR36057_OCR); | ||
510 | } | ||
511 | |||
512 | zr36057_adjust_vfe(zr, zr->codec_mode); | ||
513 | } | ||
514 | |||
515 | /* | ||
516 | * Switch overlay on or off | ||
517 | */ | ||
518 | |||
519 | void | ||
520 | zr36057_overlay (struct zoran *zr, | ||
521 | int on) | ||
522 | { | ||
523 | u32 reg; | ||
524 | |||
525 | if (on) { | ||
526 | /* do the necessary settings ... */ | ||
527 | btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR); /* switch it off first */ | ||
528 | |||
529 | zr36057_set_vfe(zr, | ||
530 | zr->overlay_settings.width, | ||
531 | zr->overlay_settings.height, | ||
532 | zr->overlay_settings.format); | ||
533 | |||
534 | /* Start and length of each line MUST be 4-byte aligned. | ||
535 | * This should be allready checked before the call to this routine. | ||
536 | * All error messages are internal driver checking only! */ | ||
537 | |||
538 | /* video display top and bottom registers */ | ||
539 | reg = (u32) zr->buffer.base + | ||
540 | zr->overlay_settings.x * | ||
541 | ((zr->overlay_settings.format->depth + 7) / 8) + | ||
542 | zr->overlay_settings.y * | ||
543 | zr->buffer.bytesperline; | ||
544 | btwrite(reg, ZR36057_VDTR); | ||
545 | if (reg & 3) | ||
546 | dprintk(1, | ||
547 | KERN_ERR | ||
548 | "%s: zr36057_overlay() - video_address not aligned\n", | ||
549 | ZR_DEVNAME(zr)); | ||
550 | if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2) | ||
551 | reg += zr->buffer.bytesperline; | ||
552 | btwrite(reg, ZR36057_VDBR); | ||
553 | |||
554 | /* video stride, status, and frame grab register */ | ||
555 | reg = zr->buffer.bytesperline - | ||
556 | zr->overlay_settings.width * | ||
557 | ((zr->overlay_settings.format->depth + 7) / 8); | ||
558 | if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2) | ||
559 | reg += zr->buffer.bytesperline; | ||
560 | if (reg & 3) | ||
561 | dprintk(1, | ||
562 | KERN_ERR | ||
563 | "%s: zr36057_overlay() - video_stride not aligned\n", | ||
564 | ZR_DEVNAME(zr)); | ||
565 | reg = (reg << ZR36057_VSSFGR_DispStride); | ||
566 | reg |= ZR36057_VSSFGR_VidOvf; /* clear overflow status */ | ||
567 | btwrite(reg, ZR36057_VSSFGR); | ||
568 | |||
569 | /* Set overlay clipping */ | ||
570 | if (zr->overlay_settings.clipcount > 0) | ||
571 | btor(ZR36057_OCR_OvlEnable, ZR36057_OCR); | ||
572 | |||
573 | /* ... and switch it on */ | ||
574 | btor(ZR36057_VDCR_VidEn, ZR36057_VDCR); | ||
575 | } else { | ||
576 | /* Switch it off */ | ||
577 | btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR); | ||
578 | } | ||
579 | } | ||
580 | |||
581 | /* | ||
582 | * The overlay mask has one bit for each pixel on a scan line, | ||
583 | * and the maximum window size is BUZ_MAX_WIDTH * BUZ_MAX_HEIGHT pixels. | ||
584 | */ | ||
585 | |||
586 | void | ||
587 | write_overlay_mask (struct file *file, | ||
588 | struct video_clip *vp, | ||
589 | int count) | ||
590 | { | ||
591 | struct zoran_fh *fh = file->private_data; | ||
592 | struct zoran *zr = fh->zr; | ||
593 | unsigned mask_line_size = (BUZ_MAX_WIDTH + 31) / 32; | ||
594 | u32 *mask; | ||
595 | int x, y, width, height; | ||
596 | unsigned i, j, k; | ||
597 | u32 reg; | ||
598 | |||
599 | /* fill mask with one bits */ | ||
600 | memset(fh->overlay_mask, ~0, mask_line_size * 4 * BUZ_MAX_HEIGHT); | ||
601 | reg = 0; | ||
602 | |||
603 | for (i = 0; i < count; ++i) { | ||
604 | /* pick up local copy of clip */ | ||
605 | x = vp[i].x; | ||
606 | y = vp[i].y; | ||
607 | width = vp[i].width; | ||
608 | height = vp[i].height; | ||
609 | |||
610 | /* trim clips that extend beyond the window */ | ||
611 | if (x < 0) { | ||
612 | width += x; | ||
613 | x = 0; | ||
614 | } | ||
615 | if (y < 0) { | ||
616 | height += y; | ||
617 | y = 0; | ||
618 | } | ||
619 | if (x + width > fh->overlay_settings.width) { | ||
620 | width = fh->overlay_settings.width - x; | ||
621 | } | ||
622 | if (y + height > fh->overlay_settings.height) { | ||
623 | height = fh->overlay_settings.height - y; | ||
624 | } | ||
625 | |||
626 | /* ignore degenerate clips */ | ||
627 | if (height <= 0) { | ||
628 | continue; | ||
629 | } | ||
630 | if (width <= 0) { | ||
631 | continue; | ||
632 | } | ||
633 | |||
634 | /* apply clip for each scan line */ | ||
635 | for (j = 0; j < height; ++j) { | ||
636 | /* reset bit for each pixel */ | ||
637 | /* this can be optimized later if need be */ | ||
638 | mask = fh->overlay_mask + (y + j) * mask_line_size; | ||
639 | for (k = 0; k < width; ++k) { | ||
640 | mask[(x + k) / 32] &= | ||
641 | ~((u32) 1 << (x + k) % 32); | ||
642 | } | ||
643 | } | ||
644 | } | ||
645 | } | ||
646 | |||
647 | /* Enable/Disable uncompressed memory grabbing of the 36057 */ | ||
648 | |||
649 | void | ||
650 | zr36057_set_memgrab (struct zoran *zr, | ||
651 | int mode) | ||
652 | { | ||
653 | if (mode) { | ||
654 | if (btread(ZR36057_VSSFGR) & | ||
655 | (ZR36057_VSSFGR_SnapShot | ZR36057_VSSFGR_FrameGrab)) | ||
656 | dprintk(1, | ||
657 | KERN_WARNING | ||
658 | "%s: zr36057_set_memgrab(1) with SnapShot or FrameGrab on!?\n", | ||
659 | ZR_DEVNAME(zr)); | ||
660 | |||
661 | /* switch on VSync interrupts */ | ||
662 | btwrite(IRQ_MASK, ZR36057_ISR); // Clear Interrupts | ||
663 | btor(zr->card.vsync_int, ZR36057_ICR); // SW | ||
664 | |||
665 | /* enable SnapShot */ | ||
666 | btor(ZR36057_VSSFGR_SnapShot, ZR36057_VSSFGR); | ||
667 | |||
668 | /* Set zr36057 video front end and enable video */ | ||
669 | zr36057_set_vfe(zr, zr->v4l_settings.width, | ||
670 | zr->v4l_settings.height, | ||
671 | zr->v4l_settings.format); | ||
672 | |||
673 | zr->v4l_memgrab_active = 1; | ||
674 | } else { | ||
675 | zr->v4l_memgrab_active = 0; | ||
676 | |||
677 | /* switch off VSync interrupts */ | ||
678 | btand(~zr->card.vsync_int, ZR36057_ICR); // SW | ||
679 | |||
680 | /* reenable grabbing to screen if it was running */ | ||
681 | if (zr->v4l_overlay_active) { | ||
682 | zr36057_overlay(zr, 1); | ||
683 | } else { | ||
684 | btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR); | ||
685 | btand(~ZR36057_VSSFGR_SnapShot, ZR36057_VSSFGR); | ||
686 | } | ||
687 | } | ||
688 | } | ||
689 | |||
690 | int | ||
691 | wait_grab_pending (struct zoran *zr) | ||
692 | { | ||
693 | unsigned long flags; | ||
694 | |||
695 | /* wait until all pending grabs are finished */ | ||
696 | |||
697 | if (!zr->v4l_memgrab_active) | ||
698 | return 0; | ||
699 | |||
700 | wait_event_interruptible(zr->v4l_capq, | ||
701 | (zr->v4l_pend_tail == zr->v4l_pend_head)); | ||
702 | if (signal_pending(current)) | ||
703 | return -ERESTARTSYS; | ||
704 | |||
705 | spin_lock_irqsave(&zr->spinlock, flags); | ||
706 | zr36057_set_memgrab(zr, 0); | ||
707 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
708 | |||
709 | return 0; | ||
710 | } | ||
711 | |||
712 | /***************************************************************************** | ||
713 | * * | ||
714 | * Set up the Buz-specific MJPEG part * | ||
715 | * * | ||
716 | *****************************************************************************/ | ||
717 | |||
718 | static inline void | ||
719 | set_frame (struct zoran *zr, | ||
720 | int val) | ||
721 | { | ||
722 | GPIO(zr, zr->card.gpio[GPIO_JPEG_FRAME], val); | ||
723 | } | ||
724 | |||
725 | static void | ||
726 | set_videobus_dir (struct zoran *zr, | ||
727 | int val) | ||
728 | { | ||
729 | switch (zr->card.type) { | ||
730 | case LML33: | ||
731 | case LML33R10: | ||
732 | if (lml33dpath == 0) | ||
733 | GPIO(zr, 5, val); | ||
734 | else | ||
735 | GPIO(zr, 5, 1); | ||
736 | break; | ||
737 | default: | ||
738 | GPIO(zr, zr->card.gpio[GPIO_VID_DIR], | ||
739 | zr->card.gpio_pol[GPIO_VID_DIR] ? !val : val); | ||
740 | break; | ||
741 | } | ||
742 | } | ||
743 | |||
744 | static void | ||
745 | init_jpeg_queue (struct zoran *zr) | ||
746 | { | ||
747 | int i; | ||
748 | |||
749 | /* re-initialize DMA ring stuff */ | ||
750 | zr->jpg_que_head = 0; | ||
751 | zr->jpg_dma_head = 0; | ||
752 | zr->jpg_dma_tail = 0; | ||
753 | zr->jpg_que_tail = 0; | ||
754 | zr->jpg_seq_num = 0; | ||
755 | zr->JPEG_error = 0; | ||
756 | zr->num_errors = 0; | ||
757 | zr->jpg_err_seq = 0; | ||
758 | zr->jpg_err_shift = 0; | ||
759 | zr->jpg_queued_num = 0; | ||
760 | for (i = 0; i < zr->jpg_buffers.num_buffers; i++) { | ||
761 | zr->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */ | ||
762 | } | ||
763 | for (i = 0; i < BUZ_NUM_STAT_COM; i++) { | ||
764 | zr->stat_com[i] = cpu_to_le32(1); /* mark as unavailable to zr36057 */ | ||
765 | } | ||
766 | } | ||
767 | |||
768 | static void | ||
769 | zr36057_set_jpg (struct zoran *zr, | ||
770 | enum zoran_codec_mode mode) | ||
771 | { | ||
772 | struct tvnorm *tvn; | ||
773 | u32 reg; | ||
774 | |||
775 | tvn = zr->timing; | ||
776 | |||
777 | /* assert P_Reset, disable code transfer, deassert Active */ | ||
778 | btwrite(0, ZR36057_JPC); | ||
779 | |||
780 | /* MJPEG compression mode */ | ||
781 | switch (mode) { | ||
782 | |||
783 | case BUZ_MODE_MOTION_COMPRESS: | ||
784 | default: | ||
785 | reg = ZR36057_JMC_MJPGCmpMode; | ||
786 | break; | ||
787 | |||
788 | case BUZ_MODE_MOTION_DECOMPRESS: | ||
789 | reg = ZR36057_JMC_MJPGExpMode; | ||
790 | reg |= ZR36057_JMC_SyncMstr; | ||
791 | /* RJ: The following is experimental - improves the output to screen */ | ||
792 | //if(zr->jpg_settings.VFIFO_FB) reg |= ZR36057_JMC_VFIFO_FB; // No, it doesn't. SM | ||
793 | break; | ||
794 | |||
795 | case BUZ_MODE_STILL_COMPRESS: | ||
796 | reg = ZR36057_JMC_JPGCmpMode; | ||
797 | break; | ||
798 | |||
799 | case BUZ_MODE_STILL_DECOMPRESS: | ||
800 | reg = ZR36057_JMC_JPGExpMode; | ||
801 | break; | ||
802 | |||
803 | } | ||
804 | reg |= ZR36057_JMC_JPG; | ||
805 | if (zr->jpg_settings.field_per_buff == 1) | ||
806 | reg |= ZR36057_JMC_Fld_per_buff; | ||
807 | btwrite(reg, ZR36057_JMC); | ||
808 | |||
809 | /* vertical */ | ||
810 | btor(ZR36057_VFEVCR_VSPol, ZR36057_VFEVCR); | ||
811 | reg = (6 << ZR36057_VSP_VsyncSize) | | ||
812 | (tvn->Ht << ZR36057_VSP_FrmTot); | ||
813 | btwrite(reg, ZR36057_VSP); | ||
814 | reg = ((zr->jpg_settings.img_y + tvn->VStart) << ZR36057_FVAP_NAY) | | ||
815 | (zr->jpg_settings.img_height << ZR36057_FVAP_PAY); | ||
816 | btwrite(reg, ZR36057_FVAP); | ||
817 | |||
818 | /* horizontal */ | ||
819 | if (zr->card.vfe_pol.hsync_pol) | ||
820 | btor(ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR); | ||
821 | else | ||
822 | btand(~ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR); | ||
823 | reg = ((tvn->HSyncStart) << ZR36057_HSP_HsyncStart) | | ||
824 | (tvn->Wt << ZR36057_HSP_LineTot); | ||
825 | btwrite(reg, ZR36057_HSP); | ||
826 | reg = ((zr->jpg_settings.img_x + | ||
827 | tvn->HStart + 4) << ZR36057_FHAP_NAX) | | ||
828 | (zr->jpg_settings.img_width << ZR36057_FHAP_PAX); | ||
829 | btwrite(reg, ZR36057_FHAP); | ||
830 | |||
831 | /* field process parameters */ | ||
832 | if (zr->jpg_settings.odd_even) | ||
833 | reg = ZR36057_FPP_Odd_Even; | ||
834 | else | ||
835 | reg = 0; | ||
836 | |||
837 | btwrite(reg, ZR36057_FPP); | ||
838 | |||
839 | /* Set proper VCLK Polarity, else colors will be wrong during playback */ | ||
840 | //btor(ZR36057_VFESPFR_VCLKPol, ZR36057_VFESPFR); | ||
841 | |||
842 | /* code base address */ | ||
843 | reg = virt_to_bus(zr->stat_com); | ||
844 | btwrite(reg, ZR36057_JCBA); | ||
845 | |||
846 | /* FIFO threshold (FIFO is 160. double words) */ | ||
847 | /* NOTE: decimal values here */ | ||
848 | switch (mode) { | ||
849 | |||
850 | case BUZ_MODE_STILL_COMPRESS: | ||
851 | case BUZ_MODE_MOTION_COMPRESS: | ||
852 | if (zr->card.type != BUZ) | ||
853 | reg = 140; | ||
854 | else | ||
855 | reg = 60; | ||
856 | break; | ||
857 | |||
858 | case BUZ_MODE_STILL_DECOMPRESS: | ||
859 | case BUZ_MODE_MOTION_DECOMPRESS: | ||
860 | reg = 20; | ||
861 | break; | ||
862 | |||
863 | default: | ||
864 | reg = 80; | ||
865 | break; | ||
866 | |||
867 | } | ||
868 | btwrite(reg, ZR36057_JCFT); | ||
869 | zr36057_adjust_vfe(zr, mode); | ||
870 | |||
871 | } | ||
872 | |||
873 | void | ||
874 | print_interrupts (struct zoran *zr) | ||
875 | { | ||
876 | int res, noerr = 0; | ||
877 | |||
878 | printk(KERN_INFO "%s: interrupts received:", ZR_DEVNAME(zr)); | ||
879 | if ((res = zr->field_counter) < -1 || res > 1) { | ||
880 | printk(" FD:%d", res); | ||
881 | } | ||
882 | if ((res = zr->intr_counter_GIRQ1) != 0) { | ||
883 | printk(" GIRQ1:%d", res); | ||
884 | noerr++; | ||
885 | } | ||
886 | if ((res = zr->intr_counter_GIRQ0) != 0) { | ||
887 | printk(" GIRQ0:%d", res); | ||
888 | noerr++; | ||
889 | } | ||
890 | if ((res = zr->intr_counter_CodRepIRQ) != 0) { | ||
891 | printk(" CodRepIRQ:%d", res); | ||
892 | noerr++; | ||
893 | } | ||
894 | if ((res = zr->intr_counter_JPEGRepIRQ) != 0) { | ||
895 | printk(" JPEGRepIRQ:%d", res); | ||
896 | noerr++; | ||
897 | } | ||
898 | if (zr->JPEG_max_missed) { | ||
899 | printk(" JPEG delays: max=%d min=%d", zr->JPEG_max_missed, | ||
900 | zr->JPEG_min_missed); | ||
901 | } | ||
902 | if (zr->END_event_missed) { | ||
903 | printk(" ENDs missed: %d", zr->END_event_missed); | ||
904 | } | ||
905 | //if (zr->jpg_queued_num) { | ||
906 | printk(" queue_state=%ld/%ld/%ld/%ld", zr->jpg_que_tail, | ||
907 | zr->jpg_dma_tail, zr->jpg_dma_head, zr->jpg_que_head); | ||
908 | //} | ||
909 | if (!noerr) { | ||
910 | printk(": no interrupts detected."); | ||
911 | } | ||
912 | printk("\n"); | ||
913 | } | ||
914 | |||
915 | void | ||
916 | clear_interrupt_counters (struct zoran *zr) | ||
917 | { | ||
918 | zr->intr_counter_GIRQ1 = 0; | ||
919 | zr->intr_counter_GIRQ0 = 0; | ||
920 | zr->intr_counter_CodRepIRQ = 0; | ||
921 | zr->intr_counter_JPEGRepIRQ = 0; | ||
922 | zr->field_counter = 0; | ||
923 | zr->IRQ1_in = 0; | ||
924 | zr->IRQ1_out = 0; | ||
925 | zr->JPEG_in = 0; | ||
926 | zr->JPEG_out = 0; | ||
927 | zr->JPEG_0 = 0; | ||
928 | zr->JPEG_1 = 0; | ||
929 | zr->END_event_missed = 0; | ||
930 | zr->JPEG_missed = 0; | ||
931 | zr->JPEG_max_missed = 0; | ||
932 | zr->JPEG_min_missed = 0x7fffffff; | ||
933 | } | ||
934 | |||
935 | static u32 | ||
936 | count_reset_interrupt (struct zoran *zr) | ||
937 | { | ||
938 | u32 isr; | ||
939 | |||
940 | if ((isr = btread(ZR36057_ISR) & 0x78000000)) { | ||
941 | if (isr & ZR36057_ISR_GIRQ1) { | ||
942 | btwrite(ZR36057_ISR_GIRQ1, ZR36057_ISR); | ||
943 | zr->intr_counter_GIRQ1++; | ||
944 | } | ||
945 | if (isr & ZR36057_ISR_GIRQ0) { | ||
946 | btwrite(ZR36057_ISR_GIRQ0, ZR36057_ISR); | ||
947 | zr->intr_counter_GIRQ0++; | ||
948 | } | ||
949 | if (isr & ZR36057_ISR_CodRepIRQ) { | ||
950 | btwrite(ZR36057_ISR_CodRepIRQ, ZR36057_ISR); | ||
951 | zr->intr_counter_CodRepIRQ++; | ||
952 | } | ||
953 | if (isr & ZR36057_ISR_JPEGRepIRQ) { | ||
954 | btwrite(ZR36057_ISR_JPEGRepIRQ, ZR36057_ISR); | ||
955 | zr->intr_counter_JPEGRepIRQ++; | ||
956 | } | ||
957 | } | ||
958 | return isr; | ||
959 | } | ||
960 | |||
961 | /* hack */ | ||
962 | extern void zr36016_write (struct videocodec *codec, | ||
963 | u16 reg, | ||
964 | u32 val); | ||
965 | |||
966 | void | ||
967 | jpeg_start (struct zoran *zr) | ||
968 | { | ||
969 | int reg; | ||
970 | |||
971 | zr->frame_num = 0; | ||
972 | |||
973 | /* deassert P_reset, disable code transfer, deassert Active */ | ||
974 | btwrite(ZR36057_JPC_P_Reset, ZR36057_JPC); | ||
975 | /* stop flushing the internal code buffer */ | ||
976 | btand(~ZR36057_MCTCR_CFlush, ZR36057_MCTCR); | ||
977 | /* enable code transfer */ | ||
978 | btor(ZR36057_JPC_CodTrnsEn, ZR36057_JPC); | ||
979 | |||
980 | /* clear IRQs */ | ||
981 | btwrite(IRQ_MASK, ZR36057_ISR); | ||
982 | /* enable the JPEG IRQs */ | ||
983 | btwrite(zr->card.jpeg_int | | ||
984 | ZR36057_ICR_JPEGRepIRQ | | ||
985 | ZR36057_ICR_IntPinEn, | ||
986 | ZR36057_ICR); | ||
987 | |||
988 | set_frame(zr, 0); // \FRAME | ||
989 | |||
990 | /* set the JPEG codec guest ID */ | ||
991 | reg = (zr->card.gpcs[1] << ZR36057_JCGI_JPEGuestID) | | ||
992 | (0 << ZR36057_JCGI_JPEGuestReg); | ||
993 | btwrite(reg, ZR36057_JCGI); | ||
994 | |||
995 | if (zr->card.video_vfe == CODEC_TYPE_ZR36016 && | ||
996 | zr->card.video_codec == CODEC_TYPE_ZR36050) { | ||
997 | /* Enable processing on the ZR36016 */ | ||
998 | if (zr->vfe) | ||
999 | zr36016_write(zr->vfe, 0, 1); | ||
1000 | |||
1001 | /* load the address of the GO register in the ZR36050 latch */ | ||
1002 | post_office_write(zr, 0, 0, 0); | ||
1003 | } | ||
1004 | |||
1005 | /* assert Active */ | ||
1006 | btor(ZR36057_JPC_Active, ZR36057_JPC); | ||
1007 | |||
1008 | /* enable the Go generation */ | ||
1009 | btor(ZR36057_JMC_Go_en, ZR36057_JMC); | ||
1010 | udelay(30); | ||
1011 | |||
1012 | set_frame(zr, 1); // /FRAME | ||
1013 | |||
1014 | dprintk(3, KERN_DEBUG "%s: jpeg_start\n", ZR_DEVNAME(zr)); | ||
1015 | } | ||
1016 | |||
1017 | void | ||
1018 | zr36057_enable_jpg (struct zoran *zr, | ||
1019 | enum zoran_codec_mode mode) | ||
1020 | { | ||
1021 | static int zero = 0; | ||
1022 | static int one = 1; | ||
1023 | struct vfe_settings cap; | ||
1024 | int field_size = | ||
1025 | zr->jpg_buffers.buffer_size / zr->jpg_settings.field_per_buff; | ||
1026 | |||
1027 | zr->codec_mode = mode; | ||
1028 | |||
1029 | cap.x = zr->jpg_settings.img_x; | ||
1030 | cap.y = zr->jpg_settings.img_y; | ||
1031 | cap.width = zr->jpg_settings.img_width; | ||
1032 | cap.height = zr->jpg_settings.img_height; | ||
1033 | cap.decimation = | ||
1034 | zr->jpg_settings.HorDcm | (zr->jpg_settings.VerDcm << 8); | ||
1035 | cap.quality = zr->jpg_settings.jpg_comp.quality; | ||
1036 | |||
1037 | switch (mode) { | ||
1038 | |||
1039 | case BUZ_MODE_MOTION_COMPRESS: { | ||
1040 | struct jpeg_app_marker app; | ||
1041 | struct jpeg_com_marker com; | ||
1042 | |||
1043 | /* In motion compress mode, the decoder output must be enabled, and | ||
1044 | * the video bus direction set to input. | ||
1045 | */ | ||
1046 | set_videobus_dir(zr, 0); | ||
1047 | decoder_command(zr, DECODER_ENABLE_OUTPUT, &one); | ||
1048 | encoder_command(zr, ENCODER_SET_INPUT, &zero); | ||
1049 | |||
1050 | /* Take the JPEG codec and the VFE out of sleep */ | ||
1051 | jpeg_codec_sleep(zr, 0); | ||
1052 | |||
1053 | /* set JPEG app/com marker */ | ||
1054 | app.appn = zr->jpg_settings.jpg_comp.APPn; | ||
1055 | app.len = zr->jpg_settings.jpg_comp.APP_len; | ||
1056 | memcpy(app.data, zr->jpg_settings.jpg_comp.APP_data, 60); | ||
1057 | zr->codec->control(zr->codec, CODEC_S_JPEG_APP_DATA, | ||
1058 | sizeof(struct jpeg_app_marker), &app); | ||
1059 | |||
1060 | com.len = zr->jpg_settings.jpg_comp.COM_len; | ||
1061 | memcpy(com.data, zr->jpg_settings.jpg_comp.COM_data, 60); | ||
1062 | zr->codec->control(zr->codec, CODEC_S_JPEG_COM_DATA, | ||
1063 | sizeof(struct jpeg_com_marker), &com); | ||
1064 | |||
1065 | /* Setup the JPEG codec */ | ||
1066 | zr->codec->control(zr->codec, CODEC_S_JPEG_TDS_BYTE, | ||
1067 | sizeof(int), &field_size); | ||
1068 | zr->codec->set_video(zr->codec, zr->timing, &cap, | ||
1069 | &zr->card.vfe_pol); | ||
1070 | zr->codec->set_mode(zr->codec, CODEC_DO_COMPRESSION); | ||
1071 | |||
1072 | /* Setup the VFE */ | ||
1073 | if (zr->vfe) { | ||
1074 | zr->vfe->control(zr->vfe, CODEC_S_JPEG_TDS_BYTE, | ||
1075 | sizeof(int), &field_size); | ||
1076 | zr->vfe->set_video(zr->vfe, zr->timing, &cap, | ||
1077 | &zr->card.vfe_pol); | ||
1078 | zr->vfe->set_mode(zr->vfe, CODEC_DO_COMPRESSION); | ||
1079 | } | ||
1080 | |||
1081 | init_jpeg_queue(zr); | ||
1082 | zr36057_set_jpg(zr, mode); // \P_Reset, ... Video param, FIFO | ||
1083 | |||
1084 | clear_interrupt_counters(zr); | ||
1085 | dprintk(2, KERN_INFO "%s: enable_jpg(MOTION_COMPRESS)\n", | ||
1086 | ZR_DEVNAME(zr)); | ||
1087 | break; | ||
1088 | } | ||
1089 | |||
1090 | case BUZ_MODE_MOTION_DECOMPRESS: | ||
1091 | /* In motion decompression mode, the decoder output must be disabled, and | ||
1092 | * the video bus direction set to output. | ||
1093 | */ | ||
1094 | decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero); | ||
1095 | set_videobus_dir(zr, 1); | ||
1096 | encoder_command(zr, ENCODER_SET_INPUT, &one); | ||
1097 | |||
1098 | /* Take the JPEG codec and the VFE out of sleep */ | ||
1099 | jpeg_codec_sleep(zr, 0); | ||
1100 | /* Setup the VFE */ | ||
1101 | if (zr->vfe) { | ||
1102 | zr->vfe->set_video(zr->vfe, zr->timing, &cap, | ||
1103 | &zr->card.vfe_pol); | ||
1104 | zr->vfe->set_mode(zr->vfe, CODEC_DO_EXPANSION); | ||
1105 | } | ||
1106 | /* Setup the JPEG codec */ | ||
1107 | zr->codec->set_video(zr->codec, zr->timing, &cap, | ||
1108 | &zr->card.vfe_pol); | ||
1109 | zr->codec->set_mode(zr->codec, CODEC_DO_EXPANSION); | ||
1110 | |||
1111 | init_jpeg_queue(zr); | ||
1112 | zr36057_set_jpg(zr, mode); // \P_Reset, ... Video param, FIFO | ||
1113 | |||
1114 | clear_interrupt_counters(zr); | ||
1115 | dprintk(2, KERN_INFO "%s: enable_jpg(MOTION_DECOMPRESS)\n", | ||
1116 | ZR_DEVNAME(zr)); | ||
1117 | break; | ||
1118 | |||
1119 | case BUZ_MODE_IDLE: | ||
1120 | default: | ||
1121 | /* shut down processing */ | ||
1122 | btand(~(zr->card.jpeg_int | ZR36057_ICR_JPEGRepIRQ), | ||
1123 | ZR36057_ICR); | ||
1124 | btwrite(zr->card.jpeg_int | ZR36057_ICR_JPEGRepIRQ, | ||
1125 | ZR36057_ISR); | ||
1126 | btand(~ZR36057_JMC_Go_en, ZR36057_JMC); // \Go_en | ||
1127 | |||
1128 | msleep(50); | ||
1129 | |||
1130 | set_videobus_dir(zr, 0); | ||
1131 | set_frame(zr, 1); // /FRAME | ||
1132 | btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR); // /CFlush | ||
1133 | btwrite(0, ZR36057_JPC); // \P_Reset,\CodTrnsEn,\Active | ||
1134 | btand(~ZR36057_JMC_VFIFO_FB, ZR36057_JMC); | ||
1135 | btand(~ZR36057_JMC_SyncMstr, ZR36057_JMC); | ||
1136 | jpeg_codec_reset(zr); | ||
1137 | jpeg_codec_sleep(zr, 1); | ||
1138 | zr36057_adjust_vfe(zr, mode); | ||
1139 | |||
1140 | decoder_command(zr, DECODER_ENABLE_OUTPUT, &one); | ||
1141 | encoder_command(zr, ENCODER_SET_INPUT, &zero); | ||
1142 | |||
1143 | dprintk(2, KERN_INFO "%s: enable_jpg(IDLE)\n", ZR_DEVNAME(zr)); | ||
1144 | break; | ||
1145 | |||
1146 | } | ||
1147 | } | ||
1148 | |||
1149 | /* when this is called the spinlock must be held */ | ||
1150 | void | ||
1151 | zoran_feed_stat_com (struct zoran *zr) | ||
1152 | { | ||
1153 | /* move frames from pending queue to DMA */ | ||
1154 | |||
1155 | int frame, i, max_stat_com; | ||
1156 | |||
1157 | max_stat_com = | ||
1158 | (zr->jpg_settings.TmpDcm == | ||
1159 | 1) ? BUZ_NUM_STAT_COM : (BUZ_NUM_STAT_COM >> 1); | ||
1160 | |||
1161 | while ((zr->jpg_dma_head - zr->jpg_dma_tail) < max_stat_com && | ||
1162 | zr->jpg_dma_head < zr->jpg_que_head) { | ||
1163 | |||
1164 | frame = zr->jpg_pend[zr->jpg_dma_head & BUZ_MASK_FRAME]; | ||
1165 | if (zr->jpg_settings.TmpDcm == 1) { | ||
1166 | /* fill 1 stat_com entry */ | ||
1167 | i = (zr->jpg_dma_head - | ||
1168 | zr->jpg_err_shift) & BUZ_MASK_STAT_COM; | ||
1169 | if (!(zr->stat_com[i] & cpu_to_le32(1))) | ||
1170 | break; | ||
1171 | zr->stat_com[i] = | ||
1172 | cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus); | ||
1173 | } else { | ||
1174 | /* fill 2 stat_com entries */ | ||
1175 | i = ((zr->jpg_dma_head - | ||
1176 | zr->jpg_err_shift) & 1) * 2; | ||
1177 | if (!(zr->stat_com[i] & cpu_to_le32(1))) | ||
1178 | break; | ||
1179 | zr->stat_com[i] = | ||
1180 | cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus); | ||
1181 | zr->stat_com[i + 1] = | ||
1182 | cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus); | ||
1183 | } | ||
1184 | zr->jpg_buffers.buffer[frame].state = BUZ_STATE_DMA; | ||
1185 | zr->jpg_dma_head++; | ||
1186 | |||
1187 | } | ||
1188 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) | ||
1189 | zr->jpg_queued_num++; | ||
1190 | } | ||
1191 | |||
1192 | /* when this is called the spinlock must be held */ | ||
1193 | static void | ||
1194 | zoran_reap_stat_com (struct zoran *zr) | ||
1195 | { | ||
1196 | /* move frames from DMA queue to done queue */ | ||
1197 | |||
1198 | int i; | ||
1199 | u32 stat_com; | ||
1200 | unsigned int seq; | ||
1201 | unsigned int dif; | ||
1202 | struct zoran_jpg_buffer *buffer; | ||
1203 | int frame; | ||
1204 | |||
1205 | /* In motion decompress we don't have a hardware frame counter, | ||
1206 | * we just count the interrupts here */ | ||
1207 | |||
1208 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) { | ||
1209 | zr->jpg_seq_num++; | ||
1210 | } | ||
1211 | while (zr->jpg_dma_tail < zr->jpg_dma_head) { | ||
1212 | if (zr->jpg_settings.TmpDcm == 1) | ||
1213 | i = (zr->jpg_dma_tail - | ||
1214 | zr->jpg_err_shift) & BUZ_MASK_STAT_COM; | ||
1215 | else | ||
1216 | i = ((zr->jpg_dma_tail - | ||
1217 | zr->jpg_err_shift) & 1) * 2 + 1; | ||
1218 | |||
1219 | stat_com = le32_to_cpu(zr->stat_com[i]); | ||
1220 | |||
1221 | if ((stat_com & 1) == 0) { | ||
1222 | return; | ||
1223 | } | ||
1224 | frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME]; | ||
1225 | buffer = &zr->jpg_buffers.buffer[frame]; | ||
1226 | do_gettimeofday(&buffer->bs.timestamp); | ||
1227 | |||
1228 | if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { | ||
1229 | buffer->bs.length = (stat_com & 0x7fffff) >> 1; | ||
1230 | |||
1231 | /* update sequence number with the help of the counter in stat_com */ | ||
1232 | |||
1233 | seq = ((stat_com >> 24) + zr->jpg_err_seq) & 0xff; | ||
1234 | dif = (seq - zr->jpg_seq_num) & 0xff; | ||
1235 | zr->jpg_seq_num += dif; | ||
1236 | } else { | ||
1237 | buffer->bs.length = 0; | ||
1238 | } | ||
1239 | buffer->bs.seq = | ||
1240 | zr->jpg_settings.TmpDcm == | ||
1241 | 2 ? (zr->jpg_seq_num >> 1) : zr->jpg_seq_num; | ||
1242 | buffer->state = BUZ_STATE_DONE; | ||
1243 | |||
1244 | zr->jpg_dma_tail++; | ||
1245 | } | ||
1246 | } | ||
1247 | |||
1248 | static void | ||
1249 | error_handler (struct zoran *zr, | ||
1250 | u32 astat, | ||
1251 | u32 stat) | ||
1252 | { | ||
1253 | /* This is JPEG error handling part */ | ||
1254 | if ((zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) && | ||
1255 | (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS)) { | ||
1256 | //dprintk(1, KERN_ERR "%s: Internal error: error handling request in mode %d\n", ZR_DEVNAME(zr), zr->codec_mode); | ||
1257 | return; | ||
1258 | } | ||
1259 | |||
1260 | if ((stat & 1) == 0 && | ||
1261 | zr->codec_mode == BUZ_MODE_MOTION_COMPRESS && | ||
1262 | zr->jpg_dma_tail - zr->jpg_que_tail >= | ||
1263 | zr->jpg_buffers.num_buffers) { | ||
1264 | /* No free buffers... */ | ||
1265 | zoran_reap_stat_com(zr); | ||
1266 | zoran_feed_stat_com(zr); | ||
1267 | wake_up_interruptible(&zr->jpg_capq); | ||
1268 | zr->JPEG_missed = 0; | ||
1269 | return; | ||
1270 | } | ||
1271 | |||
1272 | if (zr->JPEG_error != 1) { | ||
1273 | /* | ||
1274 | * First entry: error just happened during normal operation | ||
1275 | * | ||
1276 | * In BUZ_MODE_MOTION_COMPRESS: | ||
1277 | * | ||
1278 | * Possible glitch in TV signal. In this case we should | ||
1279 | * stop the codec and wait for good quality signal before | ||
1280 | * restarting it to avoid further problems | ||
1281 | * | ||
1282 | * In BUZ_MODE_MOTION_DECOMPRESS: | ||
1283 | * | ||
1284 | * Bad JPEG frame: we have to mark it as processed (codec crashed | ||
1285 | * and was not able to do it itself), and to remove it from queue. | ||
1286 | */ | ||
1287 | btand(~ZR36057_JMC_Go_en, ZR36057_JMC); | ||
1288 | udelay(1); | ||
1289 | stat = stat | (post_office_read(zr, 7, 0) & 3) << 8; | ||
1290 | btwrite(0, ZR36057_JPC); | ||
1291 | btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR); | ||
1292 | jpeg_codec_reset(zr); | ||
1293 | jpeg_codec_sleep(zr, 1); | ||
1294 | zr->JPEG_error = 1; | ||
1295 | zr->num_errors++; | ||
1296 | |||
1297 | /* Report error */ | ||
1298 | if (*zr_debug > 1 && zr->num_errors <= 8) { | ||
1299 | long frame; | ||
1300 | frame = | ||
1301 | zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME]; | ||
1302 | printk(KERN_ERR | ||
1303 | "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ", | ||
1304 | ZR_DEVNAME(zr), stat, zr->last_isr, | ||
1305 | zr->jpg_que_tail, zr->jpg_dma_tail, | ||
1306 | zr->jpg_dma_head, zr->jpg_que_head, | ||
1307 | zr->jpg_seq_num, frame); | ||
1308 | printk("stat_com frames:"); | ||
1309 | { | ||
1310 | int i, j; | ||
1311 | for (j = 0; j < BUZ_NUM_STAT_COM; j++) { | ||
1312 | for (i = 0; | ||
1313 | i < zr->jpg_buffers.num_buffers; | ||
1314 | i++) { | ||
1315 | if (le32_to_cpu(zr->stat_com[j]) == | ||
1316 | zr->jpg_buffers. | ||
1317 | buffer[i]. | ||
1318 | frag_tab_bus) { | ||
1319 | printk("% d->%d", | ||
1320 | j, i); | ||
1321 | } | ||
1322 | } | ||
1323 | } | ||
1324 | printk("\n"); | ||
1325 | } | ||
1326 | } | ||
1327 | /* Find an entry in stat_com and rotate contents */ | ||
1328 | { | ||
1329 | int i; | ||
1330 | |||
1331 | if (zr->jpg_settings.TmpDcm == 1) | ||
1332 | i = (zr->jpg_dma_tail - | ||
1333 | zr->jpg_err_shift) & BUZ_MASK_STAT_COM; | ||
1334 | else | ||
1335 | i = ((zr->jpg_dma_tail - | ||
1336 | zr->jpg_err_shift) & 1) * 2; | ||
1337 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) { | ||
1338 | /* Mimic zr36067 operation */ | ||
1339 | zr->stat_com[i] |= cpu_to_le32(1); | ||
1340 | if (zr->jpg_settings.TmpDcm != 1) | ||
1341 | zr->stat_com[i + 1] |= cpu_to_le32(1); | ||
1342 | /* Refill */ | ||
1343 | zoran_reap_stat_com(zr); | ||
1344 | zoran_feed_stat_com(zr); | ||
1345 | wake_up_interruptible(&zr->jpg_capq); | ||
1346 | /* Find an entry in stat_com again after refill */ | ||
1347 | if (zr->jpg_settings.TmpDcm == 1) | ||
1348 | i = (zr->jpg_dma_tail - | ||
1349 | zr->jpg_err_shift) & | ||
1350 | BUZ_MASK_STAT_COM; | ||
1351 | else | ||
1352 | i = ((zr->jpg_dma_tail - | ||
1353 | zr->jpg_err_shift) & 1) * 2; | ||
1354 | } | ||
1355 | if (i) { | ||
1356 | /* Rotate stat_comm entries to make current entry first */ | ||
1357 | int j; | ||
1358 | u32 bus_addr[BUZ_NUM_STAT_COM]; | ||
1359 | |||
1360 | /* Here we are copying the stat_com array, which | ||
1361 | * is already in little endian format, so | ||
1362 | * no endian conversions here | ||
1363 | */ | ||
1364 | memcpy(bus_addr, zr->stat_com, | ||
1365 | sizeof(bus_addr)); | ||
1366 | for (j = 0; j < BUZ_NUM_STAT_COM; j++) { | ||
1367 | zr->stat_com[j] = | ||
1368 | bus_addr[(i + j) & | ||
1369 | BUZ_MASK_STAT_COM]; | ||
1370 | |||
1371 | } | ||
1372 | zr->jpg_err_shift += i; | ||
1373 | zr->jpg_err_shift &= BUZ_MASK_STAT_COM; | ||
1374 | } | ||
1375 | if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) | ||
1376 | zr->jpg_err_seq = zr->jpg_seq_num; /* + 1; */ | ||
1377 | } | ||
1378 | } | ||
1379 | |||
1380 | /* Now the stat_comm buffer is ready for restart */ | ||
1381 | do { | ||
1382 | int status, mode; | ||
1383 | |||
1384 | if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { | ||
1385 | decoder_command(zr, DECODER_GET_STATUS, &status); | ||
1386 | mode = CODEC_DO_COMPRESSION; | ||
1387 | } else { | ||
1388 | status = 0; | ||
1389 | mode = CODEC_DO_EXPANSION; | ||
1390 | } | ||
1391 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || | ||
1392 | (status & DECODER_STATUS_GOOD)) { | ||
1393 | /********** RESTART code *************/ | ||
1394 | jpeg_codec_reset(zr); | ||
1395 | zr->codec->set_mode(zr->codec, mode); | ||
1396 | zr36057_set_jpg(zr, zr->codec_mode); | ||
1397 | jpeg_start(zr); | ||
1398 | |||
1399 | if (zr->num_errors <= 8) | ||
1400 | dprintk(2, KERN_INFO "%s: Restart\n", | ||
1401 | ZR_DEVNAME(zr)); | ||
1402 | |||
1403 | zr->JPEG_missed = 0; | ||
1404 | zr->JPEG_error = 2; | ||
1405 | /********** End RESTART code ***********/ | ||
1406 | } | ||
1407 | } while (0); | ||
1408 | } | ||
1409 | |||
1410 | irqreturn_t | ||
1411 | zoran_irq (int irq, | ||
1412 | void *dev_id, | ||
1413 | struct pt_regs *regs) | ||
1414 | { | ||
1415 | u32 stat, astat; | ||
1416 | int count; | ||
1417 | struct zoran *zr; | ||
1418 | unsigned long flags; | ||
1419 | |||
1420 | zr = (struct zoran *) dev_id; | ||
1421 | count = 0; | ||
1422 | |||
1423 | if (zr->testing) { | ||
1424 | /* Testing interrupts */ | ||
1425 | spin_lock_irqsave(&zr->spinlock, flags); | ||
1426 | while ((stat = count_reset_interrupt(zr))) { | ||
1427 | if (count++ > 100) { | ||
1428 | btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR); | ||
1429 | dprintk(1, | ||
1430 | KERN_ERR | ||
1431 | "%s: IRQ lockup while testing, isr=0x%08x, cleared int mask\n", | ||
1432 | ZR_DEVNAME(zr), stat); | ||
1433 | wake_up_interruptible(&zr->test_q); | ||
1434 | } | ||
1435 | } | ||
1436 | zr->last_isr = stat; | ||
1437 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
1438 | return IRQ_HANDLED; | ||
1439 | } | ||
1440 | |||
1441 | spin_lock_irqsave(&zr->spinlock, flags); | ||
1442 | while (1) { | ||
1443 | /* get/clear interrupt status bits */ | ||
1444 | stat = count_reset_interrupt(zr); | ||
1445 | astat = stat & IRQ_MASK; | ||
1446 | if (!astat) { | ||
1447 | break; | ||
1448 | } | ||
1449 | dprintk(4, | ||
1450 | KERN_DEBUG | ||
1451 | "zoran_irq: astat: 0x%08x, mask: 0x%08x\n", | ||
1452 | astat, btread(ZR36057_ICR)); | ||
1453 | if (astat & zr->card.vsync_int) { // SW | ||
1454 | |||
1455 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || | ||
1456 | zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { | ||
1457 | /* count missed interrupts */ | ||
1458 | zr->JPEG_missed++; | ||
1459 | } | ||
1460 | //post_office_read(zr,1,0); | ||
1461 | /* Interrupts may still happen when | ||
1462 | * zr->v4l_memgrab_active is switched off. | ||
1463 | * We simply ignore them */ | ||
1464 | |||
1465 | if (zr->v4l_memgrab_active) { | ||
1466 | |||
1467 | /* A lot more checks should be here ... */ | ||
1468 | if ((btread(ZR36057_VSSFGR) & | ||
1469 | ZR36057_VSSFGR_SnapShot) == 0) | ||
1470 | dprintk(1, | ||
1471 | KERN_WARNING | ||
1472 | "%s: BuzIRQ with SnapShot off ???\n", | ||
1473 | ZR_DEVNAME(zr)); | ||
1474 | |||
1475 | if (zr->v4l_grab_frame != NO_GRAB_ACTIVE) { | ||
1476 | /* There is a grab on a frame going on, check if it has finished */ | ||
1477 | |||
1478 | if ((btread(ZR36057_VSSFGR) & | ||
1479 | ZR36057_VSSFGR_FrameGrab) == | ||
1480 | 0) { | ||
1481 | /* it is finished, notify the user */ | ||
1482 | |||
1483 | zr->v4l_buffers.buffer[zr->v4l_grab_frame].state = BUZ_STATE_DONE; | ||
1484 | zr->v4l_buffers.buffer[zr->v4l_grab_frame].bs.seq = zr->v4l_grab_seq; | ||
1485 | do_gettimeofday(&zr->v4l_buffers.buffer[zr->v4l_grab_frame].bs.timestamp); | ||
1486 | zr->v4l_grab_frame = NO_GRAB_ACTIVE; | ||
1487 | zr->v4l_pend_tail++; | ||
1488 | } | ||
1489 | } | ||
1490 | |||
1491 | if (zr->v4l_grab_frame == NO_GRAB_ACTIVE) | ||
1492 | wake_up_interruptible(&zr->v4l_capq); | ||
1493 | |||
1494 | /* Check if there is another grab queued */ | ||
1495 | |||
1496 | if (zr->v4l_grab_frame == NO_GRAB_ACTIVE && | ||
1497 | zr->v4l_pend_tail != zr->v4l_pend_head) { | ||
1498 | |||
1499 | int frame = zr->v4l_pend[zr->v4l_pend_tail & | ||
1500 | V4L_MASK_FRAME]; | ||
1501 | u32 reg; | ||
1502 | |||
1503 | zr->v4l_grab_frame = frame; | ||
1504 | |||
1505 | /* Set zr36057 video front end and enable video */ | ||
1506 | |||
1507 | /* Buffer address */ | ||
1508 | |||
1509 | reg = | ||
1510 | zr->v4l_buffers.buffer[frame]. | ||
1511 | fbuffer_bus; | ||
1512 | btwrite(reg, ZR36057_VDTR); | ||
1513 | if (zr->v4l_settings.height > | ||
1514 | BUZ_MAX_HEIGHT / 2) | ||
1515 | reg += | ||
1516 | zr->v4l_settings. | ||
1517 | bytesperline; | ||
1518 | btwrite(reg, ZR36057_VDBR); | ||
1519 | |||
1520 | /* video stride, status, and frame grab register */ | ||
1521 | reg = 0; | ||
1522 | if (zr->v4l_settings.height > | ||
1523 | BUZ_MAX_HEIGHT / 2) | ||
1524 | reg += | ||
1525 | zr->v4l_settings. | ||
1526 | bytesperline; | ||
1527 | reg = | ||
1528 | (reg << | ||
1529 | ZR36057_VSSFGR_DispStride); | ||
1530 | reg |= ZR36057_VSSFGR_VidOvf; | ||
1531 | reg |= ZR36057_VSSFGR_SnapShot; | ||
1532 | reg |= ZR36057_VSSFGR_FrameGrab; | ||
1533 | btwrite(reg, ZR36057_VSSFGR); | ||
1534 | |||
1535 | btor(ZR36057_VDCR_VidEn, | ||
1536 | ZR36057_VDCR); | ||
1537 | } | ||
1538 | } | ||
1539 | |||
1540 | /* even if we don't grab, we do want to increment | ||
1541 | * the sequence counter to see lost frames */ | ||
1542 | zr->v4l_grab_seq++; | ||
1543 | } | ||
1544 | #if (IRQ_MASK & ZR36057_ISR_CodRepIRQ) | ||
1545 | if (astat & ZR36057_ISR_CodRepIRQ) { | ||
1546 | zr->intr_counter_CodRepIRQ++; | ||
1547 | IDEBUG(printk | ||
1548 | (KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n", | ||
1549 | ZR_DEVNAME(zr))); | ||
1550 | btand(~ZR36057_ICR_CodRepIRQ, ZR36057_ICR); | ||
1551 | } | ||
1552 | #endif /* (IRQ_MASK & ZR36057_ISR_CodRepIRQ) */ | ||
1553 | |||
1554 | #if (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) | ||
1555 | if (astat & ZR36057_ISR_JPEGRepIRQ) { | ||
1556 | |||
1557 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || | ||
1558 | zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { | ||
1559 | if (*zr_debug > 1 && | ||
1560 | (!zr->frame_num || zr->JPEG_error)) { | ||
1561 | printk(KERN_INFO | ||
1562 | "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n", | ||
1563 | ZR_DEVNAME(zr), stat, | ||
1564 | zr->jpg_settings.odd_even, | ||
1565 | zr->jpg_settings. | ||
1566 | field_per_buff, | ||
1567 | zr->JPEG_missed); | ||
1568 | { | ||
1569 | char sc[] = "0000"; | ||
1570 | char sv[5]; | ||
1571 | int i; | ||
1572 | strcpy(sv, sc); | ||
1573 | for (i = 0; i < 4; i++) { | ||
1574 | if (le32_to_cpu(zr->stat_com[i]) & 1) | ||
1575 | sv[i] = '1'; | ||
1576 | } | ||
1577 | sv[4] = 0; | ||
1578 | printk(KERN_INFO | ||
1579 | "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n", | ||
1580 | ZR_DEVNAME(zr), sv, | ||
1581 | zr->jpg_que_tail, | ||
1582 | zr->jpg_dma_tail, | ||
1583 | zr->jpg_dma_head, | ||
1584 | zr->jpg_que_head); | ||
1585 | } | ||
1586 | } else { | ||
1587 | if (zr->JPEG_missed > zr->JPEG_max_missed) // Get statistics | ||
1588 | zr->JPEG_max_missed = | ||
1589 | zr->JPEG_missed; | ||
1590 | if (zr->JPEG_missed < | ||
1591 | zr->JPEG_min_missed) | ||
1592 | zr->JPEG_min_missed = | ||
1593 | zr->JPEG_missed; | ||
1594 | } | ||
1595 | |||
1596 | if (*zr_debug > 2 && zr->frame_num < 6) { | ||
1597 | int i; | ||
1598 | printk("%s: seq=%ld stat_com:", | ||
1599 | ZR_DEVNAME(zr), zr->jpg_seq_num); | ||
1600 | for (i = 0; i < 4; i++) { | ||
1601 | printk(" %08x", | ||
1602 | le32_to_cpu(zr->stat_com[i])); | ||
1603 | } | ||
1604 | printk("\n"); | ||
1605 | } | ||
1606 | zr->frame_num++; | ||
1607 | zr->JPEG_missed = 0; | ||
1608 | zr->JPEG_error = 0; | ||
1609 | zoran_reap_stat_com(zr); | ||
1610 | zoran_feed_stat_com(zr); | ||
1611 | wake_up_interruptible(&zr->jpg_capq); | ||
1612 | } /*else { | ||
1613 | dprintk(1, | ||
1614 | KERN_ERR | ||
1615 | "%s: JPEG interrupt while not in motion (de)compress mode!\n", | ||
1616 | ZR_DEVNAME(zr)); | ||
1617 | }*/ | ||
1618 | } | ||
1619 | #endif /* (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) */ | ||
1620 | |||
1621 | /* DATERR, too many fields missed, error processing */ | ||
1622 | if ((astat & zr->card.jpeg_int) || | ||
1623 | zr->JPEG_missed > 25 || | ||
1624 | zr->JPEG_error == 1 || | ||
1625 | ((zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) && | ||
1626 | (zr->frame_num & (zr->JPEG_missed > | ||
1627 | zr->jpg_settings.field_per_buff)))) { | ||
1628 | error_handler(zr, astat, stat); | ||
1629 | } | ||
1630 | |||
1631 | count++; | ||
1632 | if (count > 10) { | ||
1633 | dprintk(2, KERN_WARNING "%s: irq loop %d\n", | ||
1634 | ZR_DEVNAME(zr), count); | ||
1635 | if (count > 20) { | ||
1636 | btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR); | ||
1637 | dprintk(2, | ||
1638 | KERN_ERR | ||
1639 | "%s: IRQ lockup, cleared int mask\n", | ||
1640 | ZR_DEVNAME(zr)); | ||
1641 | break; | ||
1642 | } | ||
1643 | } | ||
1644 | zr->last_isr = stat; | ||
1645 | } | ||
1646 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
1647 | |||
1648 | return IRQ_HANDLED; | ||
1649 | } | ||
1650 | |||
1651 | void | ||
1652 | zoran_set_pci_master (struct zoran *zr, | ||
1653 | int set_master) | ||
1654 | { | ||
1655 | if (set_master) { | ||
1656 | pci_set_master(zr->pci_dev); | ||
1657 | } else { | ||
1658 | u16 command; | ||
1659 | |||
1660 | pci_read_config_word(zr->pci_dev, PCI_COMMAND, &command); | ||
1661 | command &= ~PCI_COMMAND_MASTER; | ||
1662 | pci_write_config_word(zr->pci_dev, PCI_COMMAND, command); | ||
1663 | } | ||
1664 | } | ||
1665 | |||
1666 | void | ||
1667 | zoran_init_hardware (struct zoran *zr) | ||
1668 | { | ||
1669 | int j, zero = 0; | ||
1670 | |||
1671 | /* Enable bus-mastering */ | ||
1672 | zoran_set_pci_master(zr, 1); | ||
1673 | |||
1674 | /* Initialize the board */ | ||
1675 | if (zr->card.init) { | ||
1676 | zr->card.init(zr); | ||
1677 | } | ||
1678 | |||
1679 | j = zr->card.input[zr->input].muxsel; | ||
1680 | |||
1681 | decoder_command(zr, 0, NULL); | ||
1682 | decoder_command(zr, DECODER_SET_NORM, &zr->norm); | ||
1683 | decoder_command(zr, DECODER_SET_INPUT, &j); | ||
1684 | |||
1685 | encoder_command(zr, 0, NULL); | ||
1686 | encoder_command(zr, ENCODER_SET_NORM, &zr->norm); | ||
1687 | encoder_command(zr, ENCODER_SET_INPUT, &zero); | ||
1688 | |||
1689 | /* toggle JPEG codec sleep to sync PLL */ | ||
1690 | jpeg_codec_sleep(zr, 1); | ||
1691 | jpeg_codec_sleep(zr, 0); | ||
1692 | |||
1693 | /* set individual interrupt enables (without GIRQ1) | ||
1694 | * but don't global enable until zoran_open() */ | ||
1695 | |||
1696 | //btwrite(IRQ_MASK & ~ZR36057_ISR_GIRQ1, ZR36057_ICR); // SW | ||
1697 | // It looks like using only JPEGRepIRQEn is not always reliable, | ||
1698 | // may be when JPEG codec crashes it won't generate IRQ? So, | ||
1699 | /*CP*/ // btwrite(IRQ_MASK, ZR36057_ICR); // Enable Vsync interrupts too. SM WHY ? LP | ||
1700 | zr36057_init_vfe(zr); | ||
1701 | |||
1702 | zr36057_enable_jpg(zr, BUZ_MODE_IDLE); | ||
1703 | |||
1704 | btwrite(IRQ_MASK, ZR36057_ISR); // Clears interrupts | ||
1705 | } | ||
1706 | |||
1707 | void | ||
1708 | zr36057_restart (struct zoran *zr) | ||
1709 | { | ||
1710 | btwrite(0, ZR36057_SPGPPCR); | ||
1711 | mdelay(1); | ||
1712 | btor(ZR36057_SPGPPCR_SoftReset, ZR36057_SPGPPCR); | ||
1713 | mdelay(1); | ||
1714 | |||
1715 | /* assert P_Reset */ | ||
1716 | btwrite(0, ZR36057_JPC); | ||
1717 | /* set up GPIO direction - all output */ | ||
1718 | btwrite(ZR36057_SPGPPCR_SoftReset | 0, ZR36057_SPGPPCR); | ||
1719 | |||
1720 | /* set up GPIO pins and guest bus timing */ | ||
1721 | btwrite((0x81 << 24) | 0x8888, ZR36057_GPPGCR1); | ||
1722 | } | ||
1723 | |||
1724 | /* | ||
1725 | * initialize video front end | ||
1726 | */ | ||
1727 | |||
1728 | static void | ||
1729 | zr36057_init_vfe (struct zoran *zr) | ||
1730 | { | ||
1731 | u32 reg; | ||
1732 | |||
1733 | reg = btread(ZR36057_VFESPFR); | ||
1734 | reg |= ZR36057_VFESPFR_LittleEndian; | ||
1735 | reg &= ~ZR36057_VFESPFR_VCLKPol; | ||
1736 | reg |= ZR36057_VFESPFR_ExtFl; | ||
1737 | reg |= ZR36057_VFESPFR_TopField; | ||
1738 | btwrite(reg, ZR36057_VFESPFR); | ||
1739 | reg = btread(ZR36057_VDCR); | ||
1740 | if (pci_pci_problems & PCIPCI_TRITON) | ||
1741 | // || zr->revision < 1) // Revision 1 has also Triton support | ||
1742 | reg &= ~ZR36057_VDCR_Triton; | ||
1743 | else | ||
1744 | reg |= ZR36057_VDCR_Triton; | ||
1745 | btwrite(reg, ZR36057_VDCR); | ||
1746 | } | ||
1747 | |||
1748 | /* | ||
1749 | * Interface to decoder and encoder chips using i2c bus | ||
1750 | */ | ||
1751 | |||
1752 | int | ||
1753 | decoder_command (struct zoran *zr, | ||
1754 | int cmd, | ||
1755 | void *data) | ||
1756 | { | ||
1757 | if (zr->decoder == NULL) | ||
1758 | return -EIO; | ||
1759 | |||
1760 | if (zr->card.type == LML33 && | ||
1761 | (cmd == DECODER_SET_NORM || DECODER_SET_INPUT)) { | ||
1762 | int res; | ||
1763 | |||
1764 | // Bt819 needs to reset its FIFO buffer using #FRST pin and | ||
1765 | // LML33 card uses GPIO(7) for that. | ||
1766 | GPIO(zr, 7, 0); | ||
1767 | res = zr->decoder->driver->command(zr->decoder, cmd, data); | ||
1768 | // Pull #FRST high. | ||
1769 | GPIO(zr, 7, 1); | ||
1770 | return res; | ||
1771 | } else | ||
1772 | return zr->decoder->driver->command(zr->decoder, cmd, | ||
1773 | data); | ||
1774 | } | ||
1775 | |||
1776 | int | ||
1777 | encoder_command (struct zoran *zr, | ||
1778 | int cmd, | ||
1779 | void *data) | ||
1780 | { | ||
1781 | if (zr->encoder == NULL) | ||
1782 | return -1; | ||
1783 | |||
1784 | return zr->encoder->driver->command(zr->encoder, cmd, data); | ||
1785 | } | ||