diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-14 11:13:30 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-15 15:36:22 -0400 |
commit | b285192a43f0432d82c2c10974204e78af0da596 (patch) | |
tree | 618aa87e760c9c949eca9e4df6ae0eeffa11dcfc /drivers/media/video/zoran | |
parent | 68de959f773a1d49096835c411390bceff5d1549 (diff) |
[media] rename most media/video pci drivers to media/pci
Rename all PCI drivers with their own directory under
drivers/media/video into drivers/media/pci and update the
building system.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/zoran')
-rw-r--r-- | drivers/media/video/zoran/Kconfig | 74 | ||||
-rw-r--r-- | drivers/media/video/zoran/Makefile | 6 | ||||
-rw-r--r-- | drivers/media/video/zoran/videocodec.c | 407 | ||||
-rw-r--r-- | drivers/media/video/zoran/videocodec.h | 353 | ||||
-rw-r--r-- | drivers/media/video/zoran/zoran.h | 403 | ||||
-rw-r--r-- | drivers/media/video/zoran/zoran_card.c | 1524 | ||||
-rw-r--r-- | drivers/media/video/zoran/zoran_card.h | 54 | ||||
-rw-r--r-- | drivers/media/video/zoran/zoran_device.c | 1640 | ||||
-rw-r--r-- | drivers/media/video/zoran/zoran_device.h | 95 | ||||
-rw-r--r-- | drivers/media/video/zoran/zoran_driver.c | 3090 | ||||
-rw-r--r-- | drivers/media/video/zoran/zoran_procfs.c | 225 | ||||
-rw-r--r-- | drivers/media/video/zoran/zoran_procfs.h | 36 | ||||
-rw-r--r-- | drivers/media/video/zoran/zr36016.c | 524 | ||||
-rw-r--r-- | drivers/media/video/zoran/zr36016.h | 111 | ||||
-rw-r--r-- | drivers/media/video/zoran/zr36050.c | 900 | ||||
-rw-r--r-- | drivers/media/video/zoran/zr36050.h | 184 | ||||
-rw-r--r-- | drivers/media/video/zoran/zr36057.h | 168 | ||||
-rw-r--r-- | drivers/media/video/zoran/zr36060.c | 1010 | ||||
-rw-r--r-- | drivers/media/video/zoran/zr36060.h | 220 |
19 files changed, 0 insertions, 11024 deletions
diff --git a/drivers/media/video/zoran/Kconfig b/drivers/media/video/zoran/Kconfig deleted file mode 100644 index fd4120e4c104..000000000000 --- a/drivers/media/video/zoran/Kconfig +++ /dev/null | |||
@@ -1,74 +0,0 @@ | |||
1 | config VIDEO_ZORAN | ||
2 | tristate "Zoran ZR36057/36067 Video For Linux" | ||
3 | depends on PCI && I2C_ALGOBIT && VIDEO_V4L2 && VIRT_TO_BUS | ||
4 | help | ||
5 | Say Y for support for MJPEG capture cards based on the Zoran | ||
6 | 36057/36067 PCI controller chipset. This includes the Iomega | ||
7 | Buz, Pinnacle DC10+ and the Linux Media Labs LML33. There is | ||
8 | a driver homepage at <http://mjpeg.sf.net/driver-zoran/>. For | ||
9 | more information, check <file:Documentation/video4linux/Zoran>. | ||
10 | |||
11 | To compile this driver as a module, choose M here: the | ||
12 | module will be called zr36067. | ||
13 | |||
14 | config VIDEO_ZORAN_DC30 | ||
15 | tristate "Pinnacle/Miro DC30(+) support" | ||
16 | depends on VIDEO_ZORAN | ||
17 | select VIDEO_ADV7175 if VIDEO_HELPER_CHIPS_AUTO | ||
18 | select VIDEO_VPX3220 if VIDEO_HELPER_CHIPS_AUTO | ||
19 | help | ||
20 | Support for the Pinnacle/Miro DC30(+) MJPEG capture/playback | ||
21 | card. This also supports really old DC10 cards based on the | ||
22 | zr36050 MJPEG codec and zr36016 VFE. | ||
23 | |||
24 | config VIDEO_ZORAN_ZR36060 | ||
25 | tristate "Zoran ZR36060" | ||
26 | depends on VIDEO_ZORAN | ||
27 | help | ||
28 | Say Y to support Zoran boards based on 36060 chips. | ||
29 | This includes Iomega Buz, Pinnacle DC10, Linux media Labs 33 | ||
30 | and 33 R10 and AverMedia 6 boards. | ||
31 | |||
32 | config VIDEO_ZORAN_BUZ | ||
33 | tristate "Iomega Buz support" | ||
34 | depends on VIDEO_ZORAN_ZR36060 | ||
35 | select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO | ||
36 | select VIDEO_SAA7185 if VIDEO_HELPER_CHIPS_AUTO | ||
37 | help | ||
38 | Support for the Iomega Buz MJPEG capture/playback card. | ||
39 | |||
40 | config VIDEO_ZORAN_DC10 | ||
41 | tristate "Pinnacle/Miro DC10(+) support" | ||
42 | depends on VIDEO_ZORAN_ZR36060 | ||
43 | select VIDEO_SAA7110 if VIDEO_HELPER_CHIPS_AUTO | ||
44 | select VIDEO_ADV7175 if VIDEO_HELPER_CHIPS_AUTO | ||
45 | help | ||
46 | Support for the Pinnacle/Miro DC10(+) MJPEG capture/playback | ||
47 | card. | ||
48 | |||
49 | config VIDEO_ZORAN_LML33 | ||
50 | tristate "Linux Media Labs LML33 support" | ||
51 | depends on VIDEO_ZORAN_ZR36060 | ||
52 | select VIDEO_BT819 if VIDEO_HELPER_CHIPS_AUTO | ||
53 | select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO | ||
54 | help | ||
55 | Support for the Linux Media Labs LML33 MJPEG capture/playback | ||
56 | card. | ||
57 | |||
58 | config VIDEO_ZORAN_LML33R10 | ||
59 | tristate "Linux Media Labs LML33R10 support" | ||
60 | depends on VIDEO_ZORAN_ZR36060 | ||
61 | select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO | ||
62 | select VIDEO_ADV7170 if VIDEO_HELPER_CHIPS_AUTO | ||
63 | help | ||
64 | support for the Linux Media Labs LML33R10 MJPEG capture/playback | ||
65 | card. | ||
66 | |||
67 | config VIDEO_ZORAN_AVS6EYES | ||
68 | tristate "AverMedia 6 Eyes support (EXPERIMENTAL)" | ||
69 | depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL | ||
70 | select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO | ||
71 | select VIDEO_BT866 if VIDEO_HELPER_CHIPS_AUTO | ||
72 | select VIDEO_KS0127 if VIDEO_HELPER_CHIPS_AUTO | ||
73 | help | ||
74 | Support for the AverMedia 6 Eyes video surveillance card. | ||
diff --git a/drivers/media/video/zoran/Makefile b/drivers/media/video/zoran/Makefile deleted file mode 100644 index 44cc13352c88..000000000000 --- a/drivers/media/video/zoran/Makefile +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | zr36067-objs := zoran_procfs.o zoran_device.o \ | ||
2 | zoran_driver.o zoran_card.o | ||
3 | |||
4 | obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o videocodec.o | ||
5 | obj-$(CONFIG_VIDEO_ZORAN_DC30) += zr36050.o zr36016.o | ||
6 | obj-$(CONFIG_VIDEO_ZORAN_ZR36060) += zr36060.o | ||
diff --git a/drivers/media/video/zoran/videocodec.c b/drivers/media/video/zoran/videocodec.c deleted file mode 100644 index c01071635290..000000000000 --- a/drivers/media/video/zoran/videocodec.c +++ /dev/null | |||
@@ -1,407 +0,0 @@ | |||
1 | /* | ||
2 | * VIDEO MOTION CODECs internal API for video devices | ||
3 | * | ||
4 | * Interface for MJPEG (and maybe later MPEG/WAVELETS) codec's | ||
5 | * bound to a master device. | ||
6 | * | ||
7 | * (c) 2002 Wolfgang Scherr <scherr@net4you.at> | ||
8 | * | ||
9 | * $Id: videocodec.c,v 1.1.2.8 2003/03/29 07:16:04 rbultje Exp $ | ||
10 | * | ||
11 | * ------------------------------------------------------------------------ | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | * | ||
27 | * ------------------------------------------------------------------------ | ||
28 | */ | ||
29 | |||
30 | #define VIDEOCODEC_VERSION "v0.2" | ||
31 | |||
32 | #include <linux/kernel.h> | ||
33 | #include <linux/module.h> | ||
34 | #include <linux/init.h> | ||
35 | #include <linux/types.h> | ||
36 | #include <linux/slab.h> | ||
37 | |||
38 | // kernel config is here (procfs flag) | ||
39 | |||
40 | #ifdef CONFIG_PROC_FS | ||
41 | #include <linux/proc_fs.h> | ||
42 | #include <linux/seq_file.h> | ||
43 | #include <asm/uaccess.h> | ||
44 | #endif | ||
45 | |||
46 | #include "videocodec.h" | ||
47 | |||
48 | static int debug; | ||
49 | module_param(debug, int, 0); | ||
50 | MODULE_PARM_DESC(debug, "Debug level (0-4)"); | ||
51 | |||
52 | #define dprintk(num, format, args...) \ | ||
53 | do { \ | ||
54 | if (debug >= num) \ | ||
55 | printk(format, ##args); \ | ||
56 | } while (0) | ||
57 | |||
58 | struct attached_list { | ||
59 | struct videocodec *codec; | ||
60 | struct attached_list *next; | ||
61 | }; | ||
62 | |||
63 | struct codec_list { | ||
64 | const struct videocodec *codec; | ||
65 | int attached; | ||
66 | struct attached_list *list; | ||
67 | struct codec_list *next; | ||
68 | }; | ||
69 | |||
70 | static struct codec_list *codeclist_top = NULL; | ||
71 | |||
72 | /* ================================================= */ | ||
73 | /* function prototypes of the master/slave interface */ | ||
74 | /* ================================================= */ | ||
75 | |||
76 | struct videocodec * | ||
77 | videocodec_attach (struct videocodec_master *master) | ||
78 | { | ||
79 | struct codec_list *h = codeclist_top; | ||
80 | struct attached_list *a, *ptr; | ||
81 | struct videocodec *codec; | ||
82 | int res; | ||
83 | |||
84 | if (!master) { | ||
85 | dprintk(1, KERN_ERR "videocodec_attach: no data\n"); | ||
86 | return NULL; | ||
87 | } | ||
88 | |||
89 | dprintk(2, | ||
90 | "videocodec_attach: '%s', flags %lx, magic %lx\n", | ||
91 | master->name, master->flags, master->magic); | ||
92 | |||
93 | if (!h) { | ||
94 | dprintk(1, | ||
95 | KERN_ERR | ||
96 | "videocodec_attach: no device available\n"); | ||
97 | return NULL; | ||
98 | } | ||
99 | |||
100 | while (h) { | ||
101 | // attach only if the slave has at least the flags | ||
102 | // expected by the master | ||
103 | if ((master->flags & h->codec->flags) == master->flags) { | ||
104 | dprintk(4, "videocodec_attach: try '%s'\n", | ||
105 | h->codec->name); | ||
106 | |||
107 | if (!try_module_get(h->codec->owner)) | ||
108 | return NULL; | ||
109 | |||
110 | codec = kmemdup(h->codec, sizeof(struct videocodec), | ||
111 | GFP_KERNEL); | ||
112 | if (!codec) { | ||
113 | dprintk(1, | ||
114 | KERN_ERR | ||
115 | "videocodec_attach: no mem\n"); | ||
116 | goto out_module_put; | ||
117 | } | ||
118 | |||
119 | snprintf(codec->name, sizeof(codec->name), | ||
120 | "%s[%d]", codec->name, h->attached); | ||
121 | codec->master_data = master; | ||
122 | res = codec->setup(codec); | ||
123 | if (res == 0) { | ||
124 | dprintk(3, "videocodec_attach '%s'\n", | ||
125 | codec->name); | ||
126 | ptr = kzalloc(sizeof(struct attached_list), GFP_KERNEL); | ||
127 | if (!ptr) { | ||
128 | dprintk(1, | ||
129 | KERN_ERR | ||
130 | "videocodec_attach: no memory\n"); | ||
131 | goto out_kfree; | ||
132 | } | ||
133 | ptr->codec = codec; | ||
134 | |||
135 | a = h->list; | ||
136 | if (!a) { | ||
137 | h->list = ptr; | ||
138 | dprintk(4, | ||
139 | "videocodec: first element\n"); | ||
140 | } else { | ||
141 | while (a->next) | ||
142 | a = a->next; // find end | ||
143 | a->next = ptr; | ||
144 | dprintk(4, | ||
145 | "videocodec: in after '%s'\n", | ||
146 | h->codec->name); | ||
147 | } | ||
148 | |||
149 | h->attached += 1; | ||
150 | return codec; | ||
151 | } else { | ||
152 | kfree(codec); | ||
153 | } | ||
154 | } | ||
155 | h = h->next; | ||
156 | } | ||
157 | |||
158 | dprintk(1, KERN_ERR "videocodec_attach: no codec found!\n"); | ||
159 | return NULL; | ||
160 | |||
161 | out_module_put: | ||
162 | module_put(h->codec->owner); | ||
163 | out_kfree: | ||
164 | kfree(codec); | ||
165 | return NULL; | ||
166 | } | ||
167 | |||
168 | int | ||
169 | videocodec_detach (struct videocodec *codec) | ||
170 | { | ||
171 | struct codec_list *h = codeclist_top; | ||
172 | struct attached_list *a, *prev; | ||
173 | int res; | ||
174 | |||
175 | if (!codec) { | ||
176 | dprintk(1, KERN_ERR "videocodec_detach: no data\n"); | ||
177 | return -EINVAL; | ||
178 | } | ||
179 | |||
180 | dprintk(2, | ||
181 | "videocodec_detach: '%s', type: %x, flags %lx, magic %lx\n", | ||
182 | codec->name, codec->type, codec->flags, codec->magic); | ||
183 | |||
184 | if (!h) { | ||
185 | dprintk(1, | ||
186 | KERN_ERR "videocodec_detach: no device left...\n"); | ||
187 | return -ENXIO; | ||
188 | } | ||
189 | |||
190 | while (h) { | ||
191 | a = h->list; | ||
192 | prev = NULL; | ||
193 | while (a) { | ||
194 | if (codec == a->codec) { | ||
195 | res = a->codec->unset(a->codec); | ||
196 | if (res >= 0) { | ||
197 | dprintk(3, | ||
198 | "videocodec_detach: '%s'\n", | ||
199 | a->codec->name); | ||
200 | a->codec->master_data = NULL; | ||
201 | } else { | ||
202 | dprintk(1, | ||
203 | KERN_ERR | ||
204 | "videocodec_detach: '%s'\n", | ||
205 | a->codec->name); | ||
206 | a->codec->master_data = NULL; | ||
207 | } | ||
208 | if (prev == NULL) { | ||
209 | h->list = a->next; | ||
210 | dprintk(4, | ||
211 | "videocodec: delete first\n"); | ||
212 | } else { | ||
213 | prev->next = a->next; | ||
214 | dprintk(4, | ||
215 | "videocodec: delete middle\n"); | ||
216 | } | ||
217 | module_put(a->codec->owner); | ||
218 | kfree(a->codec); | ||
219 | kfree(a); | ||
220 | h->attached -= 1; | ||
221 | return 0; | ||
222 | } | ||
223 | prev = a; | ||
224 | a = a->next; | ||
225 | } | ||
226 | h = h->next; | ||
227 | } | ||
228 | |||
229 | dprintk(1, KERN_ERR "videocodec_detach: given codec not found!\n"); | ||
230 | return -EINVAL; | ||
231 | } | ||
232 | |||
233 | int | ||
234 | videocodec_register (const struct videocodec *codec) | ||
235 | { | ||
236 | struct codec_list *ptr, *h = codeclist_top; | ||
237 | |||
238 | if (!codec) { | ||
239 | dprintk(1, KERN_ERR "videocodec_register: no data!\n"); | ||
240 | return -EINVAL; | ||
241 | } | ||
242 | |||
243 | dprintk(2, | ||
244 | "videocodec: register '%s', type: %x, flags %lx, magic %lx\n", | ||
245 | codec->name, codec->type, codec->flags, codec->magic); | ||
246 | |||
247 | ptr = kzalloc(sizeof(struct codec_list), GFP_KERNEL); | ||
248 | if (!ptr) { | ||
249 | dprintk(1, KERN_ERR "videocodec_register: no memory\n"); | ||
250 | return -ENOMEM; | ||
251 | } | ||
252 | ptr->codec = codec; | ||
253 | |||
254 | if (!h) { | ||
255 | codeclist_top = ptr; | ||
256 | dprintk(4, "videocodec: hooked in as first element\n"); | ||
257 | } else { | ||
258 | while (h->next) | ||
259 | h = h->next; // find the end | ||
260 | h->next = ptr; | ||
261 | dprintk(4, "videocodec: hooked in after '%s'\n", | ||
262 | h->codec->name); | ||
263 | } | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | int | ||
269 | videocodec_unregister (const struct videocodec *codec) | ||
270 | { | ||
271 | struct codec_list *prev = NULL, *h = codeclist_top; | ||
272 | |||
273 | if (!codec) { | ||
274 | dprintk(1, KERN_ERR "videocodec_unregister: no data!\n"); | ||
275 | return -EINVAL; | ||
276 | } | ||
277 | |||
278 | dprintk(2, | ||
279 | "videocodec: unregister '%s', type: %x, flags %lx, magic %lx\n", | ||
280 | codec->name, codec->type, codec->flags, codec->magic); | ||
281 | |||
282 | if (!h) { | ||
283 | dprintk(1, | ||
284 | KERN_ERR | ||
285 | "videocodec_unregister: no device left...\n"); | ||
286 | return -ENXIO; | ||
287 | } | ||
288 | |||
289 | while (h) { | ||
290 | if (codec == h->codec) { | ||
291 | if (h->attached) { | ||
292 | dprintk(1, | ||
293 | KERN_ERR | ||
294 | "videocodec: '%s' is used\n", | ||
295 | h->codec->name); | ||
296 | return -EBUSY; | ||
297 | } | ||
298 | dprintk(3, "videocodec: unregister '%s' is ok.\n", | ||
299 | h->codec->name); | ||
300 | if (prev == NULL) { | ||
301 | codeclist_top = h->next; | ||
302 | dprintk(4, | ||
303 | "videocodec: delete first element\n"); | ||
304 | } else { | ||
305 | prev->next = h->next; | ||
306 | dprintk(4, | ||
307 | "videocodec: delete middle element\n"); | ||
308 | } | ||
309 | kfree(h); | ||
310 | return 0; | ||
311 | } | ||
312 | prev = h; | ||
313 | h = h->next; | ||
314 | } | ||
315 | |||
316 | dprintk(1, | ||
317 | KERN_ERR | ||
318 | "videocodec_unregister: given codec not found!\n"); | ||
319 | return -EINVAL; | ||
320 | } | ||
321 | |||
322 | #ifdef CONFIG_PROC_FS | ||
323 | static int proc_videocodecs_show(struct seq_file *m, void *v) | ||
324 | { | ||
325 | struct codec_list *h = codeclist_top; | ||
326 | struct attached_list *a; | ||
327 | |||
328 | seq_printf(m, "<S>lave or attached <M>aster name type flags magic "); | ||
329 | seq_printf(m, "(connected as)\n"); | ||
330 | |||
331 | h = codeclist_top; | ||
332 | while (h) { | ||
333 | seq_printf(m, "S %32s %04x %08lx %08lx (TEMPLATE)\n", | ||
334 | h->codec->name, h->codec->type, | ||
335 | h->codec->flags, h->codec->magic); | ||
336 | a = h->list; | ||
337 | while (a) { | ||
338 | seq_printf(m, "M %32s %04x %08lx %08lx (%s)\n", | ||
339 | a->codec->master_data->name, | ||
340 | a->codec->master_data->type, | ||
341 | a->codec->master_data->flags, | ||
342 | a->codec->master_data->magic, | ||
343 | a->codec->name); | ||
344 | a = a->next; | ||
345 | } | ||
346 | h = h->next; | ||
347 | } | ||
348 | |||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | static int proc_videocodecs_open(struct inode *inode, struct file *file) | ||
353 | { | ||
354 | return single_open(file, proc_videocodecs_show, NULL); | ||
355 | } | ||
356 | |||
357 | static const struct file_operations videocodecs_proc_fops = { | ||
358 | .owner = THIS_MODULE, | ||
359 | .open = proc_videocodecs_open, | ||
360 | .read = seq_read, | ||
361 | .llseek = seq_lseek, | ||
362 | .release = single_release, | ||
363 | }; | ||
364 | #endif | ||
365 | |||
366 | /* ===================== */ | ||
367 | /* hook in driver module */ | ||
368 | /* ===================== */ | ||
369 | static int __init | ||
370 | videocodec_init (void) | ||
371 | { | ||
372 | #ifdef CONFIG_PROC_FS | ||
373 | static struct proc_dir_entry *videocodec_proc_entry; | ||
374 | #endif | ||
375 | |||
376 | printk(KERN_INFO "Linux video codec intermediate layer: %s\n", | ||
377 | VIDEOCODEC_VERSION); | ||
378 | |||
379 | #ifdef CONFIG_PROC_FS | ||
380 | videocodec_proc_entry = proc_create("videocodecs", 0, NULL, &videocodecs_proc_fops); | ||
381 | if (!videocodec_proc_entry) { | ||
382 | dprintk(1, KERN_ERR "videocodec: can't init procfs.\n"); | ||
383 | } | ||
384 | #endif | ||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | static void __exit | ||
389 | videocodec_exit (void) | ||
390 | { | ||
391 | #ifdef CONFIG_PROC_FS | ||
392 | remove_proc_entry("videocodecs", NULL); | ||
393 | #endif | ||
394 | } | ||
395 | |||
396 | EXPORT_SYMBOL(videocodec_attach); | ||
397 | EXPORT_SYMBOL(videocodec_detach); | ||
398 | EXPORT_SYMBOL(videocodec_register); | ||
399 | EXPORT_SYMBOL(videocodec_unregister); | ||
400 | |||
401 | module_init(videocodec_init); | ||
402 | module_exit(videocodec_exit); | ||
403 | |||
404 | MODULE_AUTHOR("Wolfgang Scherr <scherr@net4you.at>"); | ||
405 | MODULE_DESCRIPTION("Intermediate API module for video codecs " | ||
406 | VIDEOCODEC_VERSION); | ||
407 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/zoran/videocodec.h b/drivers/media/video/zoran/videocodec.h deleted file mode 100644 index def55585ad23..000000000000 --- a/drivers/media/video/zoran/videocodec.h +++ /dev/null | |||
@@ -1,353 +0,0 @@ | |||
1 | /* | ||
2 | * VIDEO MOTION CODECs internal API for video devices | ||
3 | * | ||
4 | * Interface for MJPEG (and maybe later MPEG/WAVELETS) codec's | ||
5 | * bound to a master device. | ||
6 | * | ||
7 | * (c) 2002 Wolfgang Scherr <scherr@net4you.at> | ||
8 | * | ||
9 | * $Id: videocodec.h,v 1.1.2.4 2003/01/14 21:15:03 rbultje Exp $ | ||
10 | * | ||
11 | * ------------------------------------------------------------------------ | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | * | ||
27 | * ------------------------------------------------------------------------ | ||
28 | */ | ||
29 | |||
30 | /* =================== */ | ||
31 | /* general description */ | ||
32 | /* =================== */ | ||
33 | |||
34 | /* Should ease the (re-)usage of drivers supporting cards with (different) | ||
35 | video codecs. The codecs register to this module their functionality, | ||
36 | and the processors (masters) can attach to them if they fit. | ||
37 | |||
38 | The codecs are typically have a "strong" binding to their master - so I | ||
39 | don't think it makes sense to have a full blown interfacing as with e.g. | ||
40 | i2c. If you have an other opinion, let's discuss & implement it :-))) | ||
41 | |||
42 | Usage: | ||
43 | |||
44 | The slave has just to setup the videocodec structure and use two functions: | ||
45 | videocodec_register(codecdata); | ||
46 | videocodec_unregister(codecdata); | ||
47 | The best is just calling them at module (de-)initialisation. | ||
48 | |||
49 | The master sets up the structure videocodec_master and calls: | ||
50 | codecdata=videocodec_attach(master_codecdata); | ||
51 | videocodec_detach(codecdata); | ||
52 | |||
53 | The slave is called during attach/detach via functions setup previously | ||
54 | during register. At that time, the master_data pointer is set up | ||
55 | and the slave can access any io registers of the master device (in the case | ||
56 | the slave is bound to it). Otherwise it doesn't need this functions and | ||
57 | therfor they may not be initialized. | ||
58 | |||
59 | The other functions are just for convenience, as they are for sure used by | ||
60 | most/all of the codecs. The last ones may be omitted, too. | ||
61 | |||
62 | See the structure declaration below for more information and which data has | ||
63 | to be set up for the master and the slave. | ||
64 | |||
65 | ---------------------------------------------------------------------------- | ||
66 | The master should have "knowledge" of the slave and vice versa. So the data | ||
67 | structures sent to/from slave via set_data/get_data set_image/get_image are | ||
68 | device dependent and vary between MJPEG/MPEG/WAVELET/... devices. (!!!!) | ||
69 | ---------------------------------------------------------------------------- | ||
70 | */ | ||
71 | |||
72 | |||
73 | /* ========================================== */ | ||
74 | /* description of the videocodec_io structure */ | ||
75 | /* ========================================== */ | ||
76 | |||
77 | /* | ||
78 | ==== master setup ==== | ||
79 | name -> name of the device structure for reference and debugging | ||
80 | master_data -> data ref. for the master (e.g. the zr36055,57,67) | ||
81 | readreg -> ref. to read-fn from register (setup by master, used by slave) | ||
82 | writereg -> ref. to write-fn to register (setup by master, used by slave) | ||
83 | this two functions do the lowlevel I/O job | ||
84 | |||
85 | ==== slave functionality setup ==== | ||
86 | slave_data -> data ref. for the slave (e.g. the zr36050,60) | ||
87 | check -> fn-ref. checks availability of an device, returns -EIO on failure or | ||
88 | the type on success | ||
89 | this makes espcecially sense if a driver module supports more than | ||
90 | one codec which may be quite similar to access, nevertheless it | ||
91 | is good for a first functionality check | ||
92 | |||
93 | -- main functions you always need for compression/decompression -- | ||
94 | |||
95 | set_mode -> this fn-ref. resets the entire codec, and sets up the mode | ||
96 | with the last defined norm/size (or device default if not | ||
97 | available) - it returns 0 if the mode is possible | ||
98 | set_size -> this fn-ref. sets the norm and image size for | ||
99 | compression/decompression (returns 0 on success) | ||
100 | the norm param is defined in videodev2.h (V4L2_STD_*) | ||
101 | |||
102 | additional setup may be available, too - but the codec should work with | ||
103 | some default values even without this | ||
104 | |||
105 | set_data -> sets device-specific data (tables, quality etc.) | ||
106 | get_data -> query device-specific data (tables, quality etc.) | ||
107 | |||
108 | if the device delivers interrupts, they may be setup/handled here | ||
109 | setup_interrupt -> codec irq setup (not needed for 36050/60) | ||
110 | handle_interrupt -> codec irq handling (not needed for 36050/60) | ||
111 | |||
112 | if the device delivers pictures, they may be handled here | ||
113 | put_image -> puts image data to the codec (not needed for 36050/60) | ||
114 | get_image -> gets image data from the codec (not needed for 36050/60) | ||
115 | the calls include frame numbers and flags (even/odd/...) | ||
116 | if needed and a flag which allows blocking until its ready | ||
117 | */ | ||
118 | |||
119 | /* ============== */ | ||
120 | /* user interface */ | ||
121 | /* ============== */ | ||
122 | |||
123 | /* | ||
124 | Currently there is only a information display planned, as the layer | ||
125 | is not visible for the user space at all. | ||
126 | |||
127 | Information is available via procfs. The current entry is "/proc/videocodecs" | ||
128 | but it makes sense to "hide" it in the /proc/video tree of v4l(2) --TODO--. | ||
129 | |||
130 | A example for such an output is: | ||
131 | |||
132 | <S>lave or attached <M>aster name type flags magic (connected as) | ||
133 | S zr36050 0002 0000d001 00000000 (TEMPLATE) | ||
134 | M zr36055[0] 0001 0000c001 00000000 (zr36050[0]) | ||
135 | M zr36055[1] 0001 0000c001 00000000 (zr36050[1]) | ||
136 | |||
137 | */ | ||
138 | |||
139 | |||
140 | /* =============================================== */ | ||
141 | /* special defines for the videocodec_io structure */ | ||
142 | /* =============================================== */ | ||
143 | |||
144 | #ifndef __LINUX_VIDEOCODEC_H | ||
145 | #define __LINUX_VIDEOCODEC_H | ||
146 | |||
147 | #include <linux/videodev2.h> | ||
148 | |||
149 | #define CODEC_DO_COMPRESSION 0 | ||
150 | #define CODEC_DO_EXPANSION 1 | ||
151 | |||
152 | /* this are the current codec flags I think they are needed */ | ||
153 | /* -> type value in structure */ | ||
154 | #define CODEC_FLAG_JPEG 0x00000001L // JPEG codec | ||
155 | #define CODEC_FLAG_MPEG 0x00000002L // MPEG1/2/4 codec | ||
156 | #define CODEC_FLAG_DIVX 0x00000004L // DIVX codec | ||
157 | #define CODEC_FLAG_WAVELET 0x00000008L // WAVELET codec | ||
158 | // room for other types | ||
159 | |||
160 | #define CODEC_FLAG_MAGIC 0x00000800L // magic key must match | ||
161 | #define CODEC_FLAG_HARDWARE 0x00001000L // is a hardware codec | ||
162 | #define CODEC_FLAG_VFE 0x00002000L // has direct video frontend | ||
163 | #define CODEC_FLAG_ENCODER 0x00004000L // compression capability | ||
164 | #define CODEC_FLAG_DECODER 0x00008000L // decompression capability | ||
165 | #define CODEC_FLAG_NEEDIRQ 0x00010000L // needs irq handling | ||
166 | #define CODEC_FLAG_RDWRPIC 0x00020000L // handles picture I/O | ||
167 | |||
168 | /* a list of modes, some are just examples (is there any HW?) */ | ||
169 | #define CODEC_MODE_BJPG 0x0001 // Baseline JPEG | ||
170 | #define CODEC_MODE_LJPG 0x0002 // Lossless JPEG | ||
171 | #define CODEC_MODE_MPEG1 0x0003 // MPEG 1 | ||
172 | #define CODEC_MODE_MPEG2 0x0004 // MPEG 2 | ||
173 | #define CODEC_MODE_MPEG4 0x0005 // MPEG 4 | ||
174 | #define CODEC_MODE_MSDIVX 0x0006 // MS DivX | ||
175 | #define CODEC_MODE_ODIVX 0x0007 // Open DivX | ||
176 | #define CODEC_MODE_WAVELET 0x0008 // Wavelet | ||
177 | |||
178 | /* this are the current codec types I want to implement */ | ||
179 | /* -> type value in structure */ | ||
180 | #define CODEC_TYPE_NONE 0 | ||
181 | #define CODEC_TYPE_L64702 1 | ||
182 | #define CODEC_TYPE_ZR36050 2 | ||
183 | #define CODEC_TYPE_ZR36016 3 | ||
184 | #define CODEC_TYPE_ZR36060 4 | ||
185 | |||
186 | /* the type of data may be enhanced by future implementations (data-fn.'s) */ | ||
187 | /* -> used in command */ | ||
188 | #define CODEC_G_STATUS 0x0000 /* codec status (query only) */ | ||
189 | #define CODEC_S_CODEC_MODE 0x0001 /* codec mode (baseline JPEG, MPEG1,... */ | ||
190 | #define CODEC_G_CODEC_MODE 0x8001 | ||
191 | #define CODEC_S_VFE 0x0002 /* additional video frontend setup */ | ||
192 | #define CODEC_G_VFE 0x8002 | ||
193 | #define CODEC_S_MMAP 0x0003 /* MMAP setup (if available) */ | ||
194 | |||
195 | #define CODEC_S_JPEG_TDS_BYTE 0x0010 /* target data size in bytes */ | ||
196 | #define CODEC_G_JPEG_TDS_BYTE 0x8010 | ||
197 | #define CODEC_S_JPEG_SCALE 0x0011 /* scaling factor for quant. tables */ | ||
198 | #define CODEC_G_JPEG_SCALE 0x8011 | ||
199 | #define CODEC_S_JPEG_HDT_DATA 0x0018 /* huffman-tables */ | ||
200 | #define CODEC_G_JPEG_HDT_DATA 0x8018 | ||
201 | #define CODEC_S_JPEG_QDT_DATA 0x0019 /* quantizing-tables */ | ||
202 | #define CODEC_G_JPEG_QDT_DATA 0x8019 | ||
203 | #define CODEC_S_JPEG_APP_DATA 0x001A /* APP marker */ | ||
204 | #define CODEC_G_JPEG_APP_DATA 0x801A | ||
205 | #define CODEC_S_JPEG_COM_DATA 0x001B /* COM marker */ | ||
206 | #define CODEC_G_JPEG_COM_DATA 0x801B | ||
207 | |||
208 | #define CODEC_S_PRIVATE 0x1000 /* "private" commands start here */ | ||
209 | #define CODEC_G_PRIVATE 0x9000 | ||
210 | |||
211 | #define CODEC_G_FLAG 0x8000 /* this is how 'get' is detected */ | ||
212 | |||
213 | /* types of transfer, directly user space or a kernel buffer (image-fn.'s) */ | ||
214 | /* -> used in get_image, put_image */ | ||
215 | #define CODEC_TRANSFER_KERNEL 0 /* use "memcopy" */ | ||
216 | #define CODEC_TRANSFER_USER 1 /* use "to/from_user" */ | ||
217 | |||
218 | |||
219 | /* ========================= */ | ||
220 | /* the structures itself ... */ | ||
221 | /* ========================= */ | ||
222 | |||
223 | struct vfe_polarity { | ||
224 | unsigned int vsync_pol:1; | ||
225 | unsigned int hsync_pol:1; | ||
226 | unsigned int field_pol:1; | ||
227 | unsigned int blank_pol:1; | ||
228 | unsigned int subimg_pol:1; | ||
229 | unsigned int poe_pol:1; | ||
230 | unsigned int pvalid_pol:1; | ||
231 | unsigned int vclk_pol:1; | ||
232 | }; | ||
233 | |||
234 | struct vfe_settings { | ||
235 | __u32 x, y; /* Offsets into image */ | ||
236 | __u32 width, height; /* Area to capture */ | ||
237 | __u16 decimation; /* Decimation divider */ | ||
238 | __u16 flags; /* Flags for capture */ | ||
239 | __u16 quality; /* quality of the video */ | ||
240 | }; | ||
241 | |||
242 | struct tvnorm { | ||
243 | u16 Wt, Wa, HStart, HSyncStart, Ht, Ha, VStart; | ||
244 | }; | ||
245 | |||
246 | struct jpeg_com_marker { | ||
247 | int len; /* number of usable bytes in data */ | ||
248 | char data[60]; | ||
249 | }; | ||
250 | |||
251 | struct jpeg_app_marker { | ||
252 | int appn; /* number app segment */ | ||
253 | int len; /* number of usable bytes in data */ | ||
254 | char data[60]; | ||
255 | }; | ||
256 | |||
257 | struct videocodec { | ||
258 | struct module *owner; | ||
259 | /* -- filled in by slave device during register -- */ | ||
260 | char name[32]; | ||
261 | unsigned long magic; /* may be used for client<->master attaching */ | ||
262 | unsigned long flags; /* functionality flags */ | ||
263 | unsigned int type; /* codec type */ | ||
264 | |||
265 | /* -- these is filled in later during master device attach -- */ | ||
266 | |||
267 | struct videocodec_master *master_data; | ||
268 | |||
269 | /* -- these are filled in by the slave device during register -- */ | ||
270 | |||
271 | void *data; /* private slave data */ | ||
272 | |||
273 | /* attach/detach client functions (indirect call) */ | ||
274 | int (*setup) (struct videocodec * codec); | ||
275 | int (*unset) (struct videocodec * codec); | ||
276 | |||
277 | /* main functions, every client needs them for sure! */ | ||
278 | // set compression or decompression (or freeze, stop, standby, etc) | ||
279 | int (*set_mode) (struct videocodec * codec, | ||
280 | int mode); | ||
281 | // setup picture size and norm (for the codec's video frontend) | ||
282 | int (*set_video) (struct videocodec * codec, | ||
283 | struct tvnorm * norm, | ||
284 | struct vfe_settings * cap, | ||
285 | struct vfe_polarity * pol); | ||
286 | // other control commands, also mmap setup etc. | ||
287 | int (*control) (struct videocodec * codec, | ||
288 | int type, | ||
289 | int size, | ||
290 | void *data); | ||
291 | |||
292 | /* additional setup/query/processing (may be NULL pointer) */ | ||
293 | // interrupt setup / handling (for irq's delivered by master) | ||
294 | int (*setup_interrupt) (struct videocodec * codec, | ||
295 | long mode); | ||
296 | int (*handle_interrupt) (struct videocodec * codec, | ||
297 | int source, | ||
298 | long flag); | ||
299 | // picture interface (if any) | ||
300 | long (*put_image) (struct videocodec * codec, | ||
301 | int tr_type, | ||
302 | int block, | ||
303 | long *fr_num, | ||
304 | long *flag, | ||
305 | long size, | ||
306 | void *buf); | ||
307 | long (*get_image) (struct videocodec * codec, | ||
308 | int tr_type, | ||
309 | int block, | ||
310 | long *fr_num, | ||
311 | long *flag, | ||
312 | long size, | ||
313 | void *buf); | ||
314 | }; | ||
315 | |||
316 | struct videocodec_master { | ||
317 | /* -- filled in by master device for registration -- */ | ||
318 | char name[32]; | ||
319 | unsigned long magic; /* may be used for client<->master attaching */ | ||
320 | unsigned long flags; /* functionality flags */ | ||
321 | unsigned int type; /* master type */ | ||
322 | |||
323 | void *data; /* private master data */ | ||
324 | |||
325 | __u32(*readreg) (struct videocodec * codec, | ||
326 | __u16 reg); | ||
327 | void (*writereg) (struct videocodec * codec, | ||
328 | __u16 reg, | ||
329 | __u32 value); | ||
330 | }; | ||
331 | |||
332 | |||
333 | /* ================================================= */ | ||
334 | /* function prototypes of the master/slave interface */ | ||
335 | /* ================================================= */ | ||
336 | |||
337 | /* attach and detach commands for the master */ | ||
338 | // * master structure needs to be kmalloc'ed before calling attach | ||
339 | // and free'd after calling detach | ||
340 | // * returns pointer on success, NULL on failure | ||
341 | extern struct videocodec *videocodec_attach(struct videocodec_master *); | ||
342 | // * 0 on success, <0 (errno) on failure | ||
343 | extern int videocodec_detach(struct videocodec *); | ||
344 | |||
345 | /* register and unregister commands for the slaves */ | ||
346 | // * 0 on success, <0 (errno) on failure | ||
347 | extern int videocodec_register(const struct videocodec *); | ||
348 | // * 0 on success, <0 (errno) on failure | ||
349 | extern int videocodec_unregister(const struct videocodec *); | ||
350 | |||
351 | /* the other calls are directly done via the videocodec structure! */ | ||
352 | |||
353 | #endif /*ifndef __LINUX_VIDEOCODEC_H */ | ||
diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h deleted file mode 100644 index ca2754a3cd63..000000000000 --- a/drivers/media/video/zoran/zoran.h +++ /dev/null | |||
@@ -1,403 +0,0 @@ | |||
1 | /* | ||
2 | * zoran - Iomega Buz driver | ||
3 | * | ||
4 | * Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de> | ||
5 | * | ||
6 | * based on | ||
7 | * | ||
8 | * zoran.0.0.3 Copyright (C) 1998 Dave Perks <dperks@ibm.net> | ||
9 | * | ||
10 | * and | ||
11 | * | ||
12 | * bttv - Bt848 frame grabber driver | ||
13 | * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) | ||
14 | * & Marcus Metzler (mocm@thp.uni-koeln.de) | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or modify | ||
17 | * it under the terms of the GNU General Public License as published by | ||
18 | * the Free Software Foundation; either version 2 of the License, or | ||
19 | * (at your option) any later version. | ||
20 | * | ||
21 | * This program is distributed in the hope that it will be useful, | ||
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
24 | * GNU General Public License for more details. | ||
25 | * | ||
26 | * You should have received a copy of the GNU General Public License | ||
27 | * along with this program; if not, write to the Free Software | ||
28 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
29 | */ | ||
30 | |||
31 | #ifndef _BUZ_H_ | ||
32 | #define _BUZ_H_ | ||
33 | |||
34 | #include <media/v4l2-device.h> | ||
35 | |||
36 | struct zoran_sync { | ||
37 | unsigned long frame; /* number of buffer that has been free'd */ | ||
38 | unsigned long length; /* number of code bytes in buffer (capture only) */ | ||
39 | unsigned long seq; /* frame sequence number */ | ||
40 | struct timeval timestamp; /* timestamp */ | ||
41 | }; | ||
42 | |||
43 | |||
44 | #define ZORAN_NAME "ZORAN" /* name of the device */ | ||
45 | |||
46 | #define ZR_DEVNAME(zr) ((zr)->name) | ||
47 | |||
48 | #define BUZ_MAX_WIDTH (zr->timing->Wa) | ||
49 | #define BUZ_MAX_HEIGHT (zr->timing->Ha) | ||
50 | #define BUZ_MIN_WIDTH 32 /* never display less than 32 pixels */ | ||
51 | #define BUZ_MIN_HEIGHT 24 /* never display less than 24 rows */ | ||
52 | |||
53 | #define BUZ_NUM_STAT_COM 4 | ||
54 | #define BUZ_MASK_STAT_COM 3 | ||
55 | |||
56 | #define BUZ_MAX_FRAME 256 /* Must be a power of 2 */ | ||
57 | #define BUZ_MASK_FRAME 255 /* Must be BUZ_MAX_FRAME-1 */ | ||
58 | |||
59 | #define BUZ_MAX_INPUT 16 | ||
60 | |||
61 | #if VIDEO_MAX_FRAME <= 32 | ||
62 | # define V4L_MAX_FRAME 32 | ||
63 | #elif VIDEO_MAX_FRAME <= 64 | ||
64 | # define V4L_MAX_FRAME 64 | ||
65 | #else | ||
66 | # error "Too many video frame buffers to handle" | ||
67 | #endif | ||
68 | #define V4L_MASK_FRAME (V4L_MAX_FRAME - 1) | ||
69 | |||
70 | #define MAX_FRAME (BUZ_MAX_FRAME > VIDEO_MAX_FRAME ? BUZ_MAX_FRAME : VIDEO_MAX_FRAME) | ||
71 | |||
72 | #include "zr36057.h" | ||
73 | |||
74 | enum card_type { | ||
75 | UNKNOWN = -1, | ||
76 | |||
77 | /* Pinnacle/Miro */ | ||
78 | DC10_old, /* DC30 like */ | ||
79 | DC10_new, /* DC10plus like */ | ||
80 | DC10plus, | ||
81 | DC30, | ||
82 | DC30plus, | ||
83 | |||
84 | /* Linux Media Labs */ | ||
85 | LML33, | ||
86 | LML33R10, | ||
87 | |||
88 | /* Iomega */ | ||
89 | BUZ, | ||
90 | |||
91 | /* AverMedia */ | ||
92 | AVS6EYES, | ||
93 | |||
94 | /* total number of cards */ | ||
95 | NUM_CARDS | ||
96 | }; | ||
97 | |||
98 | enum zoran_codec_mode { | ||
99 | BUZ_MODE_IDLE, /* nothing going on */ | ||
100 | BUZ_MODE_MOTION_COMPRESS, /* grabbing frames */ | ||
101 | BUZ_MODE_MOTION_DECOMPRESS, /* playing frames */ | ||
102 | BUZ_MODE_STILL_COMPRESS, /* still frame conversion */ | ||
103 | BUZ_MODE_STILL_DECOMPRESS /* still frame conversion */ | ||
104 | }; | ||
105 | |||
106 | enum zoran_buffer_state { | ||
107 | BUZ_STATE_USER, /* buffer is owned by application */ | ||
108 | BUZ_STATE_PEND, /* buffer is queued in pend[] ready to feed to I/O */ | ||
109 | BUZ_STATE_DMA, /* buffer is queued in dma[] for I/O */ | ||
110 | BUZ_STATE_DONE /* buffer is ready to return to application */ | ||
111 | }; | ||
112 | |||
113 | enum zoran_map_mode { | ||
114 | ZORAN_MAP_MODE_RAW, | ||
115 | ZORAN_MAP_MODE_JPG_REC, | ||
116 | #define ZORAN_MAP_MODE_JPG ZORAN_MAP_MODE_JPG_REC | ||
117 | ZORAN_MAP_MODE_JPG_PLAY, | ||
118 | }; | ||
119 | |||
120 | enum gpio_type { | ||
121 | ZR_GPIO_JPEG_SLEEP = 0, | ||
122 | ZR_GPIO_JPEG_RESET, | ||
123 | ZR_GPIO_JPEG_FRAME, | ||
124 | ZR_GPIO_VID_DIR, | ||
125 | ZR_GPIO_VID_EN, | ||
126 | ZR_GPIO_VID_RESET, | ||
127 | ZR_GPIO_CLK_SEL1, | ||
128 | ZR_GPIO_CLK_SEL2, | ||
129 | ZR_GPIO_MAX, | ||
130 | }; | ||
131 | |||
132 | enum gpcs_type { | ||
133 | GPCS_JPEG_RESET = 0, | ||
134 | GPCS_JPEG_START, | ||
135 | GPCS_MAX, | ||
136 | }; | ||
137 | |||
138 | struct zoran_format { | ||
139 | char *name; | ||
140 | __u32 fourcc; | ||
141 | int colorspace; | ||
142 | int depth; | ||
143 | __u32 flags; | ||
144 | __u32 vfespfr; | ||
145 | }; | ||
146 | /* flags */ | ||
147 | #define ZORAN_FORMAT_COMPRESSED 1<<0 | ||
148 | #define ZORAN_FORMAT_OVERLAY 1<<1 | ||
149 | #define ZORAN_FORMAT_CAPTURE 1<<2 | ||
150 | #define ZORAN_FORMAT_PLAYBACK 1<<3 | ||
151 | |||
152 | /* overlay-settings */ | ||
153 | struct zoran_overlay_settings { | ||
154 | int is_set; | ||
155 | int x, y, width, height; /* position */ | ||
156 | int clipcount; /* position and number of clips */ | ||
157 | const struct zoran_format *format; /* overlay format */ | ||
158 | }; | ||
159 | |||
160 | /* v4l-capture settings */ | ||
161 | struct zoran_v4l_settings { | ||
162 | int width, height, bytesperline; /* capture size */ | ||
163 | const struct zoran_format *format; /* capture format */ | ||
164 | }; | ||
165 | |||
166 | /* jpg-capture/-playback settings */ | ||
167 | struct zoran_jpg_settings { | ||
168 | int decimation; /* this bit is used to set everything to default */ | ||
169 | int HorDcm, VerDcm, TmpDcm; /* capture decimation settings (TmpDcm=1 means both fields) */ | ||
170 | int field_per_buff, odd_even; /* field-settings (odd_even=1 (+TmpDcm=1) means top-field-first) */ | ||
171 | int img_x, img_y, img_width, img_height; /* crop settings (subframe capture) */ | ||
172 | struct v4l2_jpegcompression jpg_comp; /* JPEG-specific capture settings */ | ||
173 | }; | ||
174 | |||
175 | struct zoran_fh; | ||
176 | |||
177 | struct zoran_mapping { | ||
178 | struct zoran_fh *fh; | ||
179 | int count; | ||
180 | }; | ||
181 | |||
182 | struct zoran_buffer { | ||
183 | struct zoran_mapping *map; | ||
184 | enum zoran_buffer_state state; /* state: unused/pending/dma/done */ | ||
185 | struct zoran_sync bs; /* DONE: info to return to application */ | ||
186 | union { | ||
187 | struct { | ||
188 | __le32 *frag_tab; /* addresses of frag table */ | ||
189 | u32 frag_tab_bus; /* same value cached to save time in ISR */ | ||
190 | } jpg; | ||
191 | struct { | ||
192 | char *fbuffer; /* virtual address of frame buffer */ | ||
193 | unsigned long fbuffer_phys;/* physical address of frame buffer */ | ||
194 | unsigned long fbuffer_bus;/* bus address of frame buffer */ | ||
195 | } v4l; | ||
196 | }; | ||
197 | }; | ||
198 | |||
199 | enum zoran_lock_activity { | ||
200 | ZORAN_FREE, /* free for use */ | ||
201 | ZORAN_ACTIVE, /* active but unlocked */ | ||
202 | ZORAN_LOCKED, /* locked */ | ||
203 | }; | ||
204 | |||
205 | /* buffer collections */ | ||
206 | struct zoran_buffer_col { | ||
207 | enum zoran_lock_activity active; /* feature currently in use? */ | ||
208 | unsigned int num_buffers, buffer_size; | ||
209 | struct zoran_buffer buffer[MAX_FRAME]; /* buffers */ | ||
210 | u8 allocated; /* Flag if buffers are allocated */ | ||
211 | u8 need_contiguous; /* Flag if contiguous buffers are needed */ | ||
212 | /* only applies to jpg buffers, raw buffers are always contiguous */ | ||
213 | }; | ||
214 | |||
215 | struct zoran; | ||
216 | |||
217 | /* zoran_fh contains per-open() settings */ | ||
218 | struct zoran_fh { | ||
219 | struct zoran *zr; | ||
220 | |||
221 | enum zoran_map_mode map_mode; /* Flag which bufferset will map by next mmap() */ | ||
222 | |||
223 | struct zoran_overlay_settings overlay_settings; | ||
224 | u32 *overlay_mask; /* overlay mask */ | ||
225 | enum zoran_lock_activity overlay_active;/* feature currently in use? */ | ||
226 | |||
227 | struct zoran_buffer_col buffers; /* buffers' info */ | ||
228 | |||
229 | struct zoran_v4l_settings v4l_settings; /* structure with a lot of things to play with */ | ||
230 | struct zoran_jpg_settings jpg_settings; /* structure with a lot of things to play with */ | ||
231 | }; | ||
232 | |||
233 | struct card_info { | ||
234 | enum card_type type; | ||
235 | char name[32]; | ||
236 | const char *i2c_decoder; /* i2c decoder device */ | ||
237 | const unsigned short *addrs_decoder; | ||
238 | const char *i2c_encoder; /* i2c encoder device */ | ||
239 | const unsigned short *addrs_encoder; | ||
240 | u16 video_vfe, video_codec; /* videocodec types */ | ||
241 | u16 audio_chip; /* audio type */ | ||
242 | |||
243 | int inputs; /* number of video inputs */ | ||
244 | struct input { | ||
245 | int muxsel; | ||
246 | char name[32]; | ||
247 | } input[BUZ_MAX_INPUT]; | ||
248 | |||
249 | v4l2_std_id norms; | ||
250 | struct tvnorm *tvn[3]; /* supported TV norms */ | ||
251 | |||
252 | u32 jpeg_int; /* JPEG interrupt */ | ||
253 | u32 vsync_int; /* VSYNC interrupt */ | ||
254 | s8 gpio[ZR_GPIO_MAX]; | ||
255 | u8 gpcs[GPCS_MAX]; | ||
256 | |||
257 | struct vfe_polarity vfe_pol; | ||
258 | u8 gpio_pol[ZR_GPIO_MAX]; | ||
259 | |||
260 | /* is the /GWS line connected? */ | ||
261 | u8 gws_not_connected; | ||
262 | |||
263 | /* avs6eyes mux setting */ | ||
264 | u8 input_mux; | ||
265 | |||
266 | void (*init) (struct zoran * zr); | ||
267 | }; | ||
268 | |||
269 | struct zoran { | ||
270 | struct v4l2_device v4l2_dev; | ||
271 | struct video_device *video_dev; | ||
272 | |||
273 | struct i2c_adapter i2c_adapter; /* */ | ||
274 | struct i2c_algo_bit_data i2c_algo; /* */ | ||
275 | u32 i2cbr; | ||
276 | |||
277 | struct v4l2_subdev *decoder; /* video decoder sub-device */ | ||
278 | struct v4l2_subdev *encoder; /* video encoder sub-device */ | ||
279 | |||
280 | struct videocodec *codec; /* video codec */ | ||
281 | struct videocodec *vfe; /* video front end */ | ||
282 | |||
283 | struct mutex resource_lock; /* prevent evil stuff */ | ||
284 | struct mutex other_lock; /* please merge with above */ | ||
285 | |||
286 | u8 initialized; /* flag if zoran has been correctly initialized */ | ||
287 | int user; /* number of current users */ | ||
288 | struct card_info card; | ||
289 | struct tvnorm *timing; | ||
290 | |||
291 | unsigned short id; /* number of this device */ | ||
292 | char name[32]; /* name of this device */ | ||
293 | struct pci_dev *pci_dev; /* PCI device */ | ||
294 | unsigned char revision; /* revision of zr36057 */ | ||
295 | unsigned char __iomem *zr36057_mem;/* pointer to mapped IO memory */ | ||
296 | |||
297 | spinlock_t spinlock; /* Spinlock */ | ||
298 | |||
299 | /* Video for Linux parameters */ | ||
300 | int input; /* card's norm and input */ | ||
301 | v4l2_std_id norm; | ||
302 | |||
303 | /* Current buffer params */ | ||
304 | void *vbuf_base; | ||
305 | int vbuf_height, vbuf_width; | ||
306 | int vbuf_depth; | ||
307 | int vbuf_bytesperline; | ||
308 | |||
309 | struct zoran_overlay_settings overlay_settings; | ||
310 | u32 *overlay_mask; /* overlay mask */ | ||
311 | enum zoran_lock_activity overlay_active; /* feature currently in use? */ | ||
312 | |||
313 | wait_queue_head_t v4l_capq; | ||
314 | |||
315 | int v4l_overlay_active; /* Overlay grab is activated */ | ||
316 | int v4l_memgrab_active; /* Memory grab is activated */ | ||
317 | |||
318 | int v4l_grab_frame; /* Frame number being currently grabbed */ | ||
319 | #define NO_GRAB_ACTIVE (-1) | ||
320 | unsigned long v4l_grab_seq; /* Number of frames grabbed */ | ||
321 | struct zoran_v4l_settings v4l_settings; /* structure with a lot of things to play with */ | ||
322 | |||
323 | /* V4L grab queue of frames pending */ | ||
324 | unsigned long v4l_pend_head; | ||
325 | unsigned long v4l_pend_tail; | ||
326 | unsigned long v4l_sync_tail; | ||
327 | int v4l_pend[V4L_MAX_FRAME]; | ||
328 | struct zoran_buffer_col v4l_buffers; /* V4L buffers' info */ | ||
329 | |||
330 | /* Buz MJPEG parameters */ | ||
331 | enum zoran_codec_mode codec_mode; /* status of codec */ | ||
332 | struct zoran_jpg_settings jpg_settings; /* structure with a lot of things to play with */ | ||
333 | |||
334 | wait_queue_head_t jpg_capq; /* wait here for grab to finish */ | ||
335 | |||
336 | /* grab queue counts/indices, mask with BUZ_MASK_STAT_COM before using as index */ | ||
337 | /* (dma_head - dma_tail) is number active in DMA, must be <= BUZ_NUM_STAT_COM */ | ||
338 | /* (value & BUZ_MASK_STAT_COM) corresponds to index in stat_com table */ | ||
339 | unsigned long jpg_que_head; /* Index where to put next buffer which is queued */ | ||
340 | unsigned long jpg_dma_head; /* Index of next buffer which goes into stat_com */ | ||
341 | unsigned long jpg_dma_tail; /* Index of last buffer in stat_com */ | ||
342 | unsigned long jpg_que_tail; /* Index of last buffer in queue */ | ||
343 | unsigned long jpg_seq_num; /* count of frames since grab/play started */ | ||
344 | unsigned long jpg_err_seq; /* last seq_num before error */ | ||
345 | unsigned long jpg_err_shift; | ||
346 | unsigned long jpg_queued_num; /* count of frames queued since grab/play started */ | ||
347 | |||
348 | /* zr36057's code buffer table */ | ||
349 | __le32 *stat_com; /* stat_com[i] is indexed by dma_head/tail & BUZ_MASK_STAT_COM */ | ||
350 | |||
351 | /* (value & BUZ_MASK_FRAME) corresponds to index in pend[] queue */ | ||
352 | int jpg_pend[BUZ_MAX_FRAME]; | ||
353 | |||
354 | /* array indexed by frame number */ | ||
355 | struct zoran_buffer_col jpg_buffers; /* MJPEG buffers' info */ | ||
356 | |||
357 | /* Additional stuff for testing */ | ||
358 | #ifdef CONFIG_PROC_FS | ||
359 | struct proc_dir_entry *zoran_proc; | ||
360 | #else | ||
361 | void *zoran_proc; | ||
362 | #endif | ||
363 | int testing; | ||
364 | int jpeg_error; | ||
365 | int intr_counter_GIRQ1; | ||
366 | int intr_counter_GIRQ0; | ||
367 | int intr_counter_CodRepIRQ; | ||
368 | int intr_counter_JPEGRepIRQ; | ||
369 | int field_counter; | ||
370 | int IRQ1_in; | ||
371 | int IRQ1_out; | ||
372 | int JPEG_in; | ||
373 | int JPEG_out; | ||
374 | int JPEG_0; | ||
375 | int JPEG_1; | ||
376 | int END_event_missed; | ||
377 | int JPEG_missed; | ||
378 | int JPEG_error; | ||
379 | int num_errors; | ||
380 | int JPEG_max_missed; | ||
381 | int JPEG_min_missed; | ||
382 | |||
383 | u32 last_isr; | ||
384 | unsigned long frame_num; | ||
385 | |||
386 | wait_queue_head_t test_q; | ||
387 | }; | ||
388 | |||
389 | static inline struct zoran *to_zoran(struct v4l2_device *v4l2_dev) | ||
390 | { | ||
391 | return container_of(v4l2_dev, struct zoran, v4l2_dev); | ||
392 | } | ||
393 | |||
394 | /* There was something called _ALPHA_BUZ that used the PCI address instead of | ||
395 | * the kernel iomapped address for btread/btwrite. */ | ||
396 | #define btwrite(dat,adr) writel((dat), zr->zr36057_mem+(adr)) | ||
397 | #define btread(adr) readl(zr->zr36057_mem+(adr)) | ||
398 | |||
399 | #define btand(dat,adr) btwrite((dat) & btread(adr), adr) | ||
400 | #define btor(dat,adr) btwrite((dat) | btread(adr), adr) | ||
401 | #define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr) | ||
402 | |||
403 | #endif | ||
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c deleted file mode 100644 index c3602d6cd48e..000000000000 --- a/drivers/media/video/zoran/zoran_card.c +++ /dev/null | |||
@@ -1,1524 +0,0 @@ | |||
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 card-specific data and detection | ||
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/delay.h> | ||
31 | |||
32 | #include <linux/types.h> | ||
33 | #include <linux/kernel.h> | ||
34 | #include <linux/module.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <linux/vmalloc.h> | ||
37 | #include <linux/slab.h> | ||
38 | |||
39 | #include <linux/proc_fs.h> | ||
40 | #include <linux/i2c.h> | ||
41 | #include <linux/i2c-algo-bit.h> | ||
42 | #include <linux/videodev2.h> | ||
43 | #include <linux/spinlock.h> | ||
44 | #include <linux/sem.h> | ||
45 | #include <linux/kmod.h> | ||
46 | #include <linux/wait.h> | ||
47 | |||
48 | #include <linux/pci.h> | ||
49 | #include <linux/interrupt.h> | ||
50 | #include <linux/mutex.h> | ||
51 | #include <linux/io.h> | ||
52 | #include <media/v4l2-common.h> | ||
53 | #include <media/bt819.h> | ||
54 | |||
55 | #include "videocodec.h" | ||
56 | #include "zoran.h" | ||
57 | #include "zoran_card.h" | ||
58 | #include "zoran_device.h" | ||
59 | #include "zoran_procfs.h" | ||
60 | |||
61 | extern const struct zoran_format zoran_formats[]; | ||
62 | |||
63 | static int card[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 }; | ||
64 | module_param_array(card, int, NULL, 0444); | ||
65 | MODULE_PARM_DESC(card, "Card type"); | ||
66 | |||
67 | /* | ||
68 | The video mem address of the video card. | ||
69 | The driver has a little database for some videocards | ||
70 | to determine it from there. If your video card is not in there | ||
71 | you have either to give it to the driver as a parameter | ||
72 | or set in in a VIDIOCSFBUF ioctl | ||
73 | */ | ||
74 | |||
75 | static unsigned long vidmem; /* default = 0 - Video memory base address */ | ||
76 | module_param(vidmem, ulong, 0444); | ||
77 | MODULE_PARM_DESC(vidmem, "Default video memory base address"); | ||
78 | |||
79 | /* | ||
80 | Default input and video norm at startup of the driver. | ||
81 | */ | ||
82 | |||
83 | static unsigned int default_input; /* default 0 = Composite, 1 = S-Video */ | ||
84 | module_param(default_input, uint, 0444); | ||
85 | MODULE_PARM_DESC(default_input, | ||
86 | "Default input (0=Composite, 1=S-Video, 2=Internal)"); | ||
87 | |||
88 | static int default_mux = 1; /* 6 Eyes input selection */ | ||
89 | module_param(default_mux, int, 0644); | ||
90 | MODULE_PARM_DESC(default_mux, | ||
91 | "Default 6 Eyes mux setting (Input selection)"); | ||
92 | |||
93 | static int default_norm; /* default 0 = PAL, 1 = NTSC 2 = SECAM */ | ||
94 | module_param(default_norm, int, 0444); | ||
95 | MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)"); | ||
96 | |||
97 | /* /dev/videoN, -1 for autodetect */ | ||
98 | static int video_nr[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 }; | ||
99 | module_param_array(video_nr, int, NULL, 0444); | ||
100 | MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)"); | ||
101 | |||
102 | int v4l_nbufs = 4; | ||
103 | int v4l_bufsize = 864; /* Everybody should be able to work with this setting */ | ||
104 | module_param(v4l_nbufs, int, 0644); | ||
105 | MODULE_PARM_DESC(v4l_nbufs, "Maximum number of V4L buffers to use"); | ||
106 | module_param(v4l_bufsize, int, 0644); | ||
107 | MODULE_PARM_DESC(v4l_bufsize, "Maximum size per V4L buffer (in kB)"); | ||
108 | |||
109 | int jpg_nbufs = 32; | ||
110 | int jpg_bufsize = 512; /* max size for 100% quality full-PAL frame */ | ||
111 | module_param(jpg_nbufs, int, 0644); | ||
112 | MODULE_PARM_DESC(jpg_nbufs, "Maximum number of JPG buffers to use"); | ||
113 | module_param(jpg_bufsize, int, 0644); | ||
114 | MODULE_PARM_DESC(jpg_bufsize, "Maximum size per JPG buffer (in kB)"); | ||
115 | |||
116 | int pass_through = 0; /* 1=Pass through TV signal when device is not used */ | ||
117 | /* 0=Show color bar when device is not used (LML33: only if lml33dpath=1) */ | ||
118 | module_param(pass_through, int, 0644); | ||
119 | MODULE_PARM_DESC(pass_through, | ||
120 | "Pass TV signal through to TV-out when idling"); | ||
121 | |||
122 | int zr36067_debug = 1; | ||
123 | module_param_named(debug, zr36067_debug, int, 0644); | ||
124 | MODULE_PARM_DESC(debug, "Debug level (0-5)"); | ||
125 | |||
126 | #define ZORAN_VERSION "0.10.1" | ||
127 | |||
128 | MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver"); | ||
129 | MODULE_AUTHOR("Serguei Miridonov"); | ||
130 | MODULE_LICENSE("GPL"); | ||
131 | MODULE_VERSION(ZORAN_VERSION); | ||
132 | |||
133 | #define ZR_DEVICE(subven, subdev, data) { \ | ||
134 | .vendor = PCI_VENDOR_ID_ZORAN, .device = PCI_DEVICE_ID_ZORAN_36057, \ | ||
135 | .subvendor = (subven), .subdevice = (subdev), .driver_data = (data) } | ||
136 | |||
137 | static struct pci_device_id zr36067_pci_tbl[] = { | ||
138 | ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC10PLUS, DC10plus), | ||
139 | ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC30PLUS, DC30plus), | ||
140 | ZR_DEVICE(PCI_VENDOR_ID_ELECTRONICDESIGNGMBH, PCI_DEVICE_ID_LML_33R10, LML33R10), | ||
141 | ZR_DEVICE(PCI_VENDOR_ID_IOMEGA, PCI_DEVICE_ID_IOMEGA_BUZ, BUZ), | ||
142 | ZR_DEVICE(PCI_ANY_ID, PCI_ANY_ID, NUM_CARDS), | ||
143 | {0} | ||
144 | }; | ||
145 | MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl); | ||
146 | |||
147 | static unsigned int zoran_num; /* number of cards found */ | ||
148 | |||
149 | /* videocodec bus functions ZR36060 */ | ||
150 | static u32 | ||
151 | zr36060_read (struct videocodec *codec, | ||
152 | u16 reg) | ||
153 | { | ||
154 | struct zoran *zr = (struct zoran *) codec->master_data->data; | ||
155 | __u32 data; | ||
156 | |||
157 | if (post_office_wait(zr) | ||
158 | || post_office_write(zr, 0, 1, reg >> 8) | ||
159 | || post_office_write(zr, 0, 2, reg & 0xff)) { | ||
160 | return -1; | ||
161 | } | ||
162 | |||
163 | data = post_office_read(zr, 0, 3) & 0xff; | ||
164 | return data; | ||
165 | } | ||
166 | |||
167 | static void | ||
168 | zr36060_write (struct videocodec *codec, | ||
169 | u16 reg, | ||
170 | u32 val) | ||
171 | { | ||
172 | struct zoran *zr = (struct zoran *) codec->master_data->data; | ||
173 | |||
174 | if (post_office_wait(zr) | ||
175 | || post_office_write(zr, 0, 1, reg >> 8) | ||
176 | || post_office_write(zr, 0, 2, reg & 0xff)) { | ||
177 | return; | ||
178 | } | ||
179 | |||
180 | post_office_write(zr, 0, 3, val & 0xff); | ||
181 | } | ||
182 | |||
183 | /* videocodec bus functions ZR36050 */ | ||
184 | static u32 | ||
185 | zr36050_read (struct videocodec *codec, | ||
186 | u16 reg) | ||
187 | { | ||
188 | struct zoran *zr = (struct zoran *) codec->master_data->data; | ||
189 | __u32 data; | ||
190 | |||
191 | if (post_office_wait(zr) | ||
192 | || post_office_write(zr, 1, 0, reg >> 2)) { // reg. HIGHBYTES | ||
193 | return -1; | ||
194 | } | ||
195 | |||
196 | data = post_office_read(zr, 0, reg & 0x03) & 0xff; // reg. LOWBYTES + read | ||
197 | return data; | ||
198 | } | ||
199 | |||
200 | static void | ||
201 | zr36050_write (struct videocodec *codec, | ||
202 | u16 reg, | ||
203 | u32 val) | ||
204 | { | ||
205 | struct zoran *zr = (struct zoran *) codec->master_data->data; | ||
206 | |||
207 | if (post_office_wait(zr) | ||
208 | || post_office_write(zr, 1, 0, reg >> 2)) { // reg. HIGHBYTES | ||
209 | return; | ||
210 | } | ||
211 | |||
212 | post_office_write(zr, 0, reg & 0x03, val & 0xff); // reg. LOWBYTES + wr. data | ||
213 | } | ||
214 | |||
215 | /* videocodec bus functions ZR36016 */ | ||
216 | static u32 | ||
217 | zr36016_read (struct videocodec *codec, | ||
218 | u16 reg) | ||
219 | { | ||
220 | struct zoran *zr = (struct zoran *) codec->master_data->data; | ||
221 | __u32 data; | ||
222 | |||
223 | if (post_office_wait(zr)) { | ||
224 | return -1; | ||
225 | } | ||
226 | |||
227 | data = post_office_read(zr, 2, reg & 0x03) & 0xff; // read | ||
228 | return data; | ||
229 | } | ||
230 | |||
231 | /* hack for in zoran_device.c */ | ||
232 | void | ||
233 | zr36016_write (struct videocodec *codec, | ||
234 | u16 reg, | ||
235 | u32 val) | ||
236 | { | ||
237 | struct zoran *zr = (struct zoran *) codec->master_data->data; | ||
238 | |||
239 | if (post_office_wait(zr)) { | ||
240 | return; | ||
241 | } | ||
242 | |||
243 | post_office_write(zr, 2, reg & 0x03, val & 0x0ff); // wr. data | ||
244 | } | ||
245 | |||
246 | /* | ||
247 | * Board specific information | ||
248 | */ | ||
249 | |||
250 | static void | ||
251 | dc10_init (struct zoran *zr) | ||
252 | { | ||
253 | dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__); | ||
254 | |||
255 | /* Pixel clock selection */ | ||
256 | GPIO(zr, 4, 0); | ||
257 | GPIO(zr, 5, 1); | ||
258 | /* Enable the video bus sync signals */ | ||
259 | GPIO(zr, 7, 0); | ||
260 | } | ||
261 | |||
262 | static void | ||
263 | dc10plus_init (struct zoran *zr) | ||
264 | { | ||
265 | dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__); | ||
266 | } | ||
267 | |||
268 | static void | ||
269 | buz_init (struct zoran *zr) | ||
270 | { | ||
271 | dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__); | ||
272 | |||
273 | /* some stuff from Iomega */ | ||
274 | pci_write_config_dword(zr->pci_dev, 0xfc, 0x90680f15); | ||
275 | pci_write_config_dword(zr->pci_dev, 0x0c, 0x00012020); | ||
276 | pci_write_config_dword(zr->pci_dev, 0xe8, 0xc0200000); | ||
277 | } | ||
278 | |||
279 | static void | ||
280 | lml33_init (struct zoran *zr) | ||
281 | { | ||
282 | dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__); | ||
283 | |||
284 | GPIO(zr, 2, 1); // Set Composite input/output | ||
285 | } | ||
286 | |||
287 | static void | ||
288 | avs6eyes_init (struct zoran *zr) | ||
289 | { | ||
290 | // AverMedia 6-Eyes original driver by Christer Weinigel | ||
291 | |||
292 | // Lifted straight from Christer's old driver and | ||
293 | // modified slightly by Martin Samuelsson. | ||
294 | |||
295 | int mux = default_mux; /* 1 = BT866, 7 = VID1 */ | ||
296 | |||
297 | GPIO(zr, 4, 1); /* Bt866 SLEEP on */ | ||
298 | udelay(2); | ||
299 | |||
300 | GPIO(zr, 0, 1); /* ZR36060 /RESET on */ | ||
301 | GPIO(zr, 1, 0); /* ZR36060 /SLEEP on */ | ||
302 | GPIO(zr, 2, mux & 1); /* MUX S0 */ | ||
303 | GPIO(zr, 3, 0); /* /FRAME on */ | ||
304 | GPIO(zr, 4, 0); /* Bt866 SLEEP off */ | ||
305 | GPIO(zr, 5, mux & 2); /* MUX S1 */ | ||
306 | GPIO(zr, 6, 0); /* ? */ | ||
307 | GPIO(zr, 7, mux & 4); /* MUX S2 */ | ||
308 | |||
309 | } | ||
310 | |||
311 | static char * | ||
312 | codecid_to_modulename (u16 codecid) | ||
313 | { | ||
314 | char *name = NULL; | ||
315 | |||
316 | switch (codecid) { | ||
317 | case CODEC_TYPE_ZR36060: | ||
318 | name = "zr36060"; | ||
319 | break; | ||
320 | case CODEC_TYPE_ZR36050: | ||
321 | name = "zr36050"; | ||
322 | break; | ||
323 | case CODEC_TYPE_ZR36016: | ||
324 | name = "zr36016"; | ||
325 | break; | ||
326 | } | ||
327 | |||
328 | return name; | ||
329 | } | ||
330 | |||
331 | // struct tvnorm { | ||
332 | // u16 Wt, Wa, HStart, HSyncStart, Ht, Ha, VStart; | ||
333 | // }; | ||
334 | |||
335 | static struct tvnorm f50sqpixel = { 944, 768, 83, 880, 625, 576, 16 }; | ||
336 | static struct tvnorm f60sqpixel = { 780, 640, 51, 716, 525, 480, 12 }; | ||
337 | static struct tvnorm f50ccir601 = { 864, 720, 75, 804, 625, 576, 18 }; | ||
338 | static struct tvnorm f60ccir601 = { 858, 720, 57, 788, 525, 480, 16 }; | ||
339 | |||
340 | static struct tvnorm f50ccir601_lml33 = { 864, 720, 75+34, 804, 625, 576, 18 }; | ||
341 | static struct tvnorm f60ccir601_lml33 = { 858, 720, 57+34, 788, 525, 480, 16 }; | ||
342 | |||
343 | /* The DC10 (57/16/50) uses VActive as HSync, so HStart must be 0 */ | ||
344 | static struct tvnorm f50sqpixel_dc10 = { 944, 768, 0, 880, 625, 576, 0 }; | ||
345 | static struct tvnorm f60sqpixel_dc10 = { 780, 640, 0, 716, 525, 480, 12 }; | ||
346 | |||
347 | /* FIXME: I cannot swap U and V in saa7114, so i do one | ||
348 | * pixel left shift in zoran (75 -> 74) | ||
349 | * (Maxim Yevtyushkin <max@linuxmedialabs.com>) */ | ||
350 | static struct tvnorm f50ccir601_lm33r10 = { 864, 720, 74+54, 804, 625, 576, 18 }; | ||
351 | static struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56+54, 788, 525, 480, 16 }; | ||
352 | |||
353 | /* FIXME: The ks0127 seem incapable of swapping U and V, too, which is why I | ||
354 | * copy Maxim's left shift hack for the 6 Eyes. | ||
355 | * | ||
356 | * Christer's driver used the unshifted norms, though... | ||
357 | * /Sam */ | ||
358 | static struct tvnorm f50ccir601_avs6eyes = { 864, 720, 74, 804, 625, 576, 18 }; | ||
359 | static struct tvnorm f60ccir601_avs6eyes = { 858, 720, 56, 788, 525, 480, 16 }; | ||
360 | |||
361 | static const unsigned short vpx3220_addrs[] = { 0x43, 0x47, I2C_CLIENT_END }; | ||
362 | static const unsigned short saa7110_addrs[] = { 0x4e, 0x4f, I2C_CLIENT_END }; | ||
363 | static const unsigned short saa7111_addrs[] = { 0x25, 0x24, I2C_CLIENT_END }; | ||
364 | static const unsigned short saa7114_addrs[] = { 0x21, 0x20, I2C_CLIENT_END }; | ||
365 | static const unsigned short adv717x_addrs[] = { 0x6a, 0x6b, 0x2a, 0x2b, I2C_CLIENT_END }; | ||
366 | static const unsigned short ks0127_addrs[] = { 0x6c, 0x6d, I2C_CLIENT_END }; | ||
367 | static const unsigned short saa7185_addrs[] = { 0x44, I2C_CLIENT_END }; | ||
368 | static const unsigned short bt819_addrs[] = { 0x45, I2C_CLIENT_END }; | ||
369 | static const unsigned short bt856_addrs[] = { 0x44, I2C_CLIENT_END }; | ||
370 | static const unsigned short bt866_addrs[] = { 0x44, I2C_CLIENT_END }; | ||
371 | |||
372 | static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { | ||
373 | { | ||
374 | .type = DC10_old, | ||
375 | .name = "DC10(old)", | ||
376 | .i2c_decoder = "vpx3220a", | ||
377 | .addrs_decoder = vpx3220_addrs, | ||
378 | .video_codec = CODEC_TYPE_ZR36050, | ||
379 | .video_vfe = CODEC_TYPE_ZR36016, | ||
380 | |||
381 | .inputs = 3, | ||
382 | .input = { | ||
383 | { 1, "Composite" }, | ||
384 | { 2, "S-Video" }, | ||
385 | { 0, "Internal/comp" } | ||
386 | }, | ||
387 | .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, | ||
388 | .tvn = { | ||
389 | &f50sqpixel_dc10, | ||
390 | &f60sqpixel_dc10, | ||
391 | &f50sqpixel_dc10 | ||
392 | }, | ||
393 | .jpeg_int = 0, | ||
394 | .vsync_int = ZR36057_ISR_GIRQ1, | ||
395 | .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 }, | ||
396 | .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 }, | ||
397 | .gpcs = { -1, 0 }, | ||
398 | .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
399 | .gws_not_connected = 0, | ||
400 | .input_mux = 0, | ||
401 | .init = &dc10_init, | ||
402 | }, { | ||
403 | .type = DC10_new, | ||
404 | .name = "DC10(new)", | ||
405 | .i2c_decoder = "saa7110", | ||
406 | .addrs_decoder = saa7110_addrs, | ||
407 | .i2c_encoder = "adv7175", | ||
408 | .addrs_encoder = adv717x_addrs, | ||
409 | .video_codec = CODEC_TYPE_ZR36060, | ||
410 | |||
411 | .inputs = 3, | ||
412 | .input = { | ||
413 | { 0, "Composite" }, | ||
414 | { 7, "S-Video" }, | ||
415 | { 5, "Internal/comp" } | ||
416 | }, | ||
417 | .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, | ||
418 | .tvn = { | ||
419 | &f50sqpixel, | ||
420 | &f60sqpixel, | ||
421 | &f50sqpixel}, | ||
422 | .jpeg_int = ZR36057_ISR_GIRQ0, | ||
423 | .vsync_int = ZR36057_ISR_GIRQ1, | ||
424 | .gpio = { 3, 0, 6, 1, 2, -1, 4, 5 }, | ||
425 | .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
426 | .gpcs = { -1, 1}, | ||
427 | .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 }, | ||
428 | .gws_not_connected = 0, | ||
429 | .input_mux = 0, | ||
430 | .init = &dc10plus_init, | ||
431 | }, { | ||
432 | .type = DC10plus, | ||
433 | .name = "DC10plus", | ||
434 | .i2c_decoder = "saa7110", | ||
435 | .addrs_decoder = saa7110_addrs, | ||
436 | .i2c_encoder = "adv7175", | ||
437 | .addrs_encoder = adv717x_addrs, | ||
438 | .video_codec = CODEC_TYPE_ZR36060, | ||
439 | |||
440 | .inputs = 3, | ||
441 | .input = { | ||
442 | { 0, "Composite" }, | ||
443 | { 7, "S-Video" }, | ||
444 | { 5, "Internal/comp" } | ||
445 | }, | ||
446 | .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, | ||
447 | .tvn = { | ||
448 | &f50sqpixel, | ||
449 | &f60sqpixel, | ||
450 | &f50sqpixel | ||
451 | }, | ||
452 | .jpeg_int = ZR36057_ISR_GIRQ0, | ||
453 | .vsync_int = ZR36057_ISR_GIRQ1, | ||
454 | .gpio = { 3, 0, 6, 1, 2, -1, 4, 5 }, | ||
455 | .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
456 | .gpcs = { -1, 1 }, | ||
457 | .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 }, | ||
458 | .gws_not_connected = 0, | ||
459 | .input_mux = 0, | ||
460 | .init = &dc10plus_init, | ||
461 | }, { | ||
462 | .type = DC30, | ||
463 | .name = "DC30", | ||
464 | .i2c_decoder = "vpx3220a", | ||
465 | .addrs_decoder = vpx3220_addrs, | ||
466 | .i2c_encoder = "adv7175", | ||
467 | .addrs_encoder = adv717x_addrs, | ||
468 | .video_codec = CODEC_TYPE_ZR36050, | ||
469 | .video_vfe = CODEC_TYPE_ZR36016, | ||
470 | |||
471 | .inputs = 3, | ||
472 | .input = { | ||
473 | { 1, "Composite" }, | ||
474 | { 2, "S-Video" }, | ||
475 | { 0, "Internal/comp" } | ||
476 | }, | ||
477 | .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, | ||
478 | .tvn = { | ||
479 | &f50sqpixel_dc10, | ||
480 | &f60sqpixel_dc10, | ||
481 | &f50sqpixel_dc10 | ||
482 | }, | ||
483 | .jpeg_int = 0, | ||
484 | .vsync_int = ZR36057_ISR_GIRQ1, | ||
485 | .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 }, | ||
486 | .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 }, | ||
487 | .gpcs = { -1, 0 }, | ||
488 | .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
489 | .gws_not_connected = 0, | ||
490 | .input_mux = 0, | ||
491 | .init = &dc10_init, | ||
492 | }, { | ||
493 | .type = DC30plus, | ||
494 | .name = "DC30plus", | ||
495 | .i2c_decoder = "vpx3220a", | ||
496 | .addrs_decoder = vpx3220_addrs, | ||
497 | .i2c_encoder = "adv7175", | ||
498 | .addrs_encoder = adv717x_addrs, | ||
499 | .video_codec = CODEC_TYPE_ZR36050, | ||
500 | .video_vfe = CODEC_TYPE_ZR36016, | ||
501 | |||
502 | .inputs = 3, | ||
503 | .input = { | ||
504 | { 1, "Composite" }, | ||
505 | { 2, "S-Video" }, | ||
506 | { 0, "Internal/comp" } | ||
507 | }, | ||
508 | .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, | ||
509 | .tvn = { | ||
510 | &f50sqpixel_dc10, | ||
511 | &f60sqpixel_dc10, | ||
512 | &f50sqpixel_dc10 | ||
513 | }, | ||
514 | .jpeg_int = 0, | ||
515 | .vsync_int = ZR36057_ISR_GIRQ1, | ||
516 | .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 }, | ||
517 | .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 }, | ||
518 | .gpcs = { -1, 0 }, | ||
519 | .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
520 | .gws_not_connected = 0, | ||
521 | .input_mux = 0, | ||
522 | .init = &dc10_init, | ||
523 | }, { | ||
524 | .type = LML33, | ||
525 | .name = "LML33", | ||
526 | .i2c_decoder = "bt819a", | ||
527 | .addrs_decoder = bt819_addrs, | ||
528 | .i2c_encoder = "bt856", | ||
529 | .addrs_encoder = bt856_addrs, | ||
530 | .video_codec = CODEC_TYPE_ZR36060, | ||
531 | |||
532 | .inputs = 2, | ||
533 | .input = { | ||
534 | { 0, "Composite" }, | ||
535 | { 7, "S-Video" } | ||
536 | }, | ||
537 | .norms = V4L2_STD_NTSC|V4L2_STD_PAL, | ||
538 | .tvn = { | ||
539 | &f50ccir601_lml33, | ||
540 | &f60ccir601_lml33, | ||
541 | NULL | ||
542 | }, | ||
543 | .jpeg_int = ZR36057_ISR_GIRQ1, | ||
544 | .vsync_int = ZR36057_ISR_GIRQ0, | ||
545 | .gpio = { 1, -1, 3, 5, 7, -1, -1, -1 }, | ||
546 | .gpio_pol = { 0, 0, 0, 0, 1, 0, 0, 0 }, | ||
547 | .gpcs = { 3, 1 }, | ||
548 | .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, | ||
549 | .gws_not_connected = 1, | ||
550 | .input_mux = 0, | ||
551 | .init = &lml33_init, | ||
552 | }, { | ||
553 | .type = LML33R10, | ||
554 | .name = "LML33R10", | ||
555 | .i2c_decoder = "saa7114", | ||
556 | .addrs_decoder = saa7114_addrs, | ||
557 | .i2c_encoder = "adv7170", | ||
558 | .addrs_encoder = adv717x_addrs, | ||
559 | .video_codec = CODEC_TYPE_ZR36060, | ||
560 | |||
561 | .inputs = 2, | ||
562 | .input = { | ||
563 | { 0, "Composite" }, | ||
564 | { 7, "S-Video" } | ||
565 | }, | ||
566 | .norms = V4L2_STD_NTSC|V4L2_STD_PAL, | ||
567 | .tvn = { | ||
568 | &f50ccir601_lm33r10, | ||
569 | &f60ccir601_lm33r10, | ||
570 | NULL | ||
571 | }, | ||
572 | .jpeg_int = ZR36057_ISR_GIRQ1, | ||
573 | .vsync_int = ZR36057_ISR_GIRQ0, | ||
574 | .gpio = { 1, -1, 3, 5, 7, -1, -1, -1 }, | ||
575 | .gpio_pol = { 0, 0, 0, 0, 1, 0, 0, 0 }, | ||
576 | .gpcs = { 3, 1 }, | ||
577 | .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, | ||
578 | .gws_not_connected = 1, | ||
579 | .input_mux = 0, | ||
580 | .init = &lml33_init, | ||
581 | }, { | ||
582 | .type = BUZ, | ||
583 | .name = "Buz", | ||
584 | .i2c_decoder = "saa7111", | ||
585 | .addrs_decoder = saa7111_addrs, | ||
586 | .i2c_encoder = "saa7185", | ||
587 | .addrs_encoder = saa7185_addrs, | ||
588 | .video_codec = CODEC_TYPE_ZR36060, | ||
589 | |||
590 | .inputs = 2, | ||
591 | .input = { | ||
592 | { 3, "Composite" }, | ||
593 | { 7, "S-Video" } | ||
594 | }, | ||
595 | .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, | ||
596 | .tvn = { | ||
597 | &f50ccir601, | ||
598 | &f60ccir601, | ||
599 | &f50ccir601 | ||
600 | }, | ||
601 | .jpeg_int = ZR36057_ISR_GIRQ1, | ||
602 | .vsync_int = ZR36057_ISR_GIRQ0, | ||
603 | .gpio = { 1, -1, 3, -1, -1, -1, -1, -1 }, | ||
604 | .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
605 | .gpcs = { 3, 1 }, | ||
606 | .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, | ||
607 | .gws_not_connected = 1, | ||
608 | .input_mux = 0, | ||
609 | .init = &buz_init, | ||
610 | }, { | ||
611 | .type = AVS6EYES, | ||
612 | .name = "6-Eyes", | ||
613 | /* AverMedia chose not to brand the 6-Eyes. Thus it | ||
614 | can't be autodetected, and requires card=x. */ | ||
615 | .i2c_decoder = "ks0127", | ||
616 | .addrs_decoder = ks0127_addrs, | ||
617 | .i2c_encoder = "bt866", | ||
618 | .addrs_encoder = bt866_addrs, | ||
619 | .video_codec = CODEC_TYPE_ZR36060, | ||
620 | |||
621 | .inputs = 10, | ||
622 | .input = { | ||
623 | { 0, "Composite 1" }, | ||
624 | { 1, "Composite 2" }, | ||
625 | { 2, "Composite 3" }, | ||
626 | { 4, "Composite 4" }, | ||
627 | { 5, "Composite 5" }, | ||
628 | { 6, "Composite 6" }, | ||
629 | { 8, "S-Video 1" }, | ||
630 | { 9, "S-Video 2" }, | ||
631 | {10, "S-Video 3" }, | ||
632 | {15, "YCbCr" } | ||
633 | }, | ||
634 | .norms = V4L2_STD_NTSC|V4L2_STD_PAL, | ||
635 | .tvn = { | ||
636 | &f50ccir601_avs6eyes, | ||
637 | &f60ccir601_avs6eyes, | ||
638 | NULL | ||
639 | }, | ||
640 | .jpeg_int = ZR36057_ISR_GIRQ1, | ||
641 | .vsync_int = ZR36057_ISR_GIRQ0, | ||
642 | .gpio = { 1, 0, 3, -1, -1, -1, -1, -1 },// Validity unknown /Sam | ||
643 | .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, // Validity unknown /Sam | ||
644 | .gpcs = { 3, 1 }, // Validity unknown /Sam | ||
645 | .vfe_pol = { 1, 0, 0, 0, 0, 1, 0, 0 }, // Validity unknown /Sam | ||
646 | .gws_not_connected = 1, | ||
647 | .input_mux = 1, | ||
648 | .init = &avs6eyes_init, | ||
649 | } | ||
650 | |||
651 | }; | ||
652 | |||
653 | /* | ||
654 | * I2C functions | ||
655 | */ | ||
656 | /* software I2C functions */ | ||
657 | static int | ||
658 | zoran_i2c_getsda (void *data) | ||
659 | { | ||
660 | struct zoran *zr = (struct zoran *) data; | ||
661 | |||
662 | return (btread(ZR36057_I2CBR) >> 1) & 1; | ||
663 | } | ||
664 | |||
665 | static int | ||
666 | zoran_i2c_getscl (void *data) | ||
667 | { | ||
668 | struct zoran *zr = (struct zoran *) data; | ||
669 | |||
670 | return btread(ZR36057_I2CBR) & 1; | ||
671 | } | ||
672 | |||
673 | static void | ||
674 | zoran_i2c_setsda (void *data, | ||
675 | int state) | ||
676 | { | ||
677 | struct zoran *zr = (struct zoran *) data; | ||
678 | |||
679 | if (state) | ||
680 | zr->i2cbr |= 2; | ||
681 | else | ||
682 | zr->i2cbr &= ~2; | ||
683 | btwrite(zr->i2cbr, ZR36057_I2CBR); | ||
684 | } | ||
685 | |||
686 | static void | ||
687 | zoran_i2c_setscl (void *data, | ||
688 | int state) | ||
689 | { | ||
690 | struct zoran *zr = (struct zoran *) data; | ||
691 | |||
692 | if (state) | ||
693 | zr->i2cbr |= 1; | ||
694 | else | ||
695 | zr->i2cbr &= ~1; | ||
696 | btwrite(zr->i2cbr, ZR36057_I2CBR); | ||
697 | } | ||
698 | |||
699 | static const struct i2c_algo_bit_data zoran_i2c_bit_data_template = { | ||
700 | .setsda = zoran_i2c_setsda, | ||
701 | .setscl = zoran_i2c_setscl, | ||
702 | .getsda = zoran_i2c_getsda, | ||
703 | .getscl = zoran_i2c_getscl, | ||
704 | .udelay = 10, | ||
705 | .timeout = 100, | ||
706 | }; | ||
707 | |||
708 | static int | ||
709 | zoran_register_i2c (struct zoran *zr) | ||
710 | { | ||
711 | memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template, | ||
712 | sizeof(struct i2c_algo_bit_data)); | ||
713 | zr->i2c_algo.data = zr; | ||
714 | strlcpy(zr->i2c_adapter.name, ZR_DEVNAME(zr), | ||
715 | sizeof(zr->i2c_adapter.name)); | ||
716 | i2c_set_adapdata(&zr->i2c_adapter, &zr->v4l2_dev); | ||
717 | zr->i2c_adapter.algo_data = &zr->i2c_algo; | ||
718 | zr->i2c_adapter.dev.parent = &zr->pci_dev->dev; | ||
719 | return i2c_bit_add_bus(&zr->i2c_adapter); | ||
720 | } | ||
721 | |||
722 | static void | ||
723 | zoran_unregister_i2c (struct zoran *zr) | ||
724 | { | ||
725 | i2c_del_adapter(&zr->i2c_adapter); | ||
726 | } | ||
727 | |||
728 | /* Check a zoran_params struct for correctness, insert default params */ | ||
729 | |||
730 | int | ||
731 | zoran_check_jpg_settings (struct zoran *zr, | ||
732 | struct zoran_jpg_settings *settings, | ||
733 | int try) | ||
734 | { | ||
735 | int err = 0, err0 = 0; | ||
736 | |||
737 | dprintk(4, | ||
738 | KERN_DEBUG | ||
739 | "%s: %s - dec: %d, Hdcm: %d, Vdcm: %d, Tdcm: %d\n", | ||
740 | ZR_DEVNAME(zr), __func__, settings->decimation, settings->HorDcm, | ||
741 | settings->VerDcm, settings->TmpDcm); | ||
742 | dprintk(4, | ||
743 | KERN_DEBUG | ||
744 | "%s: %s - x: %d, y: %d, w: %d, y: %d\n", | ||
745 | ZR_DEVNAME(zr), __func__, settings->img_x, settings->img_y, | ||
746 | settings->img_width, settings->img_height); | ||
747 | /* Check decimation, set default values for decimation = 1, 2, 4 */ | ||
748 | switch (settings->decimation) { | ||
749 | case 1: | ||
750 | |||
751 | settings->HorDcm = 1; | ||
752 | settings->VerDcm = 1; | ||
753 | settings->TmpDcm = 1; | ||
754 | settings->field_per_buff = 2; | ||
755 | settings->img_x = 0; | ||
756 | settings->img_y = 0; | ||
757 | settings->img_width = BUZ_MAX_WIDTH; | ||
758 | settings->img_height = BUZ_MAX_HEIGHT / 2; | ||
759 | break; | ||
760 | case 2: | ||
761 | |||
762 | settings->HorDcm = 2; | ||
763 | settings->VerDcm = 1; | ||
764 | settings->TmpDcm = 2; | ||
765 | settings->field_per_buff = 1; | ||
766 | settings->img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0; | ||
767 | settings->img_y = 0; | ||
768 | settings->img_width = | ||
769 | (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH; | ||
770 | settings->img_height = BUZ_MAX_HEIGHT / 2; | ||
771 | break; | ||
772 | case 4: | ||
773 | |||
774 | if (zr->card.type == DC10_new) { | ||
775 | dprintk(1, | ||
776 | KERN_DEBUG | ||
777 | "%s: %s - HDec by 4 is not supported on the DC10\n", | ||
778 | ZR_DEVNAME(zr), __func__); | ||
779 | err0++; | ||
780 | break; | ||
781 | } | ||
782 | |||
783 | settings->HorDcm = 4; | ||
784 | settings->VerDcm = 2; | ||
785 | settings->TmpDcm = 2; | ||
786 | settings->field_per_buff = 1; | ||
787 | settings->img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0; | ||
788 | settings->img_y = 0; | ||
789 | settings->img_width = | ||
790 | (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH; | ||
791 | settings->img_height = BUZ_MAX_HEIGHT / 2; | ||
792 | break; | ||
793 | case 0: | ||
794 | |||
795 | /* We have to check the data the user has set */ | ||
796 | |||
797 | if (settings->HorDcm != 1 && settings->HorDcm != 2 && | ||
798 | (zr->card.type == DC10_new || settings->HorDcm != 4)) { | ||
799 | settings->HorDcm = clamp(settings->HorDcm, 1, 2); | ||
800 | err0++; | ||
801 | } | ||
802 | if (settings->VerDcm != 1 && settings->VerDcm != 2) { | ||
803 | settings->VerDcm = clamp(settings->VerDcm, 1, 2); | ||
804 | err0++; | ||
805 | } | ||
806 | if (settings->TmpDcm != 1 && settings->TmpDcm != 2) { | ||
807 | settings->TmpDcm = clamp(settings->TmpDcm, 1, 2); | ||
808 | err0++; | ||
809 | } | ||
810 | if (settings->field_per_buff != 1 && | ||
811 | settings->field_per_buff != 2) { | ||
812 | settings->field_per_buff = clamp(settings->field_per_buff, 1, 2); | ||
813 | err0++; | ||
814 | } | ||
815 | if (settings->img_x < 0) { | ||
816 | settings->img_x = 0; | ||
817 | err0++; | ||
818 | } | ||
819 | if (settings->img_y < 0) { | ||
820 | settings->img_y = 0; | ||
821 | err0++; | ||
822 | } | ||
823 | if (settings->img_width < 0 || settings->img_width > BUZ_MAX_WIDTH) { | ||
824 | settings->img_width = clamp(settings->img_width, 0, (int)BUZ_MAX_WIDTH); | ||
825 | err0++; | ||
826 | } | ||
827 | if (settings->img_height < 0 || settings->img_height > BUZ_MAX_HEIGHT / 2) { | ||
828 | settings->img_height = clamp(settings->img_height, 0, BUZ_MAX_HEIGHT / 2); | ||
829 | err0++; | ||
830 | } | ||
831 | if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) { | ||
832 | settings->img_x = BUZ_MAX_WIDTH - settings->img_width; | ||
833 | err0++; | ||
834 | } | ||
835 | if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2) { | ||
836 | settings->img_y = BUZ_MAX_HEIGHT / 2 - settings->img_height; | ||
837 | err0++; | ||
838 | } | ||
839 | if (settings->img_width % (16 * settings->HorDcm) != 0) { | ||
840 | settings->img_width -= settings->img_width % (16 * settings->HorDcm); | ||
841 | if (settings->img_width == 0) | ||
842 | settings->img_width = 16 * settings->HorDcm; | ||
843 | err0++; | ||
844 | } | ||
845 | if (settings->img_height % (8 * settings->VerDcm) != 0) { | ||
846 | settings->img_height -= settings->img_height % (8 * settings->VerDcm); | ||
847 | if (settings->img_height == 0) | ||
848 | settings->img_height = 8 * settings->VerDcm; | ||
849 | err0++; | ||
850 | } | ||
851 | |||
852 | if (!try && err0) { | ||
853 | dprintk(1, | ||
854 | KERN_ERR | ||
855 | "%s: %s - error in params for decimation = 0\n", | ||
856 | ZR_DEVNAME(zr), __func__); | ||
857 | err++; | ||
858 | } | ||
859 | break; | ||
860 | default: | ||
861 | dprintk(1, | ||
862 | KERN_ERR | ||
863 | "%s: %s - decimation = %d, must be 0, 1, 2 or 4\n", | ||
864 | ZR_DEVNAME(zr), __func__, settings->decimation); | ||
865 | err++; | ||
866 | break; | ||
867 | } | ||
868 | |||
869 | if (settings->jpg_comp.quality > 100) | ||
870 | settings->jpg_comp.quality = 100; | ||
871 | if (settings->jpg_comp.quality < 5) | ||
872 | settings->jpg_comp.quality = 5; | ||
873 | if (settings->jpg_comp.APPn < 0) | ||
874 | settings->jpg_comp.APPn = 0; | ||
875 | if (settings->jpg_comp.APPn > 15) | ||
876 | settings->jpg_comp.APPn = 15; | ||
877 | if (settings->jpg_comp.APP_len < 0) | ||
878 | settings->jpg_comp.APP_len = 0; | ||
879 | if (settings->jpg_comp.APP_len > 60) | ||
880 | settings->jpg_comp.APP_len = 60; | ||
881 | if (settings->jpg_comp.COM_len < 0) | ||
882 | settings->jpg_comp.COM_len = 0; | ||
883 | if (settings->jpg_comp.COM_len > 60) | ||
884 | settings->jpg_comp.COM_len = 60; | ||
885 | if (err) | ||
886 | return -EINVAL; | ||
887 | return 0; | ||
888 | } | ||
889 | |||
890 | void | ||
891 | zoran_open_init_params (struct zoran *zr) | ||
892 | { | ||
893 | int i; | ||
894 | |||
895 | /* User must explicitly set a window */ | ||
896 | zr->overlay_settings.is_set = 0; | ||
897 | zr->overlay_mask = NULL; | ||
898 | zr->overlay_active = ZORAN_FREE; | ||
899 | |||
900 | zr->v4l_memgrab_active = 0; | ||
901 | zr->v4l_overlay_active = 0; | ||
902 | zr->v4l_grab_frame = NO_GRAB_ACTIVE; | ||
903 | zr->v4l_grab_seq = 0; | ||
904 | zr->v4l_settings.width = 192; | ||
905 | zr->v4l_settings.height = 144; | ||
906 | zr->v4l_settings.format = &zoran_formats[7]; /* YUY2 - YUV-4:2:2 packed */ | ||
907 | zr->v4l_settings.bytesperline = | ||
908 | zr->v4l_settings.width * | ||
909 | ((zr->v4l_settings.format->depth + 7) / 8); | ||
910 | |||
911 | /* DMA ring stuff for V4L */ | ||
912 | zr->v4l_pend_tail = 0; | ||
913 | zr->v4l_pend_head = 0; | ||
914 | zr->v4l_sync_tail = 0; | ||
915 | zr->v4l_buffers.active = ZORAN_FREE; | ||
916 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { | ||
917 | zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */ | ||
918 | } | ||
919 | zr->v4l_buffers.allocated = 0; | ||
920 | |||
921 | for (i = 0; i < BUZ_MAX_FRAME; i++) { | ||
922 | zr->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */ | ||
923 | } | ||
924 | zr->jpg_buffers.active = ZORAN_FREE; | ||
925 | zr->jpg_buffers.allocated = 0; | ||
926 | /* Set necessary params and call zoran_check_jpg_settings to set the defaults */ | ||
927 | zr->jpg_settings.decimation = 1; | ||
928 | zr->jpg_settings.jpg_comp.quality = 50; /* default compression factor 8 */ | ||
929 | if (zr->card.type != BUZ) | ||
930 | zr->jpg_settings.odd_even = 1; | ||
931 | else | ||
932 | zr->jpg_settings.odd_even = 0; | ||
933 | zr->jpg_settings.jpg_comp.APPn = 0; | ||
934 | zr->jpg_settings.jpg_comp.APP_len = 0; /* No APPn marker */ | ||
935 | memset(zr->jpg_settings.jpg_comp.APP_data, 0, | ||
936 | sizeof(zr->jpg_settings.jpg_comp.APP_data)); | ||
937 | zr->jpg_settings.jpg_comp.COM_len = 0; /* No COM marker */ | ||
938 | memset(zr->jpg_settings.jpg_comp.COM_data, 0, | ||
939 | sizeof(zr->jpg_settings.jpg_comp.COM_data)); | ||
940 | zr->jpg_settings.jpg_comp.jpeg_markers = | ||
941 | V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT; | ||
942 | i = zoran_check_jpg_settings(zr, &zr->jpg_settings, 0); | ||
943 | if (i) | ||
944 | dprintk(1, KERN_ERR "%s: %s internal error\n", | ||
945 | ZR_DEVNAME(zr), __func__); | ||
946 | |||
947 | clear_interrupt_counters(zr); | ||
948 | zr->testing = 0; | ||
949 | } | ||
950 | |||
951 | static void __devinit | ||
952 | test_interrupts (struct zoran *zr) | ||
953 | { | ||
954 | DEFINE_WAIT(wait); | ||
955 | int timeout, icr; | ||
956 | |||
957 | clear_interrupt_counters(zr); | ||
958 | |||
959 | zr->testing = 1; | ||
960 | icr = btread(ZR36057_ICR); | ||
961 | btwrite(0x78000000 | ZR36057_ICR_IntPinEn, ZR36057_ICR); | ||
962 | prepare_to_wait(&zr->test_q, &wait, TASK_INTERRUPTIBLE); | ||
963 | timeout = schedule_timeout(HZ); | ||
964 | finish_wait(&zr->test_q, &wait); | ||
965 | btwrite(0, ZR36057_ICR); | ||
966 | btwrite(0x78000000, ZR36057_ISR); | ||
967 | zr->testing = 0; | ||
968 | dprintk(5, KERN_INFO "%s: Testing interrupts...\n", ZR_DEVNAME(zr)); | ||
969 | if (timeout) { | ||
970 | dprintk(1, ": time spent: %d\n", 1 * HZ - timeout); | ||
971 | } | ||
972 | if (zr36067_debug > 1) | ||
973 | print_interrupts(zr); | ||
974 | btwrite(icr, ZR36057_ICR); | ||
975 | } | ||
976 | |||
977 | static int __devinit | ||
978 | zr36057_init (struct zoran *zr) | ||
979 | { | ||
980 | int j, err; | ||
981 | |||
982 | dprintk(1, | ||
983 | KERN_INFO | ||
984 | "%s: %s - initializing card[%d], zr=%p\n", | ||
985 | ZR_DEVNAME(zr), __func__, zr->id, zr); | ||
986 | |||
987 | /* default setup of all parameters which will persist between opens */ | ||
988 | zr->user = 0; | ||
989 | |||
990 | init_waitqueue_head(&zr->v4l_capq); | ||
991 | init_waitqueue_head(&zr->jpg_capq); | ||
992 | init_waitqueue_head(&zr->test_q); | ||
993 | zr->jpg_buffers.allocated = 0; | ||
994 | zr->v4l_buffers.allocated = 0; | ||
995 | |||
996 | zr->vbuf_base = (void *) vidmem; | ||
997 | zr->vbuf_width = 0; | ||
998 | zr->vbuf_height = 0; | ||
999 | zr->vbuf_depth = 0; | ||
1000 | zr->vbuf_bytesperline = 0; | ||
1001 | |||
1002 | /* Avoid nonsense settings from user for default input/norm */ | ||
1003 | if (default_norm < 0 || default_norm > 2) | ||
1004 | default_norm = 0; | ||
1005 | if (default_norm == 0) { | ||
1006 | zr->norm = V4L2_STD_PAL; | ||
1007 | zr->timing = zr->card.tvn[0]; | ||
1008 | } else if (default_norm == 1) { | ||
1009 | zr->norm = V4L2_STD_NTSC; | ||
1010 | zr->timing = zr->card.tvn[1]; | ||
1011 | } else { | ||
1012 | zr->norm = V4L2_STD_SECAM; | ||
1013 | zr->timing = zr->card.tvn[2]; | ||
1014 | } | ||
1015 | if (zr->timing == NULL) { | ||
1016 | dprintk(1, | ||
1017 | KERN_WARNING | ||
1018 | "%s: %s - default TV standard not supported by hardware. PAL will be used.\n", | ||
1019 | ZR_DEVNAME(zr), __func__); | ||
1020 | zr->norm = V4L2_STD_PAL; | ||
1021 | zr->timing = zr->card.tvn[0]; | ||
1022 | } | ||
1023 | |||
1024 | if (default_input > zr->card.inputs-1) { | ||
1025 | dprintk(1, | ||
1026 | KERN_WARNING | ||
1027 | "%s: default_input value %d out of range (0-%d)\n", | ||
1028 | ZR_DEVNAME(zr), default_input, zr->card.inputs-1); | ||
1029 | default_input = 0; | ||
1030 | } | ||
1031 | zr->input = default_input; | ||
1032 | |||
1033 | /* default setup (will be repeated at every open) */ | ||
1034 | zoran_open_init_params(zr); | ||
1035 | |||
1036 | /* allocate memory *before* doing anything to the hardware | ||
1037 | * in case allocation fails */ | ||
1038 | zr->stat_com = kzalloc(BUZ_NUM_STAT_COM * 4, GFP_KERNEL); | ||
1039 | zr->video_dev = video_device_alloc(); | ||
1040 | if (!zr->stat_com || !zr->video_dev) { | ||
1041 | dprintk(1, | ||
1042 | KERN_ERR | ||
1043 | "%s: %s - kmalloc (STAT_COM) failed\n", | ||
1044 | ZR_DEVNAME(zr), __func__); | ||
1045 | err = -ENOMEM; | ||
1046 | goto exit_free; | ||
1047 | } | ||
1048 | for (j = 0; j < BUZ_NUM_STAT_COM; j++) { | ||
1049 | zr->stat_com[j] = cpu_to_le32(1); /* mark as unavailable to zr36057 */ | ||
1050 | } | ||
1051 | |||
1052 | /* | ||
1053 | * Now add the template and register the device unit. | ||
1054 | */ | ||
1055 | memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template)); | ||
1056 | zr->video_dev->parent = &zr->pci_dev->dev; | ||
1057 | strcpy(zr->video_dev->name, ZR_DEVNAME(zr)); | ||
1058 | err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]); | ||
1059 | if (err < 0) | ||
1060 | goto exit_free; | ||
1061 | video_set_drvdata(zr->video_dev, zr); | ||
1062 | |||
1063 | zoran_init_hardware(zr); | ||
1064 | if (zr36067_debug > 2) | ||
1065 | detect_guest_activity(zr); | ||
1066 | test_interrupts(zr); | ||
1067 | if (!pass_through) { | ||
1068 | decoder_call(zr, video, s_stream, 0); | ||
1069 | encoder_call(zr, video, s_routing, 2, 0, 0); | ||
1070 | } | ||
1071 | |||
1072 | zr->zoran_proc = NULL; | ||
1073 | zr->initialized = 1; | ||
1074 | return 0; | ||
1075 | |||
1076 | exit_free: | ||
1077 | kfree(zr->stat_com); | ||
1078 | kfree(zr->video_dev); | ||
1079 | return err; | ||
1080 | } | ||
1081 | |||
1082 | static void __devexit zoran_remove(struct pci_dev *pdev) | ||
1083 | { | ||
1084 | struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); | ||
1085 | struct zoran *zr = to_zoran(v4l2_dev); | ||
1086 | |||
1087 | if (!zr->initialized) | ||
1088 | goto exit_free; | ||
1089 | |||
1090 | /* unregister videocodec bus */ | ||
1091 | if (zr->codec) { | ||
1092 | struct videocodec_master *master = zr->codec->master_data; | ||
1093 | |||
1094 | videocodec_detach(zr->codec); | ||
1095 | kfree(master); | ||
1096 | } | ||
1097 | if (zr->vfe) { | ||
1098 | struct videocodec_master *master = zr->vfe->master_data; | ||
1099 | |||
1100 | videocodec_detach(zr->vfe); | ||
1101 | kfree(master); | ||
1102 | } | ||
1103 | |||
1104 | /* unregister i2c bus */ | ||
1105 | zoran_unregister_i2c(zr); | ||
1106 | /* disable PCI bus-mastering */ | ||
1107 | zoran_set_pci_master(zr, 0); | ||
1108 | /* put chip into reset */ | ||
1109 | btwrite(0, ZR36057_SPGPPCR); | ||
1110 | free_irq(zr->pci_dev->irq, zr); | ||
1111 | /* unmap and free memory */ | ||
1112 | kfree(zr->stat_com); | ||
1113 | zoran_proc_cleanup(zr); | ||
1114 | iounmap(zr->zr36057_mem); | ||
1115 | pci_disable_device(zr->pci_dev); | ||
1116 | video_unregister_device(zr->video_dev); | ||
1117 | exit_free: | ||
1118 | v4l2_device_unregister(&zr->v4l2_dev); | ||
1119 | kfree(zr); | ||
1120 | } | ||
1121 | |||
1122 | void | ||
1123 | zoran_vdev_release (struct video_device *vdev) | ||
1124 | { | ||
1125 | kfree(vdev); | ||
1126 | } | ||
1127 | |||
1128 | static struct videocodec_master * __devinit | ||
1129 | zoran_setup_videocodec (struct zoran *zr, | ||
1130 | int type) | ||
1131 | { | ||
1132 | struct videocodec_master *m = NULL; | ||
1133 | |||
1134 | m = kmalloc(sizeof(struct videocodec_master), GFP_KERNEL); | ||
1135 | if (!m) { | ||
1136 | dprintk(1, KERN_ERR "%s: %s - no memory\n", | ||
1137 | ZR_DEVNAME(zr), __func__); | ||
1138 | return m; | ||
1139 | } | ||
1140 | |||
1141 | /* magic and type are unused for master struct. Makes sense only at | ||
1142 | codec structs. | ||
1143 | In the past, .type were initialized to the old V4L1 .hardware | ||
1144 | value, as VID_HARDWARE_ZR36067 | ||
1145 | */ | ||
1146 | m->magic = 0L; | ||
1147 | m->type = 0; | ||
1148 | |||
1149 | m->flags = CODEC_FLAG_ENCODER | CODEC_FLAG_DECODER; | ||
1150 | strlcpy(m->name, ZR_DEVNAME(zr), sizeof(m->name)); | ||
1151 | m->data = zr; | ||
1152 | |||
1153 | switch (type) | ||
1154 | { | ||
1155 | case CODEC_TYPE_ZR36060: | ||
1156 | m->readreg = zr36060_read; | ||
1157 | m->writereg = zr36060_write; | ||
1158 | m->flags |= CODEC_FLAG_JPEG | CODEC_FLAG_VFE; | ||
1159 | break; | ||
1160 | case CODEC_TYPE_ZR36050: | ||
1161 | m->readreg = zr36050_read; | ||
1162 | m->writereg = zr36050_write; | ||
1163 | m->flags |= CODEC_FLAG_JPEG; | ||
1164 | break; | ||
1165 | case CODEC_TYPE_ZR36016: | ||
1166 | m->readreg = zr36016_read; | ||
1167 | m->writereg = zr36016_write; | ||
1168 | m->flags |= CODEC_FLAG_VFE; | ||
1169 | break; | ||
1170 | } | ||
1171 | |||
1172 | return m; | ||
1173 | } | ||
1174 | |||
1175 | static void zoran_subdev_notify(struct v4l2_subdev *sd, unsigned int cmd, void *arg) | ||
1176 | { | ||
1177 | struct zoran *zr = to_zoran(sd->v4l2_dev); | ||
1178 | |||
1179 | /* Bt819 needs to reset its FIFO buffer using #FRST pin and | ||
1180 | LML33 card uses GPIO(7) for that. */ | ||
1181 | if (cmd == BT819_FIFO_RESET_LOW) | ||
1182 | GPIO(zr, 7, 0); | ||
1183 | else if (cmd == BT819_FIFO_RESET_HIGH) | ||
1184 | GPIO(zr, 7, 1); | ||
1185 | } | ||
1186 | |||
1187 | /* | ||
1188 | * Scan for a Buz card (actually for the PCI controller ZR36057), | ||
1189 | * request the irq and map the io memory | ||
1190 | */ | ||
1191 | static int __devinit zoran_probe(struct pci_dev *pdev, | ||
1192 | const struct pci_device_id *ent) | ||
1193 | { | ||
1194 | unsigned char latency, need_latency; | ||
1195 | struct zoran *zr; | ||
1196 | int result; | ||
1197 | struct videocodec_master *master_vfe = NULL; | ||
1198 | struct videocodec_master *master_codec = NULL; | ||
1199 | int card_num; | ||
1200 | char *codec_name, *vfe_name; | ||
1201 | unsigned int nr; | ||
1202 | |||
1203 | |||
1204 | nr = zoran_num++; | ||
1205 | if (nr >= BUZ_MAX) { | ||
1206 | dprintk(1, KERN_ERR "%s: driver limited to %d card(s) maximum\n", | ||
1207 | ZORAN_NAME, BUZ_MAX); | ||
1208 | return -ENOENT; | ||
1209 | } | ||
1210 | |||
1211 | zr = kzalloc(sizeof(struct zoran), GFP_KERNEL); | ||
1212 | if (!zr) { | ||
1213 | dprintk(1, KERN_ERR "%s: %s - kzalloc failed\n", | ||
1214 | ZORAN_NAME, __func__); | ||
1215 | return -ENOMEM; | ||
1216 | } | ||
1217 | zr->v4l2_dev.notify = zoran_subdev_notify; | ||
1218 | if (v4l2_device_register(&pdev->dev, &zr->v4l2_dev)) | ||
1219 | goto zr_free_mem; | ||
1220 | zr->pci_dev = pdev; | ||
1221 | zr->id = nr; | ||
1222 | snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id); | ||
1223 | spin_lock_init(&zr->spinlock); | ||
1224 | mutex_init(&zr->resource_lock); | ||
1225 | mutex_init(&zr->other_lock); | ||
1226 | if (pci_enable_device(pdev)) | ||
1227 | goto zr_unreg; | ||
1228 | zr->revision = zr->pci_dev->revision; | ||
1229 | |||
1230 | dprintk(1, | ||
1231 | KERN_INFO | ||
1232 | "%s: Zoran ZR360%c7 (rev %d), irq: %d, memory: 0x%08llx\n", | ||
1233 | ZR_DEVNAME(zr), zr->revision < 2 ? '5' : '6', zr->revision, | ||
1234 | zr->pci_dev->irq, (uint64_t)pci_resource_start(zr->pci_dev, 0)); | ||
1235 | if (zr->revision >= 2) { | ||
1236 | dprintk(1, | ||
1237 | KERN_INFO | ||
1238 | "%s: Subsystem vendor=0x%04x id=0x%04x\n", | ||
1239 | ZR_DEVNAME(zr), zr->pci_dev->subsystem_vendor, | ||
1240 | zr->pci_dev->subsystem_device); | ||
1241 | } | ||
1242 | |||
1243 | /* Use auto-detected card type? */ | ||
1244 | if (card[nr] == -1) { | ||
1245 | if (zr->revision < 2) { | ||
1246 | dprintk(1, | ||
1247 | KERN_ERR | ||
1248 | "%s: No card type specified, please use the card=X module parameter\n", | ||
1249 | ZR_DEVNAME(zr)); | ||
1250 | dprintk(1, | ||
1251 | KERN_ERR | ||
1252 | "%s: It is not possible to auto-detect ZR36057 based cards\n", | ||
1253 | ZR_DEVNAME(zr)); | ||
1254 | goto zr_unreg; | ||
1255 | } | ||
1256 | |||
1257 | card_num = ent->driver_data; | ||
1258 | if (card_num >= NUM_CARDS) { | ||
1259 | dprintk(1, | ||
1260 | KERN_ERR | ||
1261 | "%s: Unknown card, try specifying card=X module parameter\n", | ||
1262 | ZR_DEVNAME(zr)); | ||
1263 | goto zr_unreg; | ||
1264 | } | ||
1265 | dprintk(3, | ||
1266 | KERN_DEBUG | ||
1267 | "%s: %s() - card %s detected\n", | ||
1268 | ZR_DEVNAME(zr), __func__, zoran_cards[card_num].name); | ||
1269 | } else { | ||
1270 | card_num = card[nr]; | ||
1271 | if (card_num >= NUM_CARDS || card_num < 0) { | ||
1272 | dprintk(1, | ||
1273 | KERN_ERR | ||
1274 | "%s: User specified card type %d out of range (0 .. %d)\n", | ||
1275 | ZR_DEVNAME(zr), card_num, NUM_CARDS - 1); | ||
1276 | goto zr_unreg; | ||
1277 | } | ||
1278 | } | ||
1279 | |||
1280 | /* even though we make this a non pointer and thus | ||
1281 | * theoretically allow for making changes to this struct | ||
1282 | * on a per-individual card basis at runtime, this is | ||
1283 | * strongly discouraged. This structure is intended to | ||
1284 | * keep general card information, no settings or anything */ | ||
1285 | zr->card = zoran_cards[card_num]; | ||
1286 | snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), | ||
1287 | "%s[%u]", zr->card.name, zr->id); | ||
1288 | |||
1289 | zr->zr36057_mem = pci_ioremap_bar(zr->pci_dev, 0); | ||
1290 | if (!zr->zr36057_mem) { | ||
1291 | dprintk(1, KERN_ERR "%s: %s() - ioremap failed\n", | ||
1292 | ZR_DEVNAME(zr), __func__); | ||
1293 | goto zr_unreg; | ||
1294 | } | ||
1295 | |||
1296 | result = request_irq(zr->pci_dev->irq, zoran_irq, | ||
1297 | IRQF_SHARED | IRQF_DISABLED, ZR_DEVNAME(zr), zr); | ||
1298 | if (result < 0) { | ||
1299 | if (result == -EINVAL) { | ||
1300 | dprintk(1, | ||
1301 | KERN_ERR | ||
1302 | "%s: %s - bad irq number or handler\n", | ||
1303 | ZR_DEVNAME(zr), __func__); | ||
1304 | } else if (result == -EBUSY) { | ||
1305 | dprintk(1, | ||
1306 | KERN_ERR | ||
1307 | "%s: %s - IRQ %d busy, change your PnP config in BIOS\n", | ||
1308 | ZR_DEVNAME(zr), __func__, zr->pci_dev->irq); | ||
1309 | } else { | ||
1310 | dprintk(1, | ||
1311 | KERN_ERR | ||
1312 | "%s: %s - can't assign irq, error code %d\n", | ||
1313 | ZR_DEVNAME(zr), __func__, result); | ||
1314 | } | ||
1315 | goto zr_unmap; | ||
1316 | } | ||
1317 | |||
1318 | /* set PCI latency timer */ | ||
1319 | pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, | ||
1320 | &latency); | ||
1321 | need_latency = zr->revision > 1 ? 32 : 48; | ||
1322 | if (latency != need_latency) { | ||
1323 | dprintk(2, KERN_INFO "%s: Changing PCI latency from %d to %d\n", | ||
1324 | ZR_DEVNAME(zr), latency, need_latency); | ||
1325 | pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, | ||
1326 | need_latency); | ||
1327 | } | ||
1328 | |||
1329 | zr36057_restart(zr); | ||
1330 | /* i2c */ | ||
1331 | dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n", | ||
1332 | ZR_DEVNAME(zr)); | ||
1333 | |||
1334 | if (zoran_register_i2c(zr) < 0) { | ||
1335 | dprintk(1, KERN_ERR "%s: %s - can't initialize i2c bus\n", | ||
1336 | ZR_DEVNAME(zr), __func__); | ||
1337 | goto zr_free_irq; | ||
1338 | } | ||
1339 | |||
1340 | zr->decoder = v4l2_i2c_new_subdev(&zr->v4l2_dev, | ||
1341 | &zr->i2c_adapter, zr->card.i2c_decoder, | ||
1342 | 0, zr->card.addrs_decoder); | ||
1343 | |||
1344 | if (zr->card.i2c_encoder) | ||
1345 | zr->encoder = v4l2_i2c_new_subdev(&zr->v4l2_dev, | ||
1346 | &zr->i2c_adapter, zr->card.i2c_encoder, | ||
1347 | 0, zr->card.addrs_encoder); | ||
1348 | |||
1349 | dprintk(2, | ||
1350 | KERN_INFO "%s: Initializing videocodec bus...\n", | ||
1351 | ZR_DEVNAME(zr)); | ||
1352 | |||
1353 | if (zr->card.video_codec) { | ||
1354 | codec_name = codecid_to_modulename(zr->card.video_codec); | ||
1355 | if (codec_name) { | ||
1356 | result = request_module(codec_name); | ||
1357 | if (result) { | ||
1358 | dprintk(1, | ||
1359 | KERN_ERR | ||
1360 | "%s: failed to load modules %s: %d\n", | ||
1361 | ZR_DEVNAME(zr), codec_name, result); | ||
1362 | } | ||
1363 | } | ||
1364 | } | ||
1365 | if (zr->card.video_vfe) { | ||
1366 | vfe_name = codecid_to_modulename(zr->card.video_vfe); | ||
1367 | if (vfe_name) { | ||
1368 | result = request_module(vfe_name); | ||
1369 | if (result < 0) { | ||
1370 | dprintk(1, | ||
1371 | KERN_ERR | ||
1372 | "%s: failed to load modules %s: %d\n", | ||
1373 | ZR_DEVNAME(zr), vfe_name, result); | ||
1374 | } | ||
1375 | } | ||
1376 | } | ||
1377 | |||
1378 | /* reset JPEG codec */ | ||
1379 | jpeg_codec_sleep(zr, 1); | ||
1380 | jpeg_codec_reset(zr); | ||
1381 | /* video bus enabled */ | ||
1382 | /* display codec revision */ | ||
1383 | if (zr->card.video_codec != 0) { | ||
1384 | master_codec = zoran_setup_videocodec(zr, zr->card.video_codec); | ||
1385 | if (!master_codec) | ||
1386 | goto zr_unreg_i2c; | ||
1387 | zr->codec = videocodec_attach(master_codec); | ||
1388 | if (!zr->codec) { | ||
1389 | dprintk(1, KERN_ERR "%s: %s - no codec found\n", | ||
1390 | ZR_DEVNAME(zr), __func__); | ||
1391 | goto zr_free_codec; | ||
1392 | } | ||
1393 | if (zr->codec->type != zr->card.video_codec) { | ||
1394 | dprintk(1, KERN_ERR "%s: %s - wrong codec\n", | ||
1395 | ZR_DEVNAME(zr), __func__); | ||
1396 | goto zr_detach_codec; | ||
1397 | } | ||
1398 | } | ||
1399 | if (zr->card.video_vfe != 0) { | ||
1400 | master_vfe = zoran_setup_videocodec(zr, zr->card.video_vfe); | ||
1401 | if (!master_vfe) | ||
1402 | goto zr_detach_codec; | ||
1403 | zr->vfe = videocodec_attach(master_vfe); | ||
1404 | if (!zr->vfe) { | ||
1405 | dprintk(1, KERN_ERR "%s: %s - no VFE found\n", | ||
1406 | ZR_DEVNAME(zr), __func__); | ||
1407 | goto zr_free_vfe; | ||
1408 | } | ||
1409 | if (zr->vfe->type != zr->card.video_vfe) { | ||
1410 | dprintk(1, KERN_ERR "%s: %s = wrong VFE\n", | ||
1411 | ZR_DEVNAME(zr), __func__); | ||
1412 | goto zr_detach_vfe; | ||
1413 | } | ||
1414 | } | ||
1415 | |||
1416 | /* take care of Natoma chipset and a revision 1 zr36057 */ | ||
1417 | if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) { | ||
1418 | zr->jpg_buffers.need_contiguous = 1; | ||
1419 | dprintk(1, KERN_INFO | ||
1420 | "%s: ZR36057/Natoma bug, max. buffer size is 128K\n", | ||
1421 | ZR_DEVNAME(zr)); | ||
1422 | } | ||
1423 | |||
1424 | if (zr36057_init(zr) < 0) | ||
1425 | goto zr_detach_vfe; | ||
1426 | |||
1427 | zoran_proc_init(zr); | ||
1428 | |||
1429 | return 0; | ||
1430 | |||
1431 | zr_detach_vfe: | ||
1432 | videocodec_detach(zr->vfe); | ||
1433 | zr_free_vfe: | ||
1434 | kfree(master_vfe); | ||
1435 | zr_detach_codec: | ||
1436 | videocodec_detach(zr->codec); | ||
1437 | zr_free_codec: | ||
1438 | kfree(master_codec); | ||
1439 | zr_unreg_i2c: | ||
1440 | zoran_unregister_i2c(zr); | ||
1441 | zr_free_irq: | ||
1442 | btwrite(0, ZR36057_SPGPPCR); | ||
1443 | free_irq(zr->pci_dev->irq, zr); | ||
1444 | zr_unmap: | ||
1445 | iounmap(zr->zr36057_mem); | ||
1446 | zr_unreg: | ||
1447 | v4l2_device_unregister(&zr->v4l2_dev); | ||
1448 | zr_free_mem: | ||
1449 | kfree(zr); | ||
1450 | |||
1451 | return -ENODEV; | ||
1452 | } | ||
1453 | |||
1454 | static struct pci_driver zoran_driver = { | ||
1455 | .name = "zr36067", | ||
1456 | .id_table = zr36067_pci_tbl, | ||
1457 | .probe = zoran_probe, | ||
1458 | .remove = __devexit_p(zoran_remove), | ||
1459 | }; | ||
1460 | |||
1461 | static int __init zoran_init(void) | ||
1462 | { | ||
1463 | int res; | ||
1464 | |||
1465 | printk(KERN_INFO "Zoran MJPEG board driver version %s\n", | ||
1466 | ZORAN_VERSION); | ||
1467 | |||
1468 | /* check the parameters we have been given, adjust if necessary */ | ||
1469 | if (v4l_nbufs < 2) | ||
1470 | v4l_nbufs = 2; | ||
1471 | if (v4l_nbufs > VIDEO_MAX_FRAME) | ||
1472 | v4l_nbufs = VIDEO_MAX_FRAME; | ||
1473 | /* The user specfies the in KB, we want them in byte | ||
1474 | * (and page aligned) */ | ||
1475 | v4l_bufsize = PAGE_ALIGN(v4l_bufsize * 1024); | ||
1476 | if (v4l_bufsize < 32768) | ||
1477 | v4l_bufsize = 32768; | ||
1478 | /* 2 MB is arbitrary but sufficient for the maximum possible images */ | ||
1479 | if (v4l_bufsize > 2048 * 1024) | ||
1480 | v4l_bufsize = 2048 * 1024; | ||
1481 | if (jpg_nbufs < 4) | ||
1482 | jpg_nbufs = 4; | ||
1483 | if (jpg_nbufs > BUZ_MAX_FRAME) | ||
1484 | jpg_nbufs = BUZ_MAX_FRAME; | ||
1485 | jpg_bufsize = PAGE_ALIGN(jpg_bufsize * 1024); | ||
1486 | if (jpg_bufsize < 8192) | ||
1487 | jpg_bufsize = 8192; | ||
1488 | if (jpg_bufsize > (512 * 1024)) | ||
1489 | jpg_bufsize = 512 * 1024; | ||
1490 | /* Use parameter for vidmem or try to find a video card */ | ||
1491 | if (vidmem) { | ||
1492 | dprintk(1, | ||
1493 | KERN_INFO | ||
1494 | "%s: Using supplied video memory base address @ 0x%lx\n", | ||
1495 | ZORAN_NAME, vidmem); | ||
1496 | } | ||
1497 | |||
1498 | /* some mainboards might not do PCI-PCI data transfer well */ | ||
1499 | if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL|PCIPCI_ALIMAGIK)) { | ||
1500 | dprintk(1, | ||
1501 | KERN_WARNING | ||
1502 | "%s: chipset does not support reliable PCI-PCI DMA\n", | ||
1503 | ZORAN_NAME); | ||
1504 | } | ||
1505 | |||
1506 | res = pci_register_driver(&zoran_driver); | ||
1507 | if (res) { | ||
1508 | dprintk(1, | ||
1509 | KERN_ERR | ||
1510 | "%s: Unable to register ZR36057 driver\n", | ||
1511 | ZORAN_NAME); | ||
1512 | return res; | ||
1513 | } | ||
1514 | |||
1515 | return 0; | ||
1516 | } | ||
1517 | |||
1518 | static void __exit zoran_exit(void) | ||
1519 | { | ||
1520 | pci_unregister_driver(&zoran_driver); | ||
1521 | } | ||
1522 | |||
1523 | module_init(zoran_init); | ||
1524 | module_exit(zoran_exit); | ||
diff --git a/drivers/media/video/zoran/zoran_card.h b/drivers/media/video/zoran/zoran_card.h deleted file mode 100644 index 4936fead73e8..000000000000 --- a/drivers/media/video/zoran/zoran_card.h +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
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 card-specific data and detection | ||
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 | #ifndef __ZORAN_CARD_H__ | ||
31 | #define __ZORAN_CARD_H__ | ||
32 | |||
33 | extern int zr36067_debug; | ||
34 | |||
35 | #define dprintk(num, format, args...) \ | ||
36 | do { \ | ||
37 | if (zr36067_debug >= num) \ | ||
38 | printk(format, ##args); \ | ||
39 | } while (0) | ||
40 | |||
41 | /* Anybody who uses more than four? */ | ||
42 | #define BUZ_MAX 4 | ||
43 | |||
44 | extern struct video_device zoran_template; | ||
45 | |||
46 | extern int zoran_check_jpg_settings(struct zoran *zr, | ||
47 | struct zoran_jpg_settings *settings, | ||
48 | int try); | ||
49 | extern void zoran_open_init_params(struct zoran *zr); | ||
50 | extern void zoran_vdev_release(struct video_device *vdev); | ||
51 | |||
52 | void zr36016_write(struct videocodec *codec, u16 reg, u32 val); | ||
53 | |||
54 | #endif /* __ZORAN_CARD_H__ */ | ||
diff --git a/drivers/media/video/zoran/zoran_device.c b/drivers/media/video/zoran/zoran_device.c deleted file mode 100644 index a4cd504b8eee..000000000000 --- a/drivers/media/video/zoran/zoran_device.c +++ /dev/null | |||
@@ -1,1640 +0,0 @@ | |||
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/types.h> | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/vmalloc.h> | ||
34 | |||
35 | #include <linux/interrupt.h> | ||
36 | #include <linux/proc_fs.h> | ||
37 | #include <linux/i2c.h> | ||
38 | #include <linux/i2c-algo-bit.h> | ||
39 | #include <linux/videodev2.h> | ||
40 | #include <media/v4l2-common.h> | ||
41 | #include <linux/spinlock.h> | ||
42 | #include <linux/sem.h> | ||
43 | |||
44 | #include <linux/pci.h> | ||
45 | #include <linux/delay.h> | ||
46 | #include <linux/wait.h> | ||
47 | |||
48 | #include <asm/byteorder.h> | ||
49 | #include <asm/io.h> | ||
50 | |||
51 | #include "videocodec.h" | ||
52 | #include "zoran.h" | ||
53 | #include "zoran_device.h" | ||
54 | #include "zoran_card.h" | ||
55 | |||
56 | #define IRQ_MASK ( ZR36057_ISR_GIRQ0 | \ | ||
57 | ZR36057_ISR_GIRQ1 | \ | ||
58 | ZR36057_ISR_JPEGRepIRQ ) | ||
59 | |||
60 | static bool lml33dpath; /* default = 0 | ||
61 | * 1 will use digital path in capture | ||
62 | * mode instead of analog. It can be | ||
63 | * used for picture adjustments using | ||
64 | * tool like xawtv while watching image | ||
65 | * on TV monitor connected to the output. | ||
66 | * However, due to absence of 75 Ohm | ||
67 | * load on Bt819 input, there will be | ||
68 | * some image imperfections */ | ||
69 | |||
70 | module_param(lml33dpath, bool, 0644); | ||
71 | MODULE_PARM_DESC(lml33dpath, | ||
72 | "Use digital path capture mode (on LML33 cards)"); | ||
73 | |||
74 | static void | ||
75 | zr36057_init_vfe (struct zoran *zr); | ||
76 | |||
77 | /* | ||
78 | * General Purpose I/O and Guest bus access | ||
79 | */ | ||
80 | |||
81 | /* | ||
82 | * This is a bit tricky. When a board lacks a GPIO function, the corresponding | ||
83 | * GPIO bit number in the card_info structure is set to 0. | ||
84 | */ | ||
85 | |||
86 | void | ||
87 | GPIO (struct zoran *zr, | ||
88 | int bit, | ||
89 | unsigned int value) | ||
90 | { | ||
91 | u32 reg; | ||
92 | u32 mask; | ||
93 | |||
94 | /* Make sure the bit number is legal | ||
95 | * A bit number of -1 (lacking) gives a mask of 0, | ||
96 | * making it harmless */ | ||
97 | mask = (1 << (24 + bit)) & 0xff000000; | ||
98 | reg = btread(ZR36057_GPPGCR1) & ~mask; | ||
99 | if (value) { | ||
100 | reg |= mask; | ||
101 | } | ||
102 | btwrite(reg, ZR36057_GPPGCR1); | ||
103 | udelay(1); | ||
104 | } | ||
105 | |||
106 | /* | ||
107 | * Wait til post office is no longer busy | ||
108 | */ | ||
109 | |||
110 | int | ||
111 | post_office_wait (struct zoran *zr) | ||
112 | { | ||
113 | u32 por; | ||
114 | |||
115 | // while (((por = btread(ZR36057_POR)) & (ZR36057_POR_POPen | ZR36057_POR_POTime)) == ZR36057_POR_POPen) { | ||
116 | while ((por = btread(ZR36057_POR)) & ZR36057_POR_POPen) { | ||
117 | /* wait for something to happen */ | ||
118 | } | ||
119 | if ((por & ZR36057_POR_POTime) && !zr->card.gws_not_connected) { | ||
120 | /* In LML33/BUZ \GWS line is not connected, so it has always timeout set */ | ||
121 | dprintk(1, KERN_INFO "%s: pop timeout %08x\n", ZR_DEVNAME(zr), | ||
122 | por); | ||
123 | return -1; | ||
124 | } | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | int | ||
130 | post_office_write (struct zoran *zr, | ||
131 | unsigned int guest, | ||
132 | unsigned int reg, | ||
133 | unsigned int value) | ||
134 | { | ||
135 | u32 por; | ||
136 | |||
137 | por = | ||
138 | ZR36057_POR_PODir | ZR36057_POR_POTime | ((guest & 7) << 20) | | ||
139 | ((reg & 7) << 16) | (value & 0xFF); | ||
140 | btwrite(por, ZR36057_POR); | ||
141 | |||
142 | return post_office_wait(zr); | ||
143 | } | ||
144 | |||
145 | int | ||
146 | post_office_read (struct zoran *zr, | ||
147 | unsigned int guest, | ||
148 | unsigned int reg) | ||
149 | { | ||
150 | u32 por; | ||
151 | |||
152 | por = ZR36057_POR_POTime | ((guest & 7) << 20) | ((reg & 7) << 16); | ||
153 | btwrite(por, ZR36057_POR); | ||
154 | if (post_office_wait(zr) < 0) { | ||
155 | return -1; | ||
156 | } | ||
157 | |||
158 | return btread(ZR36057_POR) & 0xFF; | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * detect guests | ||
163 | */ | ||
164 | |||
165 | static void | ||
166 | dump_guests (struct zoran *zr) | ||
167 | { | ||
168 | if (zr36067_debug > 2) { | ||
169 | int i, guest[8]; | ||
170 | |||
171 | for (i = 1; i < 8; i++) { // Don't read jpeg codec here | ||
172 | guest[i] = post_office_read(zr, i, 0); | ||
173 | } | ||
174 | |||
175 | printk(KERN_INFO "%s: Guests:", ZR_DEVNAME(zr)); | ||
176 | |||
177 | for (i = 1; i < 8; i++) { | ||
178 | printk(" 0x%02x", guest[i]); | ||
179 | } | ||
180 | printk("\n"); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | static inline unsigned long | ||
185 | get_time (void) | ||
186 | { | ||
187 | struct timeval tv; | ||
188 | |||
189 | do_gettimeofday(&tv); | ||
190 | return (1000000 * tv.tv_sec + tv.tv_usec); | ||
191 | } | ||
192 | |||
193 | void | ||
194 | detect_guest_activity (struct zoran *zr) | ||
195 | { | ||
196 | int timeout, i, j, res, guest[8], guest0[8], change[8][3]; | ||
197 | unsigned long t0, t1; | ||
198 | |||
199 | dump_guests(zr); | ||
200 | printk(KERN_INFO "%s: Detecting guests activity, please wait...\n", | ||
201 | ZR_DEVNAME(zr)); | ||
202 | for (i = 1; i < 8; i++) { // Don't read jpeg codec here | ||
203 | guest0[i] = guest[i] = post_office_read(zr, i, 0); | ||
204 | } | ||
205 | |||
206 | timeout = 0; | ||
207 | j = 0; | ||
208 | t0 = get_time(); | ||
209 | while (timeout < 10000) { | ||
210 | udelay(10); | ||
211 | timeout++; | ||
212 | for (i = 1; (i < 8) && (j < 8); i++) { | ||
213 | res = post_office_read(zr, i, 0); | ||
214 | if (res != guest[i]) { | ||
215 | t1 = get_time(); | ||
216 | change[j][0] = (t1 - t0); | ||
217 | t0 = t1; | ||
218 | change[j][1] = i; | ||
219 | change[j][2] = res; | ||
220 | j++; | ||
221 | guest[i] = res; | ||
222 | } | ||
223 | } | ||
224 | if (j >= 8) | ||
225 | break; | ||
226 | } | ||
227 | printk(KERN_INFO "%s: Guests:", ZR_DEVNAME(zr)); | ||
228 | |||
229 | for (i = 1; i < 8; i++) { | ||
230 | printk(" 0x%02x", guest0[i]); | ||
231 | } | ||
232 | printk("\n"); | ||
233 | if (j == 0) { | ||
234 | printk(KERN_INFO "%s: No activity detected.\n", ZR_DEVNAME(zr)); | ||
235 | return; | ||
236 | } | ||
237 | for (i = 0; i < j; i++) { | ||
238 | printk(KERN_INFO "%s: %6d: %d => 0x%02x\n", ZR_DEVNAME(zr), | ||
239 | change[i][0], change[i][1], change[i][2]); | ||
240 | } | ||
241 | } | ||
242 | |||
243 | /* | ||
244 | * JPEG Codec access | ||
245 | */ | ||
246 | |||
247 | void | ||
248 | jpeg_codec_sleep (struct zoran *zr, | ||
249 | int sleep) | ||
250 | { | ||
251 | GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_SLEEP], !sleep); | ||
252 | if (!sleep) { | ||
253 | dprintk(3, | ||
254 | KERN_DEBUG | ||
255 | "%s: jpeg_codec_sleep() - wake GPIO=0x%08x\n", | ||
256 | ZR_DEVNAME(zr), btread(ZR36057_GPPGCR1)); | ||
257 | udelay(500); | ||
258 | } else { | ||
259 | dprintk(3, | ||
260 | KERN_DEBUG | ||
261 | "%s: jpeg_codec_sleep() - sleep GPIO=0x%08x\n", | ||
262 | ZR_DEVNAME(zr), btread(ZR36057_GPPGCR1)); | ||
263 | udelay(2); | ||
264 | } | ||
265 | } | ||
266 | |||
267 | int | ||
268 | jpeg_codec_reset (struct zoran *zr) | ||
269 | { | ||
270 | /* Take the codec out of sleep */ | ||
271 | jpeg_codec_sleep(zr, 0); | ||
272 | |||
273 | if (zr->card.gpcs[GPCS_JPEG_RESET] != 0xff) { | ||
274 | post_office_write(zr, zr->card.gpcs[GPCS_JPEG_RESET], 0, | ||
275 | 0); | ||
276 | udelay(2); | ||
277 | } else { | ||
278 | GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 0); | ||
279 | udelay(2); | ||
280 | GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 1); | ||
281 | udelay(2); | ||
282 | } | ||
283 | |||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | /* | ||
288 | * Set the registers for the size we have specified. Don't bother | ||
289 | * trying to understand this without the ZR36057 manual in front of | ||
290 | * you [AC]. | ||
291 | * | ||
292 | * PS: The manual is free for download in .pdf format from | ||
293 | * www.zoran.com - nicely done those folks. | ||
294 | */ | ||
295 | |||
296 | static void | ||
297 | zr36057_adjust_vfe (struct zoran *zr, | ||
298 | enum zoran_codec_mode mode) | ||
299 | { | ||
300 | u32 reg; | ||
301 | |||
302 | switch (mode) { | ||
303 | case BUZ_MODE_MOTION_DECOMPRESS: | ||
304 | btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR); | ||
305 | reg = btread(ZR36057_VFEHCR); | ||
306 | if ((reg & (1 << 10)) && zr->card.type != LML33R10) { | ||
307 | reg += ((1 << 10) | 1); | ||
308 | } | ||
309 | btwrite(reg, ZR36057_VFEHCR); | ||
310 | break; | ||
311 | case BUZ_MODE_MOTION_COMPRESS: | ||
312 | case BUZ_MODE_IDLE: | ||
313 | default: | ||
314 | if ((zr->norm & V4L2_STD_NTSC) || | ||
315 | (zr->card.type == LML33R10 && | ||
316 | (zr->norm & V4L2_STD_PAL))) | ||
317 | btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR); | ||
318 | else | ||
319 | btor(ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR); | ||
320 | reg = btread(ZR36057_VFEHCR); | ||
321 | if (!(reg & (1 << 10)) && zr->card.type != LML33R10) { | ||
322 | reg -= ((1 << 10) | 1); | ||
323 | } | ||
324 | btwrite(reg, ZR36057_VFEHCR); | ||
325 | break; | ||
326 | } | ||
327 | } | ||
328 | |||
329 | /* | ||
330 | * set geometry | ||
331 | */ | ||
332 | |||
333 | static void | ||
334 | zr36057_set_vfe (struct zoran *zr, | ||
335 | int video_width, | ||
336 | int video_height, | ||
337 | const struct zoran_format *format) | ||
338 | { | ||
339 | struct tvnorm *tvn; | ||
340 | unsigned HStart, HEnd, VStart, VEnd; | ||
341 | unsigned DispMode; | ||
342 | unsigned VidWinWid, VidWinHt; | ||
343 | unsigned hcrop1, hcrop2, vcrop1, vcrop2; | ||
344 | unsigned Wa, We, Ha, He; | ||
345 | unsigned X, Y, HorDcm, VerDcm; | ||
346 | u32 reg; | ||
347 | unsigned mask_line_size; | ||
348 | |||
349 | tvn = zr->timing; | ||
350 | |||
351 | Wa = tvn->Wa; | ||
352 | Ha = tvn->Ha; | ||
353 | |||
354 | dprintk(2, KERN_INFO "%s: set_vfe() - width = %d, height = %d\n", | ||
355 | ZR_DEVNAME(zr), video_width, video_height); | ||
356 | |||
357 | if (video_width < BUZ_MIN_WIDTH || | ||
358 | video_height < BUZ_MIN_HEIGHT || | ||
359 | video_width > Wa || video_height > Ha) { | ||
360 | dprintk(1, KERN_ERR "%s: set_vfe: w=%d h=%d not valid\n", | ||
361 | ZR_DEVNAME(zr), video_width, video_height); | ||
362 | return; | ||
363 | } | ||
364 | |||
365 | /**** zr36057 ****/ | ||
366 | |||
367 | /* horizontal */ | ||
368 | VidWinWid = video_width; | ||
369 | X = DIV_ROUND_UP(VidWinWid * 64, tvn->Wa); | ||
370 | We = (VidWinWid * 64) / X; | ||
371 | HorDcm = 64 - X; | ||
372 | hcrop1 = 2 * ((tvn->Wa - We) / 4); | ||
373 | hcrop2 = tvn->Wa - We - hcrop1; | ||
374 | HStart = tvn->HStart ? tvn->HStart : 1; | ||
375 | /* (Ronald) Original comment: | ||
376 | * "| 1 Doesn't have any effect, tested on both a DC10 and a DC10+" | ||
377 | * this is false. It inverses chroma values on the LML33R10 (so Cr | ||
378 | * suddenly is shown as Cb and reverse, really cool effect if you | ||
379 | * want to see blue faces, not useful otherwise). So don't use |1. | ||
380 | * However, the DC10 has '0' as HStart, but does need |1, so we | ||
381 | * use a dirty check... | ||
382 | */ | ||
383 | HEnd = HStart + tvn->Wa - 1; | ||
384 | HStart += hcrop1; | ||
385 | HEnd -= hcrop2; | ||
386 | reg = ((HStart & ZR36057_VFEHCR_Hmask) << ZR36057_VFEHCR_HStart) | ||
387 | | ((HEnd & ZR36057_VFEHCR_Hmask) << ZR36057_VFEHCR_HEnd); | ||
388 | if (zr->card.vfe_pol.hsync_pol) | ||
389 | reg |= ZR36057_VFEHCR_HSPol; | ||
390 | btwrite(reg, ZR36057_VFEHCR); | ||
391 | |||
392 | /* Vertical */ | ||
393 | DispMode = !(video_height > BUZ_MAX_HEIGHT / 2); | ||
394 | VidWinHt = DispMode ? video_height : video_height / 2; | ||
395 | Y = DIV_ROUND_UP(VidWinHt * 64 * 2, tvn->Ha); | ||
396 | He = (VidWinHt * 64) / Y; | ||
397 | VerDcm = 64 - Y; | ||
398 | vcrop1 = (tvn->Ha / 2 - He) / 2; | ||
399 | vcrop2 = tvn->Ha / 2 - He - vcrop1; | ||
400 | VStart = tvn->VStart; | ||
401 | VEnd = VStart + tvn->Ha / 2; // - 1; FIXME SnapShot times out with -1 in 768*576 on the DC10 - LP | ||
402 | VStart += vcrop1; | ||
403 | VEnd -= vcrop2; | ||
404 | reg = ((VStart & ZR36057_VFEVCR_Vmask) << ZR36057_VFEVCR_VStart) | ||
405 | | ((VEnd & ZR36057_VFEVCR_Vmask) << ZR36057_VFEVCR_VEnd); | ||
406 | if (zr->card.vfe_pol.vsync_pol) | ||
407 | reg |= ZR36057_VFEVCR_VSPol; | ||
408 | btwrite(reg, ZR36057_VFEVCR); | ||
409 | |||
410 | /* scaler and pixel format */ | ||
411 | reg = 0; | ||
412 | reg |= (HorDcm << ZR36057_VFESPFR_HorDcm); | ||
413 | reg |= (VerDcm << ZR36057_VFESPFR_VerDcm); | ||
414 | reg |= (DispMode << ZR36057_VFESPFR_DispMode); | ||
415 | /* RJ: I don't know, why the following has to be the opposite | ||
416 | * of the corresponding ZR36060 setting, but only this way | ||
417 | * we get the correct colors when uncompressing to the screen */ | ||
418 | //reg |= ZR36057_VFESPFR_VCLKPol; /**/ | ||
419 | /* RJ: Don't know if that is needed for NTSC also */ | ||
420 | if (!(zr->norm & V4L2_STD_NTSC)) | ||
421 | reg |= ZR36057_VFESPFR_ExtFl; // NEEDED!!!!!!! Wolfgang | ||
422 | reg |= ZR36057_VFESPFR_TopField; | ||
423 | if (HorDcm >= 48) { | ||
424 | reg |= 3 << ZR36057_VFESPFR_HFilter; /* 5 tap filter */ | ||
425 | } else if (HorDcm >= 32) { | ||
426 | reg |= 2 << ZR36057_VFESPFR_HFilter; /* 4 tap filter */ | ||
427 | } else if (HorDcm >= 16) { | ||
428 | reg |= 1 << ZR36057_VFESPFR_HFilter; /* 3 tap filter */ | ||
429 | } | ||
430 | reg |= format->vfespfr; | ||
431 | btwrite(reg, ZR36057_VFESPFR); | ||
432 | |||
433 | /* display configuration */ | ||
434 | reg = (16 << ZR36057_VDCR_MinPix) | ||
435 | | (VidWinHt << ZR36057_VDCR_VidWinHt) | ||
436 | | (VidWinWid << ZR36057_VDCR_VidWinWid); | ||
437 | if (pci_pci_problems & PCIPCI_TRITON) | ||
438 | // || zr->revision < 1) // Revision 1 has also Triton support | ||
439 | reg &= ~ZR36057_VDCR_Triton; | ||
440 | else | ||
441 | reg |= ZR36057_VDCR_Triton; | ||
442 | btwrite(reg, ZR36057_VDCR); | ||
443 | |||
444 | /* (Ronald) don't write this if overlay_mask = NULL */ | ||
445 | if (zr->overlay_mask) { | ||
446 | /* Write overlay clipping mask data, but don't enable overlay clipping */ | ||
447 | /* RJ: since this makes only sense on the screen, we use | ||
448 | * zr->overlay_settings.width instead of video_width */ | ||
449 | |||
450 | mask_line_size = (BUZ_MAX_WIDTH + 31) / 32; | ||
451 | reg = virt_to_bus(zr->overlay_mask); | ||
452 | btwrite(reg, ZR36057_MMTR); | ||
453 | reg = virt_to_bus(zr->overlay_mask + mask_line_size); | ||
454 | btwrite(reg, ZR36057_MMBR); | ||
455 | reg = | ||
456 | mask_line_size - (zr->overlay_settings.width + | ||
457 | 31) / 32; | ||
458 | if (DispMode == 0) | ||
459 | reg += mask_line_size; | ||
460 | reg <<= ZR36057_OCR_MaskStride; | ||
461 | btwrite(reg, ZR36057_OCR); | ||
462 | } | ||
463 | |||
464 | zr36057_adjust_vfe(zr, zr->codec_mode); | ||
465 | } | ||
466 | |||
467 | /* | ||
468 | * Switch overlay on or off | ||
469 | */ | ||
470 | |||
471 | void | ||
472 | zr36057_overlay (struct zoran *zr, | ||
473 | int on) | ||
474 | { | ||
475 | u32 reg; | ||
476 | |||
477 | if (on) { | ||
478 | /* do the necessary settings ... */ | ||
479 | btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR); /* switch it off first */ | ||
480 | |||
481 | zr36057_set_vfe(zr, | ||
482 | zr->overlay_settings.width, | ||
483 | zr->overlay_settings.height, | ||
484 | zr->overlay_settings.format); | ||
485 | |||
486 | /* Start and length of each line MUST be 4-byte aligned. | ||
487 | * This should be already checked before the call to this routine. | ||
488 | * All error messages are internal driver checking only! */ | ||
489 | |||
490 | /* video display top and bottom registers */ | ||
491 | reg = (long) zr->vbuf_base + | ||
492 | zr->overlay_settings.x * | ||
493 | ((zr->overlay_settings.format->depth + 7) / 8) + | ||
494 | zr->overlay_settings.y * | ||
495 | zr->vbuf_bytesperline; | ||
496 | btwrite(reg, ZR36057_VDTR); | ||
497 | if (reg & 3) | ||
498 | dprintk(1, | ||
499 | KERN_ERR | ||
500 | "%s: zr36057_overlay() - video_address not aligned\n", | ||
501 | ZR_DEVNAME(zr)); | ||
502 | if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2) | ||
503 | reg += zr->vbuf_bytesperline; | ||
504 | btwrite(reg, ZR36057_VDBR); | ||
505 | |||
506 | /* video stride, status, and frame grab register */ | ||
507 | reg = zr->vbuf_bytesperline - | ||
508 | zr->overlay_settings.width * | ||
509 | ((zr->overlay_settings.format->depth + 7) / 8); | ||
510 | if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2) | ||
511 | reg += zr->vbuf_bytesperline; | ||
512 | if (reg & 3) | ||
513 | dprintk(1, | ||
514 | KERN_ERR | ||
515 | "%s: zr36057_overlay() - video_stride not aligned\n", | ||
516 | ZR_DEVNAME(zr)); | ||
517 | reg = (reg << ZR36057_VSSFGR_DispStride); | ||
518 | reg |= ZR36057_VSSFGR_VidOvf; /* clear overflow status */ | ||
519 | btwrite(reg, ZR36057_VSSFGR); | ||
520 | |||
521 | /* Set overlay clipping */ | ||
522 | if (zr->overlay_settings.clipcount > 0) | ||
523 | btor(ZR36057_OCR_OvlEnable, ZR36057_OCR); | ||
524 | |||
525 | /* ... and switch it on */ | ||
526 | btor(ZR36057_VDCR_VidEn, ZR36057_VDCR); | ||
527 | } else { | ||
528 | /* Switch it off */ | ||
529 | btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR); | ||
530 | } | ||
531 | } | ||
532 | |||
533 | /* | ||
534 | * The overlay mask has one bit for each pixel on a scan line, | ||
535 | * and the maximum window size is BUZ_MAX_WIDTH * BUZ_MAX_HEIGHT pixels. | ||
536 | */ | ||
537 | |||
538 | void write_overlay_mask(struct zoran_fh *fh, struct v4l2_clip *vp, int count) | ||
539 | { | ||
540 | struct zoran *zr = fh->zr; | ||
541 | unsigned mask_line_size = (BUZ_MAX_WIDTH + 31) / 32; | ||
542 | u32 *mask; | ||
543 | int x, y, width, height; | ||
544 | unsigned i, j, k; | ||
545 | |||
546 | /* fill mask with one bits */ | ||
547 | memset(fh->overlay_mask, ~0, mask_line_size * 4 * BUZ_MAX_HEIGHT); | ||
548 | |||
549 | for (i = 0; i < count; ++i) { | ||
550 | /* pick up local copy of clip */ | ||
551 | x = vp[i].c.left; | ||
552 | y = vp[i].c.top; | ||
553 | width = vp[i].c.width; | ||
554 | height = vp[i].c.height; | ||
555 | |||
556 | /* trim clips that extend beyond the window */ | ||
557 | if (x < 0) { | ||
558 | width += x; | ||
559 | x = 0; | ||
560 | } | ||
561 | if (y < 0) { | ||
562 | height += y; | ||
563 | y = 0; | ||
564 | } | ||
565 | if (x + width > fh->overlay_settings.width) { | ||
566 | width = fh->overlay_settings.width - x; | ||
567 | } | ||
568 | if (y + height > fh->overlay_settings.height) { | ||
569 | height = fh->overlay_settings.height - y; | ||
570 | } | ||
571 | |||
572 | /* ignore degenerate clips */ | ||
573 | if (height <= 0) { | ||
574 | continue; | ||
575 | } | ||
576 | if (width <= 0) { | ||
577 | continue; | ||
578 | } | ||
579 | |||
580 | /* apply clip for each scan line */ | ||
581 | for (j = 0; j < height; ++j) { | ||
582 | /* reset bit for each pixel */ | ||
583 | /* this can be optimized later if need be */ | ||
584 | mask = fh->overlay_mask + (y + j) * mask_line_size; | ||
585 | for (k = 0; k < width; ++k) { | ||
586 | mask[(x + k) / 32] &= | ||
587 | ~((u32) 1 << (x + k) % 32); | ||
588 | } | ||
589 | } | ||
590 | } | ||
591 | } | ||
592 | |||
593 | /* Enable/Disable uncompressed memory grabbing of the 36057 */ | ||
594 | |||
595 | void | ||
596 | zr36057_set_memgrab (struct zoran *zr, | ||
597 | int mode) | ||
598 | { | ||
599 | if (mode) { | ||
600 | /* We only check SnapShot and not FrameGrab here. SnapShot==1 | ||
601 | * means a capture is already in progress, but FrameGrab==1 | ||
602 | * doesn't necessary mean that. It's more correct to say a 1 | ||
603 | * to 0 transition indicates a capture completed. If a | ||
604 | * capture is pending when capturing is tuned off, FrameGrab | ||
605 | * will be stuck at 1 until capturing is turned back on. | ||
606 | */ | ||
607 | if (btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SnapShot) | ||
608 | dprintk(1, | ||
609 | KERN_WARNING | ||
610 | "%s: zr36057_set_memgrab(1) with SnapShot on!?\n", | ||
611 | ZR_DEVNAME(zr)); | ||
612 | |||
613 | /* switch on VSync interrupts */ | ||
614 | btwrite(IRQ_MASK, ZR36057_ISR); // Clear Interrupts | ||
615 | btor(zr->card.vsync_int, ZR36057_ICR); // SW | ||
616 | |||
617 | /* enable SnapShot */ | ||
618 | btor(ZR36057_VSSFGR_SnapShot, ZR36057_VSSFGR); | ||
619 | |||
620 | /* Set zr36057 video front end and enable video */ | ||
621 | zr36057_set_vfe(zr, zr->v4l_settings.width, | ||
622 | zr->v4l_settings.height, | ||
623 | zr->v4l_settings.format); | ||
624 | |||
625 | zr->v4l_memgrab_active = 1; | ||
626 | } else { | ||
627 | /* switch off VSync interrupts */ | ||
628 | btand(~zr->card.vsync_int, ZR36057_ICR); // SW | ||
629 | |||
630 | zr->v4l_memgrab_active = 0; | ||
631 | zr->v4l_grab_frame = NO_GRAB_ACTIVE; | ||
632 | |||
633 | /* reenable grabbing to screen if it was running */ | ||
634 | if (zr->v4l_overlay_active) { | ||
635 | zr36057_overlay(zr, 1); | ||
636 | } else { | ||
637 | btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR); | ||
638 | btand(~ZR36057_VSSFGR_SnapShot, ZR36057_VSSFGR); | ||
639 | } | ||
640 | } | ||
641 | } | ||
642 | |||
643 | int | ||
644 | wait_grab_pending (struct zoran *zr) | ||
645 | { | ||
646 | unsigned long flags; | ||
647 | |||
648 | /* wait until all pending grabs are finished */ | ||
649 | |||
650 | if (!zr->v4l_memgrab_active) | ||
651 | return 0; | ||
652 | |||
653 | wait_event_interruptible(zr->v4l_capq, | ||
654 | (zr->v4l_pend_tail == zr->v4l_pend_head)); | ||
655 | if (signal_pending(current)) | ||
656 | return -ERESTARTSYS; | ||
657 | |||
658 | spin_lock_irqsave(&zr->spinlock, flags); | ||
659 | zr36057_set_memgrab(zr, 0); | ||
660 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
661 | |||
662 | return 0; | ||
663 | } | ||
664 | |||
665 | /***************************************************************************** | ||
666 | * * | ||
667 | * Set up the Buz-specific MJPEG part * | ||
668 | * * | ||
669 | *****************************************************************************/ | ||
670 | |||
671 | static inline void | ||
672 | set_frame (struct zoran *zr, | ||
673 | int val) | ||
674 | { | ||
675 | GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_FRAME], val); | ||
676 | } | ||
677 | |||
678 | static void | ||
679 | set_videobus_dir (struct zoran *zr, | ||
680 | int val) | ||
681 | { | ||
682 | switch (zr->card.type) { | ||
683 | case LML33: | ||
684 | case LML33R10: | ||
685 | if (lml33dpath == 0) | ||
686 | GPIO(zr, 5, val); | ||
687 | else | ||
688 | GPIO(zr, 5, 1); | ||
689 | break; | ||
690 | default: | ||
691 | GPIO(zr, zr->card.gpio[ZR_GPIO_VID_DIR], | ||
692 | zr->card.gpio_pol[ZR_GPIO_VID_DIR] ? !val : val); | ||
693 | break; | ||
694 | } | ||
695 | } | ||
696 | |||
697 | static void | ||
698 | init_jpeg_queue (struct zoran *zr) | ||
699 | { | ||
700 | int i; | ||
701 | |||
702 | /* re-initialize DMA ring stuff */ | ||
703 | zr->jpg_que_head = 0; | ||
704 | zr->jpg_dma_head = 0; | ||
705 | zr->jpg_dma_tail = 0; | ||
706 | zr->jpg_que_tail = 0; | ||
707 | zr->jpg_seq_num = 0; | ||
708 | zr->JPEG_error = 0; | ||
709 | zr->num_errors = 0; | ||
710 | zr->jpg_err_seq = 0; | ||
711 | zr->jpg_err_shift = 0; | ||
712 | zr->jpg_queued_num = 0; | ||
713 | for (i = 0; i < zr->jpg_buffers.num_buffers; i++) { | ||
714 | zr->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */ | ||
715 | } | ||
716 | for (i = 0; i < BUZ_NUM_STAT_COM; i++) { | ||
717 | zr->stat_com[i] = cpu_to_le32(1); /* mark as unavailable to zr36057 */ | ||
718 | } | ||
719 | } | ||
720 | |||
721 | static void | ||
722 | zr36057_set_jpg (struct zoran *zr, | ||
723 | enum zoran_codec_mode mode) | ||
724 | { | ||
725 | struct tvnorm *tvn; | ||
726 | u32 reg; | ||
727 | |||
728 | tvn = zr->timing; | ||
729 | |||
730 | /* assert P_Reset, disable code transfer, deassert Active */ | ||
731 | btwrite(0, ZR36057_JPC); | ||
732 | |||
733 | /* MJPEG compression mode */ | ||
734 | switch (mode) { | ||
735 | |||
736 | case BUZ_MODE_MOTION_COMPRESS: | ||
737 | default: | ||
738 | reg = ZR36057_JMC_MJPGCmpMode; | ||
739 | break; | ||
740 | |||
741 | case BUZ_MODE_MOTION_DECOMPRESS: | ||
742 | reg = ZR36057_JMC_MJPGExpMode; | ||
743 | reg |= ZR36057_JMC_SyncMstr; | ||
744 | /* RJ: The following is experimental - improves the output to screen */ | ||
745 | //if(zr->jpg_settings.VFIFO_FB) reg |= ZR36057_JMC_VFIFO_FB; // No, it doesn't. SM | ||
746 | break; | ||
747 | |||
748 | case BUZ_MODE_STILL_COMPRESS: | ||
749 | reg = ZR36057_JMC_JPGCmpMode; | ||
750 | break; | ||
751 | |||
752 | case BUZ_MODE_STILL_DECOMPRESS: | ||
753 | reg = ZR36057_JMC_JPGExpMode; | ||
754 | break; | ||
755 | |||
756 | } | ||
757 | reg |= ZR36057_JMC_JPG; | ||
758 | if (zr->jpg_settings.field_per_buff == 1) | ||
759 | reg |= ZR36057_JMC_Fld_per_buff; | ||
760 | btwrite(reg, ZR36057_JMC); | ||
761 | |||
762 | /* vertical */ | ||
763 | btor(ZR36057_VFEVCR_VSPol, ZR36057_VFEVCR); | ||
764 | reg = (6 << ZR36057_VSP_VsyncSize) | | ||
765 | (tvn->Ht << ZR36057_VSP_FrmTot); | ||
766 | btwrite(reg, ZR36057_VSP); | ||
767 | reg = ((zr->jpg_settings.img_y + tvn->VStart) << ZR36057_FVAP_NAY) | | ||
768 | (zr->jpg_settings.img_height << ZR36057_FVAP_PAY); | ||
769 | btwrite(reg, ZR36057_FVAP); | ||
770 | |||
771 | /* horizontal */ | ||
772 | if (zr->card.vfe_pol.hsync_pol) | ||
773 | btor(ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR); | ||
774 | else | ||
775 | btand(~ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR); | ||
776 | reg = ((tvn->HSyncStart) << ZR36057_HSP_HsyncStart) | | ||
777 | (tvn->Wt << ZR36057_HSP_LineTot); | ||
778 | btwrite(reg, ZR36057_HSP); | ||
779 | reg = ((zr->jpg_settings.img_x + | ||
780 | tvn->HStart + 4) << ZR36057_FHAP_NAX) | | ||
781 | (zr->jpg_settings.img_width << ZR36057_FHAP_PAX); | ||
782 | btwrite(reg, ZR36057_FHAP); | ||
783 | |||
784 | /* field process parameters */ | ||
785 | if (zr->jpg_settings.odd_even) | ||
786 | reg = ZR36057_FPP_Odd_Even; | ||
787 | else | ||
788 | reg = 0; | ||
789 | |||
790 | btwrite(reg, ZR36057_FPP); | ||
791 | |||
792 | /* Set proper VCLK Polarity, else colors will be wrong during playback */ | ||
793 | //btor(ZR36057_VFESPFR_VCLKPol, ZR36057_VFESPFR); | ||
794 | |||
795 | /* code base address */ | ||
796 | reg = virt_to_bus(zr->stat_com); | ||
797 | btwrite(reg, ZR36057_JCBA); | ||
798 | |||
799 | /* FIFO threshold (FIFO is 160. double words) */ | ||
800 | /* NOTE: decimal values here */ | ||
801 | switch (mode) { | ||
802 | |||
803 | case BUZ_MODE_STILL_COMPRESS: | ||
804 | case BUZ_MODE_MOTION_COMPRESS: | ||
805 | if (zr->card.type != BUZ) | ||
806 | reg = 140; | ||
807 | else | ||
808 | reg = 60; | ||
809 | break; | ||
810 | |||
811 | case BUZ_MODE_STILL_DECOMPRESS: | ||
812 | case BUZ_MODE_MOTION_DECOMPRESS: | ||
813 | reg = 20; | ||
814 | break; | ||
815 | |||
816 | default: | ||
817 | reg = 80; | ||
818 | break; | ||
819 | |||
820 | } | ||
821 | btwrite(reg, ZR36057_JCFT); | ||
822 | zr36057_adjust_vfe(zr, mode); | ||
823 | |||
824 | } | ||
825 | |||
826 | void | ||
827 | print_interrupts (struct zoran *zr) | ||
828 | { | ||
829 | int res, noerr = 0; | ||
830 | |||
831 | printk(KERN_INFO "%s: interrupts received:", ZR_DEVNAME(zr)); | ||
832 | if ((res = zr->field_counter) < -1 || res > 1) { | ||
833 | printk(" FD:%d", res); | ||
834 | } | ||
835 | if ((res = zr->intr_counter_GIRQ1) != 0) { | ||
836 | printk(" GIRQ1:%d", res); | ||
837 | noerr++; | ||
838 | } | ||
839 | if ((res = zr->intr_counter_GIRQ0) != 0) { | ||
840 | printk(" GIRQ0:%d", res); | ||
841 | noerr++; | ||
842 | } | ||
843 | if ((res = zr->intr_counter_CodRepIRQ) != 0) { | ||
844 | printk(" CodRepIRQ:%d", res); | ||
845 | noerr++; | ||
846 | } | ||
847 | if ((res = zr->intr_counter_JPEGRepIRQ) != 0) { | ||
848 | printk(" JPEGRepIRQ:%d", res); | ||
849 | noerr++; | ||
850 | } | ||
851 | if (zr->JPEG_max_missed) { | ||
852 | printk(" JPEG delays: max=%d min=%d", zr->JPEG_max_missed, | ||
853 | zr->JPEG_min_missed); | ||
854 | } | ||
855 | if (zr->END_event_missed) { | ||
856 | printk(" ENDs missed: %d", zr->END_event_missed); | ||
857 | } | ||
858 | //if (zr->jpg_queued_num) { | ||
859 | printk(" queue_state=%ld/%ld/%ld/%ld", zr->jpg_que_tail, | ||
860 | zr->jpg_dma_tail, zr->jpg_dma_head, zr->jpg_que_head); | ||
861 | //} | ||
862 | if (!noerr) { | ||
863 | printk(": no interrupts detected."); | ||
864 | } | ||
865 | printk("\n"); | ||
866 | } | ||
867 | |||
868 | void | ||
869 | clear_interrupt_counters (struct zoran *zr) | ||
870 | { | ||
871 | zr->intr_counter_GIRQ1 = 0; | ||
872 | zr->intr_counter_GIRQ0 = 0; | ||
873 | zr->intr_counter_CodRepIRQ = 0; | ||
874 | zr->intr_counter_JPEGRepIRQ = 0; | ||
875 | zr->field_counter = 0; | ||
876 | zr->IRQ1_in = 0; | ||
877 | zr->IRQ1_out = 0; | ||
878 | zr->JPEG_in = 0; | ||
879 | zr->JPEG_out = 0; | ||
880 | zr->JPEG_0 = 0; | ||
881 | zr->JPEG_1 = 0; | ||
882 | zr->END_event_missed = 0; | ||
883 | zr->JPEG_missed = 0; | ||
884 | zr->JPEG_max_missed = 0; | ||
885 | zr->JPEG_min_missed = 0x7fffffff; | ||
886 | } | ||
887 | |||
888 | static u32 | ||
889 | count_reset_interrupt (struct zoran *zr) | ||
890 | { | ||
891 | u32 isr; | ||
892 | |||
893 | if ((isr = btread(ZR36057_ISR) & 0x78000000)) { | ||
894 | if (isr & ZR36057_ISR_GIRQ1) { | ||
895 | btwrite(ZR36057_ISR_GIRQ1, ZR36057_ISR); | ||
896 | zr->intr_counter_GIRQ1++; | ||
897 | } | ||
898 | if (isr & ZR36057_ISR_GIRQ0) { | ||
899 | btwrite(ZR36057_ISR_GIRQ0, ZR36057_ISR); | ||
900 | zr->intr_counter_GIRQ0++; | ||
901 | } | ||
902 | if (isr & ZR36057_ISR_CodRepIRQ) { | ||
903 | btwrite(ZR36057_ISR_CodRepIRQ, ZR36057_ISR); | ||
904 | zr->intr_counter_CodRepIRQ++; | ||
905 | } | ||
906 | if (isr & ZR36057_ISR_JPEGRepIRQ) { | ||
907 | btwrite(ZR36057_ISR_JPEGRepIRQ, ZR36057_ISR); | ||
908 | zr->intr_counter_JPEGRepIRQ++; | ||
909 | } | ||
910 | } | ||
911 | return isr; | ||
912 | } | ||
913 | |||
914 | void | ||
915 | jpeg_start (struct zoran *zr) | ||
916 | { | ||
917 | int reg; | ||
918 | |||
919 | zr->frame_num = 0; | ||
920 | |||
921 | /* deassert P_reset, disable code transfer, deassert Active */ | ||
922 | btwrite(ZR36057_JPC_P_Reset, ZR36057_JPC); | ||
923 | /* stop flushing the internal code buffer */ | ||
924 | btand(~ZR36057_MCTCR_CFlush, ZR36057_MCTCR); | ||
925 | /* enable code transfer */ | ||
926 | btor(ZR36057_JPC_CodTrnsEn, ZR36057_JPC); | ||
927 | |||
928 | /* clear IRQs */ | ||
929 | btwrite(IRQ_MASK, ZR36057_ISR); | ||
930 | /* enable the JPEG IRQs */ | ||
931 | btwrite(zr->card.jpeg_int | | ||
932 | ZR36057_ICR_JPEGRepIRQ | | ||
933 | ZR36057_ICR_IntPinEn, | ||
934 | ZR36057_ICR); | ||
935 | |||
936 | set_frame(zr, 0); // \FRAME | ||
937 | |||
938 | /* set the JPEG codec guest ID */ | ||
939 | reg = (zr->card.gpcs[1] << ZR36057_JCGI_JPEGuestID) | | ||
940 | (0 << ZR36057_JCGI_JPEGuestReg); | ||
941 | btwrite(reg, ZR36057_JCGI); | ||
942 | |||
943 | if (zr->card.video_vfe == CODEC_TYPE_ZR36016 && | ||
944 | zr->card.video_codec == CODEC_TYPE_ZR36050) { | ||
945 | /* Enable processing on the ZR36016 */ | ||
946 | if (zr->vfe) | ||
947 | zr36016_write(zr->vfe, 0, 1); | ||
948 | |||
949 | /* load the address of the GO register in the ZR36050 latch */ | ||
950 | post_office_write(zr, 0, 0, 0); | ||
951 | } | ||
952 | |||
953 | /* assert Active */ | ||
954 | btor(ZR36057_JPC_Active, ZR36057_JPC); | ||
955 | |||
956 | /* enable the Go generation */ | ||
957 | btor(ZR36057_JMC_Go_en, ZR36057_JMC); | ||
958 | udelay(30); | ||
959 | |||
960 | set_frame(zr, 1); // /FRAME | ||
961 | |||
962 | dprintk(3, KERN_DEBUG "%s: jpeg_start\n", ZR_DEVNAME(zr)); | ||
963 | } | ||
964 | |||
965 | void | ||
966 | zr36057_enable_jpg (struct zoran *zr, | ||
967 | enum zoran_codec_mode mode) | ||
968 | { | ||
969 | struct vfe_settings cap; | ||
970 | int field_size = | ||
971 | zr->jpg_buffers.buffer_size / zr->jpg_settings.field_per_buff; | ||
972 | |||
973 | zr->codec_mode = mode; | ||
974 | |||
975 | cap.x = zr->jpg_settings.img_x; | ||
976 | cap.y = zr->jpg_settings.img_y; | ||
977 | cap.width = zr->jpg_settings.img_width; | ||
978 | cap.height = zr->jpg_settings.img_height; | ||
979 | cap.decimation = | ||
980 | zr->jpg_settings.HorDcm | (zr->jpg_settings.VerDcm << 8); | ||
981 | cap.quality = zr->jpg_settings.jpg_comp.quality; | ||
982 | |||
983 | switch (mode) { | ||
984 | |||
985 | case BUZ_MODE_MOTION_COMPRESS: { | ||
986 | struct jpeg_app_marker app; | ||
987 | struct jpeg_com_marker com; | ||
988 | |||
989 | /* In motion compress mode, the decoder output must be enabled, and | ||
990 | * the video bus direction set to input. | ||
991 | */ | ||
992 | set_videobus_dir(zr, 0); | ||
993 | decoder_call(zr, video, s_stream, 1); | ||
994 | encoder_call(zr, video, s_routing, 0, 0, 0); | ||
995 | |||
996 | /* Take the JPEG codec and the VFE out of sleep */ | ||
997 | jpeg_codec_sleep(zr, 0); | ||
998 | |||
999 | /* set JPEG app/com marker */ | ||
1000 | app.appn = zr->jpg_settings.jpg_comp.APPn; | ||
1001 | app.len = zr->jpg_settings.jpg_comp.APP_len; | ||
1002 | memcpy(app.data, zr->jpg_settings.jpg_comp.APP_data, 60); | ||
1003 | zr->codec->control(zr->codec, CODEC_S_JPEG_APP_DATA, | ||
1004 | sizeof(struct jpeg_app_marker), &app); | ||
1005 | |||
1006 | com.len = zr->jpg_settings.jpg_comp.COM_len; | ||
1007 | memcpy(com.data, zr->jpg_settings.jpg_comp.COM_data, 60); | ||
1008 | zr->codec->control(zr->codec, CODEC_S_JPEG_COM_DATA, | ||
1009 | sizeof(struct jpeg_com_marker), &com); | ||
1010 | |||
1011 | /* Setup the JPEG codec */ | ||
1012 | zr->codec->control(zr->codec, CODEC_S_JPEG_TDS_BYTE, | ||
1013 | sizeof(int), &field_size); | ||
1014 | zr->codec->set_video(zr->codec, zr->timing, &cap, | ||
1015 | &zr->card.vfe_pol); | ||
1016 | zr->codec->set_mode(zr->codec, CODEC_DO_COMPRESSION); | ||
1017 | |||
1018 | /* Setup the VFE */ | ||
1019 | if (zr->vfe) { | ||
1020 | zr->vfe->control(zr->vfe, CODEC_S_JPEG_TDS_BYTE, | ||
1021 | sizeof(int), &field_size); | ||
1022 | zr->vfe->set_video(zr->vfe, zr->timing, &cap, | ||
1023 | &zr->card.vfe_pol); | ||
1024 | zr->vfe->set_mode(zr->vfe, CODEC_DO_COMPRESSION); | ||
1025 | } | ||
1026 | |||
1027 | init_jpeg_queue(zr); | ||
1028 | zr36057_set_jpg(zr, mode); // \P_Reset, ... Video param, FIFO | ||
1029 | |||
1030 | clear_interrupt_counters(zr); | ||
1031 | dprintk(2, KERN_INFO "%s: enable_jpg(MOTION_COMPRESS)\n", | ||
1032 | ZR_DEVNAME(zr)); | ||
1033 | break; | ||
1034 | } | ||
1035 | |||
1036 | case BUZ_MODE_MOTION_DECOMPRESS: | ||
1037 | /* In motion decompression mode, the decoder output must be disabled, and | ||
1038 | * the video bus direction set to output. | ||
1039 | */ | ||
1040 | decoder_call(zr, video, s_stream, 0); | ||
1041 | set_videobus_dir(zr, 1); | ||
1042 | encoder_call(zr, video, s_routing, 1, 0, 0); | ||
1043 | |||
1044 | /* Take the JPEG codec and the VFE out of sleep */ | ||
1045 | jpeg_codec_sleep(zr, 0); | ||
1046 | /* Setup the VFE */ | ||
1047 | if (zr->vfe) { | ||
1048 | zr->vfe->set_video(zr->vfe, zr->timing, &cap, | ||
1049 | &zr->card.vfe_pol); | ||
1050 | zr->vfe->set_mode(zr->vfe, CODEC_DO_EXPANSION); | ||
1051 | } | ||
1052 | /* Setup the JPEG codec */ | ||
1053 | zr->codec->set_video(zr->codec, zr->timing, &cap, | ||
1054 | &zr->card.vfe_pol); | ||
1055 | zr->codec->set_mode(zr->codec, CODEC_DO_EXPANSION); | ||
1056 | |||
1057 | init_jpeg_queue(zr); | ||
1058 | zr36057_set_jpg(zr, mode); // \P_Reset, ... Video param, FIFO | ||
1059 | |||
1060 | clear_interrupt_counters(zr); | ||
1061 | dprintk(2, KERN_INFO "%s: enable_jpg(MOTION_DECOMPRESS)\n", | ||
1062 | ZR_DEVNAME(zr)); | ||
1063 | break; | ||
1064 | |||
1065 | case BUZ_MODE_IDLE: | ||
1066 | default: | ||
1067 | /* shut down processing */ | ||
1068 | btand(~(zr->card.jpeg_int | ZR36057_ICR_JPEGRepIRQ), | ||
1069 | ZR36057_ICR); | ||
1070 | btwrite(zr->card.jpeg_int | ZR36057_ICR_JPEGRepIRQ, | ||
1071 | ZR36057_ISR); | ||
1072 | btand(~ZR36057_JMC_Go_en, ZR36057_JMC); // \Go_en | ||
1073 | |||
1074 | msleep(50); | ||
1075 | |||
1076 | set_videobus_dir(zr, 0); | ||
1077 | set_frame(zr, 1); // /FRAME | ||
1078 | btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR); // /CFlush | ||
1079 | btwrite(0, ZR36057_JPC); // \P_Reset,\CodTrnsEn,\Active | ||
1080 | btand(~ZR36057_JMC_VFIFO_FB, ZR36057_JMC); | ||
1081 | btand(~ZR36057_JMC_SyncMstr, ZR36057_JMC); | ||
1082 | jpeg_codec_reset(zr); | ||
1083 | jpeg_codec_sleep(zr, 1); | ||
1084 | zr36057_adjust_vfe(zr, mode); | ||
1085 | |||
1086 | decoder_call(zr, video, s_stream, 1); | ||
1087 | encoder_call(zr, video, s_routing, 0, 0, 0); | ||
1088 | |||
1089 | dprintk(2, KERN_INFO "%s: enable_jpg(IDLE)\n", ZR_DEVNAME(zr)); | ||
1090 | break; | ||
1091 | |||
1092 | } | ||
1093 | } | ||
1094 | |||
1095 | /* when this is called the spinlock must be held */ | ||
1096 | void | ||
1097 | zoran_feed_stat_com (struct zoran *zr) | ||
1098 | { | ||
1099 | /* move frames from pending queue to DMA */ | ||
1100 | |||
1101 | int frame, i, max_stat_com; | ||
1102 | |||
1103 | max_stat_com = | ||
1104 | (zr->jpg_settings.TmpDcm == | ||
1105 | 1) ? BUZ_NUM_STAT_COM : (BUZ_NUM_STAT_COM >> 1); | ||
1106 | |||
1107 | while ((zr->jpg_dma_head - zr->jpg_dma_tail) < max_stat_com && | ||
1108 | zr->jpg_dma_head < zr->jpg_que_head) { | ||
1109 | |||
1110 | frame = zr->jpg_pend[zr->jpg_dma_head & BUZ_MASK_FRAME]; | ||
1111 | if (zr->jpg_settings.TmpDcm == 1) { | ||
1112 | /* fill 1 stat_com entry */ | ||
1113 | i = (zr->jpg_dma_head - | ||
1114 | zr->jpg_err_shift) & BUZ_MASK_STAT_COM; | ||
1115 | if (!(zr->stat_com[i] & cpu_to_le32(1))) | ||
1116 | break; | ||
1117 | zr->stat_com[i] = | ||
1118 | cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus); | ||
1119 | } else { | ||
1120 | /* fill 2 stat_com entries */ | ||
1121 | i = ((zr->jpg_dma_head - | ||
1122 | zr->jpg_err_shift) & 1) * 2; | ||
1123 | if (!(zr->stat_com[i] & cpu_to_le32(1))) | ||
1124 | break; | ||
1125 | zr->stat_com[i] = | ||
1126 | cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus); | ||
1127 | zr->stat_com[i + 1] = | ||
1128 | cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus); | ||
1129 | } | ||
1130 | zr->jpg_buffers.buffer[frame].state = BUZ_STATE_DMA; | ||
1131 | zr->jpg_dma_head++; | ||
1132 | |||
1133 | } | ||
1134 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) | ||
1135 | zr->jpg_queued_num++; | ||
1136 | } | ||
1137 | |||
1138 | /* when this is called the spinlock must be held */ | ||
1139 | static void | ||
1140 | zoran_reap_stat_com (struct zoran *zr) | ||
1141 | { | ||
1142 | /* move frames from DMA queue to done queue */ | ||
1143 | |||
1144 | int i; | ||
1145 | u32 stat_com; | ||
1146 | unsigned int seq; | ||
1147 | unsigned int dif; | ||
1148 | struct zoran_buffer *buffer; | ||
1149 | int frame; | ||
1150 | |||
1151 | /* In motion decompress we don't have a hardware frame counter, | ||
1152 | * we just count the interrupts here */ | ||
1153 | |||
1154 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) { | ||
1155 | zr->jpg_seq_num++; | ||
1156 | } | ||
1157 | while (zr->jpg_dma_tail < zr->jpg_dma_head) { | ||
1158 | if (zr->jpg_settings.TmpDcm == 1) | ||
1159 | i = (zr->jpg_dma_tail - | ||
1160 | zr->jpg_err_shift) & BUZ_MASK_STAT_COM; | ||
1161 | else | ||
1162 | i = ((zr->jpg_dma_tail - | ||
1163 | zr->jpg_err_shift) & 1) * 2 + 1; | ||
1164 | |||
1165 | stat_com = le32_to_cpu(zr->stat_com[i]); | ||
1166 | |||
1167 | if ((stat_com & 1) == 0) { | ||
1168 | return; | ||
1169 | } | ||
1170 | frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME]; | ||
1171 | buffer = &zr->jpg_buffers.buffer[frame]; | ||
1172 | do_gettimeofday(&buffer->bs.timestamp); | ||
1173 | |||
1174 | if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { | ||
1175 | buffer->bs.length = (stat_com & 0x7fffff) >> 1; | ||
1176 | |||
1177 | /* update sequence number with the help of the counter in stat_com */ | ||
1178 | |||
1179 | seq = ((stat_com >> 24) + zr->jpg_err_seq) & 0xff; | ||
1180 | dif = (seq - zr->jpg_seq_num) & 0xff; | ||
1181 | zr->jpg_seq_num += dif; | ||
1182 | } else { | ||
1183 | buffer->bs.length = 0; | ||
1184 | } | ||
1185 | buffer->bs.seq = | ||
1186 | zr->jpg_settings.TmpDcm == | ||
1187 | 2 ? (zr->jpg_seq_num >> 1) : zr->jpg_seq_num; | ||
1188 | buffer->state = BUZ_STATE_DONE; | ||
1189 | |||
1190 | zr->jpg_dma_tail++; | ||
1191 | } | ||
1192 | } | ||
1193 | |||
1194 | static void zoran_restart(struct zoran *zr) | ||
1195 | { | ||
1196 | /* Now the stat_comm buffer is ready for restart */ | ||
1197 | unsigned int status = 0; | ||
1198 | int mode; | ||
1199 | |||
1200 | if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { | ||
1201 | decoder_call(zr, video, g_input_status, &status); | ||
1202 | mode = CODEC_DO_COMPRESSION; | ||
1203 | } else { | ||
1204 | status = V4L2_IN_ST_NO_SIGNAL; | ||
1205 | mode = CODEC_DO_EXPANSION; | ||
1206 | } | ||
1207 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || | ||
1208 | !(status & V4L2_IN_ST_NO_SIGNAL)) { | ||
1209 | /********** RESTART code *************/ | ||
1210 | jpeg_codec_reset(zr); | ||
1211 | zr->codec->set_mode(zr->codec, mode); | ||
1212 | zr36057_set_jpg(zr, zr->codec_mode); | ||
1213 | jpeg_start(zr); | ||
1214 | |||
1215 | if (zr->num_errors <= 8) | ||
1216 | dprintk(2, KERN_INFO "%s: Restart\n", | ||
1217 | ZR_DEVNAME(zr)); | ||
1218 | |||
1219 | zr->JPEG_missed = 0; | ||
1220 | zr->JPEG_error = 2; | ||
1221 | /********** End RESTART code ***********/ | ||
1222 | } | ||
1223 | } | ||
1224 | |||
1225 | static void | ||
1226 | error_handler (struct zoran *zr, | ||
1227 | u32 astat, | ||
1228 | u32 stat) | ||
1229 | { | ||
1230 | int i; | ||
1231 | |||
1232 | /* This is JPEG error handling part */ | ||
1233 | if (zr->codec_mode != BUZ_MODE_MOTION_COMPRESS && | ||
1234 | zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS) { | ||
1235 | return; | ||
1236 | } | ||
1237 | |||
1238 | if ((stat & 1) == 0 && | ||
1239 | zr->codec_mode == BUZ_MODE_MOTION_COMPRESS && | ||
1240 | zr->jpg_dma_tail - zr->jpg_que_tail >= zr->jpg_buffers.num_buffers) { | ||
1241 | /* No free buffers... */ | ||
1242 | zoran_reap_stat_com(zr); | ||
1243 | zoran_feed_stat_com(zr); | ||
1244 | wake_up_interruptible(&zr->jpg_capq); | ||
1245 | zr->JPEG_missed = 0; | ||
1246 | return; | ||
1247 | } | ||
1248 | |||
1249 | if (zr->JPEG_error == 1) { | ||
1250 | zoran_restart(zr); | ||
1251 | return; | ||
1252 | } | ||
1253 | |||
1254 | /* | ||
1255 | * First entry: error just happened during normal operation | ||
1256 | * | ||
1257 | * In BUZ_MODE_MOTION_COMPRESS: | ||
1258 | * | ||
1259 | * Possible glitch in TV signal. In this case we should | ||
1260 | * stop the codec and wait for good quality signal before | ||
1261 | * restarting it to avoid further problems | ||
1262 | * | ||
1263 | * In BUZ_MODE_MOTION_DECOMPRESS: | ||
1264 | * | ||
1265 | * Bad JPEG frame: we have to mark it as processed (codec crashed | ||
1266 | * and was not able to do it itself), and to remove it from queue. | ||
1267 | */ | ||
1268 | btand(~ZR36057_JMC_Go_en, ZR36057_JMC); | ||
1269 | udelay(1); | ||
1270 | stat = stat | (post_office_read(zr, 7, 0) & 3) << 8; | ||
1271 | btwrite(0, ZR36057_JPC); | ||
1272 | btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR); | ||
1273 | jpeg_codec_reset(zr); | ||
1274 | jpeg_codec_sleep(zr, 1); | ||
1275 | zr->JPEG_error = 1; | ||
1276 | zr->num_errors++; | ||
1277 | |||
1278 | /* Report error */ | ||
1279 | if (zr36067_debug > 1 && zr->num_errors <= 8) { | ||
1280 | long frame; | ||
1281 | int j; | ||
1282 | |||
1283 | frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME]; | ||
1284 | printk(KERN_ERR | ||
1285 | "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ", | ||
1286 | ZR_DEVNAME(zr), stat, zr->last_isr, | ||
1287 | zr->jpg_que_tail, zr->jpg_dma_tail, | ||
1288 | zr->jpg_dma_head, zr->jpg_que_head, | ||
1289 | zr->jpg_seq_num, frame); | ||
1290 | printk(KERN_INFO "stat_com frames:"); | ||
1291 | for (j = 0; j < BUZ_NUM_STAT_COM; j++) { | ||
1292 | for (i = 0; i < zr->jpg_buffers.num_buffers; i++) { | ||
1293 | if (le32_to_cpu(zr->stat_com[j]) == zr->jpg_buffers.buffer[i].jpg.frag_tab_bus) | ||
1294 | printk(KERN_CONT "% d->%d", j, i); | ||
1295 | } | ||
1296 | } | ||
1297 | printk(KERN_CONT "\n"); | ||
1298 | } | ||
1299 | /* Find an entry in stat_com and rotate contents */ | ||
1300 | if (zr->jpg_settings.TmpDcm == 1) | ||
1301 | i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM; | ||
1302 | else | ||
1303 | i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2; | ||
1304 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) { | ||
1305 | /* Mimic zr36067 operation */ | ||
1306 | zr->stat_com[i] |= cpu_to_le32(1); | ||
1307 | if (zr->jpg_settings.TmpDcm != 1) | ||
1308 | zr->stat_com[i + 1] |= cpu_to_le32(1); | ||
1309 | /* Refill */ | ||
1310 | zoran_reap_stat_com(zr); | ||
1311 | zoran_feed_stat_com(zr); | ||
1312 | wake_up_interruptible(&zr->jpg_capq); | ||
1313 | /* Find an entry in stat_com again after refill */ | ||
1314 | if (zr->jpg_settings.TmpDcm == 1) | ||
1315 | i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM; | ||
1316 | else | ||
1317 | i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2; | ||
1318 | } | ||
1319 | if (i) { | ||
1320 | /* Rotate stat_comm entries to make current entry first */ | ||
1321 | int j; | ||
1322 | __le32 bus_addr[BUZ_NUM_STAT_COM]; | ||
1323 | |||
1324 | /* Here we are copying the stat_com array, which | ||
1325 | * is already in little endian format, so | ||
1326 | * no endian conversions here | ||
1327 | */ | ||
1328 | memcpy(bus_addr, zr->stat_com, sizeof(bus_addr)); | ||
1329 | |||
1330 | for (j = 0; j < BUZ_NUM_STAT_COM; j++) | ||
1331 | zr->stat_com[j] = bus_addr[(i + j) & BUZ_MASK_STAT_COM]; | ||
1332 | |||
1333 | zr->jpg_err_shift += i; | ||
1334 | zr->jpg_err_shift &= BUZ_MASK_STAT_COM; | ||
1335 | } | ||
1336 | if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) | ||
1337 | zr->jpg_err_seq = zr->jpg_seq_num; /* + 1; */ | ||
1338 | zoran_restart(zr); | ||
1339 | } | ||
1340 | |||
1341 | irqreturn_t | ||
1342 | zoran_irq (int irq, | ||
1343 | void *dev_id) | ||
1344 | { | ||
1345 | u32 stat, astat; | ||
1346 | int count; | ||
1347 | struct zoran *zr; | ||
1348 | unsigned long flags; | ||
1349 | |||
1350 | zr = dev_id; | ||
1351 | count = 0; | ||
1352 | |||
1353 | if (zr->testing) { | ||
1354 | /* Testing interrupts */ | ||
1355 | spin_lock_irqsave(&zr->spinlock, flags); | ||
1356 | while ((stat = count_reset_interrupt(zr))) { | ||
1357 | if (count++ > 100) { | ||
1358 | btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR); | ||
1359 | dprintk(1, | ||
1360 | KERN_ERR | ||
1361 | "%s: IRQ lockup while testing, isr=0x%08x, cleared int mask\n", | ||
1362 | ZR_DEVNAME(zr), stat); | ||
1363 | wake_up_interruptible(&zr->test_q); | ||
1364 | } | ||
1365 | } | ||
1366 | zr->last_isr = stat; | ||
1367 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
1368 | return IRQ_HANDLED; | ||
1369 | } | ||
1370 | |||
1371 | spin_lock_irqsave(&zr->spinlock, flags); | ||
1372 | while (1) { | ||
1373 | /* get/clear interrupt status bits */ | ||
1374 | stat = count_reset_interrupt(zr); | ||
1375 | astat = stat & IRQ_MASK; | ||
1376 | if (!astat) { | ||
1377 | break; | ||
1378 | } | ||
1379 | dprintk(4, | ||
1380 | KERN_DEBUG | ||
1381 | "zoran_irq: astat: 0x%08x, mask: 0x%08x\n", | ||
1382 | astat, btread(ZR36057_ICR)); | ||
1383 | if (astat & zr->card.vsync_int) { // SW | ||
1384 | |||
1385 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || | ||
1386 | zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { | ||
1387 | /* count missed interrupts */ | ||
1388 | zr->JPEG_missed++; | ||
1389 | } | ||
1390 | //post_office_read(zr,1,0); | ||
1391 | /* Interrupts may still happen when | ||
1392 | * zr->v4l_memgrab_active is switched off. | ||
1393 | * We simply ignore them */ | ||
1394 | |||
1395 | if (zr->v4l_memgrab_active) { | ||
1396 | /* A lot more checks should be here ... */ | ||
1397 | if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SnapShot) == 0) | ||
1398 | dprintk(1, | ||
1399 | KERN_WARNING | ||
1400 | "%s: BuzIRQ with SnapShot off ???\n", | ||
1401 | ZR_DEVNAME(zr)); | ||
1402 | |||
1403 | if (zr->v4l_grab_frame != NO_GRAB_ACTIVE) { | ||
1404 | /* There is a grab on a frame going on, check if it has finished */ | ||
1405 | if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_FrameGrab) == 0) { | ||
1406 | /* it is finished, notify the user */ | ||
1407 | |||
1408 | zr->v4l_buffers.buffer[zr->v4l_grab_frame].state = BUZ_STATE_DONE; | ||
1409 | zr->v4l_buffers.buffer[zr->v4l_grab_frame].bs.seq = zr->v4l_grab_seq; | ||
1410 | do_gettimeofday(&zr->v4l_buffers.buffer[zr->v4l_grab_frame].bs.timestamp); | ||
1411 | zr->v4l_grab_frame = NO_GRAB_ACTIVE; | ||
1412 | zr->v4l_pend_tail++; | ||
1413 | } | ||
1414 | } | ||
1415 | |||
1416 | if (zr->v4l_grab_frame == NO_GRAB_ACTIVE) | ||
1417 | wake_up_interruptible(&zr->v4l_capq); | ||
1418 | |||
1419 | /* Check if there is another grab queued */ | ||
1420 | |||
1421 | if (zr->v4l_grab_frame == NO_GRAB_ACTIVE && | ||
1422 | zr->v4l_pend_tail != zr->v4l_pend_head) { | ||
1423 | int frame = zr->v4l_pend[zr->v4l_pend_tail & V4L_MASK_FRAME]; | ||
1424 | u32 reg; | ||
1425 | |||
1426 | zr->v4l_grab_frame = frame; | ||
1427 | |||
1428 | /* Set zr36057 video front end and enable video */ | ||
1429 | |||
1430 | /* Buffer address */ | ||
1431 | |||
1432 | reg = zr->v4l_buffers.buffer[frame].v4l.fbuffer_bus; | ||
1433 | btwrite(reg, ZR36057_VDTR); | ||
1434 | if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2) | ||
1435 | reg += zr->v4l_settings.bytesperline; | ||
1436 | btwrite(reg, ZR36057_VDBR); | ||
1437 | |||
1438 | /* video stride, status, and frame grab register */ | ||
1439 | reg = 0; | ||
1440 | if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2) | ||
1441 | reg += zr->v4l_settings.bytesperline; | ||
1442 | reg = (reg << ZR36057_VSSFGR_DispStride); | ||
1443 | reg |= ZR36057_VSSFGR_VidOvf; | ||
1444 | reg |= ZR36057_VSSFGR_SnapShot; | ||
1445 | reg |= ZR36057_VSSFGR_FrameGrab; | ||
1446 | btwrite(reg, ZR36057_VSSFGR); | ||
1447 | |||
1448 | btor(ZR36057_VDCR_VidEn, | ||
1449 | ZR36057_VDCR); | ||
1450 | } | ||
1451 | } | ||
1452 | |||
1453 | /* even if we don't grab, we do want to increment | ||
1454 | * the sequence counter to see lost frames */ | ||
1455 | zr->v4l_grab_seq++; | ||
1456 | } | ||
1457 | #if (IRQ_MASK & ZR36057_ISR_CodRepIRQ) | ||
1458 | if (astat & ZR36057_ISR_CodRepIRQ) { | ||
1459 | zr->intr_counter_CodRepIRQ++; | ||
1460 | IDEBUG(printk(KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n", | ||
1461 | ZR_DEVNAME(zr))); | ||
1462 | btand(~ZR36057_ICR_CodRepIRQ, ZR36057_ICR); | ||
1463 | } | ||
1464 | #endif /* (IRQ_MASK & ZR36057_ISR_CodRepIRQ) */ | ||
1465 | |||
1466 | #if (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) | ||
1467 | if ((astat & ZR36057_ISR_JPEGRepIRQ) && | ||
1468 | (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || | ||
1469 | zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)) { | ||
1470 | if (zr36067_debug > 1 && (!zr->frame_num || zr->JPEG_error)) { | ||
1471 | char sv[BUZ_NUM_STAT_COM + 1]; | ||
1472 | int i; | ||
1473 | |||
1474 | printk(KERN_INFO | ||
1475 | "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n", | ||
1476 | ZR_DEVNAME(zr), stat, | ||
1477 | zr->jpg_settings.odd_even, | ||
1478 | zr->jpg_settings.field_per_buff, | ||
1479 | zr->JPEG_missed); | ||
1480 | |||
1481 | for (i = 0; i < BUZ_NUM_STAT_COM; i++) | ||
1482 | sv[i] = le32_to_cpu(zr->stat_com[i]) & 1 ? '1' : '0'; | ||
1483 | sv[BUZ_NUM_STAT_COM] = 0; | ||
1484 | printk(KERN_INFO | ||
1485 | "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n", | ||
1486 | ZR_DEVNAME(zr), sv, | ||
1487 | zr->jpg_que_tail, | ||
1488 | zr->jpg_dma_tail, | ||
1489 | zr->jpg_dma_head, | ||
1490 | zr->jpg_que_head); | ||
1491 | } else { | ||
1492 | /* Get statistics */ | ||
1493 | if (zr->JPEG_missed > zr->JPEG_max_missed) | ||
1494 | zr->JPEG_max_missed = zr->JPEG_missed; | ||
1495 | if (zr->JPEG_missed < zr->JPEG_min_missed) | ||
1496 | zr->JPEG_min_missed = zr->JPEG_missed; | ||
1497 | } | ||
1498 | |||
1499 | if (zr36067_debug > 2 && zr->frame_num < 6) { | ||
1500 | int i; | ||
1501 | |||
1502 | printk(KERN_INFO "%s: seq=%ld stat_com:", | ||
1503 | ZR_DEVNAME(zr), zr->jpg_seq_num); | ||
1504 | for (i = 0; i < 4; i++) { | ||
1505 | printk(KERN_CONT " %08x", | ||
1506 | le32_to_cpu(zr->stat_com[i])); | ||
1507 | } | ||
1508 | printk(KERN_CONT "\n"); | ||
1509 | } | ||
1510 | zr->frame_num++; | ||
1511 | zr->JPEG_missed = 0; | ||
1512 | zr->JPEG_error = 0; | ||
1513 | zoran_reap_stat_com(zr); | ||
1514 | zoran_feed_stat_com(zr); | ||
1515 | wake_up_interruptible(&zr->jpg_capq); | ||
1516 | } | ||
1517 | #endif /* (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) */ | ||
1518 | |||
1519 | /* DATERR, too many fields missed, error processing */ | ||
1520 | if ((astat & zr->card.jpeg_int) || | ||
1521 | zr->JPEG_missed > 25 || | ||
1522 | zr->JPEG_error == 1 || | ||
1523 | ((zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) && | ||
1524 | (zr->frame_num && (zr->JPEG_missed > zr->jpg_settings.field_per_buff)))) { | ||
1525 | error_handler(zr, astat, stat); | ||
1526 | } | ||
1527 | |||
1528 | count++; | ||
1529 | if (count > 10) { | ||
1530 | dprintk(2, KERN_WARNING "%s: irq loop %d\n", | ||
1531 | ZR_DEVNAME(zr), count); | ||
1532 | if (count > 20) { | ||
1533 | btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR); | ||
1534 | dprintk(2, | ||
1535 | KERN_ERR | ||
1536 | "%s: IRQ lockup, cleared int mask\n", | ||
1537 | ZR_DEVNAME(zr)); | ||
1538 | break; | ||
1539 | } | ||
1540 | } | ||
1541 | zr->last_isr = stat; | ||
1542 | } | ||
1543 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
1544 | |||
1545 | return IRQ_HANDLED; | ||
1546 | } | ||
1547 | |||
1548 | void | ||
1549 | zoran_set_pci_master (struct zoran *zr, | ||
1550 | int set_master) | ||
1551 | { | ||
1552 | if (set_master) { | ||
1553 | pci_set_master(zr->pci_dev); | ||
1554 | } else { | ||
1555 | u16 command; | ||
1556 | |||
1557 | pci_read_config_word(zr->pci_dev, PCI_COMMAND, &command); | ||
1558 | command &= ~PCI_COMMAND_MASTER; | ||
1559 | pci_write_config_word(zr->pci_dev, PCI_COMMAND, command); | ||
1560 | } | ||
1561 | } | ||
1562 | |||
1563 | void | ||
1564 | zoran_init_hardware (struct zoran *zr) | ||
1565 | { | ||
1566 | /* Enable bus-mastering */ | ||
1567 | zoran_set_pci_master(zr, 1); | ||
1568 | |||
1569 | /* Initialize the board */ | ||
1570 | if (zr->card.init) { | ||
1571 | zr->card.init(zr); | ||
1572 | } | ||
1573 | |||
1574 | decoder_call(zr, core, init, 0); | ||
1575 | decoder_call(zr, core, s_std, zr->norm); | ||
1576 | decoder_call(zr, video, s_routing, | ||
1577 | zr->card.input[zr->input].muxsel, 0, 0); | ||
1578 | |||
1579 | encoder_call(zr, core, init, 0); | ||
1580 | encoder_call(zr, video, s_std_output, zr->norm); | ||
1581 | encoder_call(zr, video, s_routing, 0, 0, 0); | ||
1582 | |||
1583 | /* toggle JPEG codec sleep to sync PLL */ | ||
1584 | jpeg_codec_sleep(zr, 1); | ||
1585 | jpeg_codec_sleep(zr, 0); | ||
1586 | |||
1587 | /* set individual interrupt enables (without GIRQ1) | ||
1588 | * but don't global enable until zoran_open() */ | ||
1589 | |||
1590 | //btwrite(IRQ_MASK & ~ZR36057_ISR_GIRQ1, ZR36057_ICR); // SW | ||
1591 | // It looks like using only JPEGRepIRQEn is not always reliable, | ||
1592 | // may be when JPEG codec crashes it won't generate IRQ? So, | ||
1593 | /*CP*/ // btwrite(IRQ_MASK, ZR36057_ICR); // Enable Vsync interrupts too. SM WHY ? LP | ||
1594 | zr36057_init_vfe(zr); | ||
1595 | |||
1596 | zr36057_enable_jpg(zr, BUZ_MODE_IDLE); | ||
1597 | |||
1598 | btwrite(IRQ_MASK, ZR36057_ISR); // Clears interrupts | ||
1599 | } | ||
1600 | |||
1601 | void | ||
1602 | zr36057_restart (struct zoran *zr) | ||
1603 | { | ||
1604 | btwrite(0, ZR36057_SPGPPCR); | ||
1605 | mdelay(1); | ||
1606 | btor(ZR36057_SPGPPCR_SoftReset, ZR36057_SPGPPCR); | ||
1607 | mdelay(1); | ||
1608 | |||
1609 | /* assert P_Reset */ | ||
1610 | btwrite(0, ZR36057_JPC); | ||
1611 | /* set up GPIO direction - all output */ | ||
1612 | btwrite(ZR36057_SPGPPCR_SoftReset | 0, ZR36057_SPGPPCR); | ||
1613 | |||
1614 | /* set up GPIO pins and guest bus timing */ | ||
1615 | btwrite((0x81 << 24) | 0x8888, ZR36057_GPPGCR1); | ||
1616 | } | ||
1617 | |||
1618 | /* | ||
1619 | * initialize video front end | ||
1620 | */ | ||
1621 | |||
1622 | static void | ||
1623 | zr36057_init_vfe (struct zoran *zr) | ||
1624 | { | ||
1625 | u32 reg; | ||
1626 | |||
1627 | reg = btread(ZR36057_VFESPFR); | ||
1628 | reg |= ZR36057_VFESPFR_LittleEndian; | ||
1629 | reg &= ~ZR36057_VFESPFR_VCLKPol; | ||
1630 | reg |= ZR36057_VFESPFR_ExtFl; | ||
1631 | reg |= ZR36057_VFESPFR_TopField; | ||
1632 | btwrite(reg, ZR36057_VFESPFR); | ||
1633 | reg = btread(ZR36057_VDCR); | ||
1634 | if (pci_pci_problems & PCIPCI_TRITON) | ||
1635 | // || zr->revision < 1) // Revision 1 has also Triton support | ||
1636 | reg &= ~ZR36057_VDCR_Triton; | ||
1637 | else | ||
1638 | reg |= ZR36057_VDCR_Triton; | ||
1639 | btwrite(reg, ZR36057_VDCR); | ||
1640 | } | ||
diff --git a/drivers/media/video/zoran/zoran_device.h b/drivers/media/video/zoran/zoran_device.h deleted file mode 100644 index 07f2c23ff740..000000000000 --- a/drivers/media/video/zoran/zoran_device.h +++ /dev/null | |||
@@ -1,95 +0,0 @@ | |||
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 card-specific data and detection | ||
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 | #ifndef __ZORAN_DEVICE_H__ | ||
31 | #define __ZORAN_DEVICE_H__ | ||
32 | |||
33 | /* general purpose I/O */ | ||
34 | extern void GPIO(struct zoran *zr, | ||
35 | int bit, | ||
36 | unsigned int value); | ||
37 | |||
38 | /* codec (or actually: guest bus) access */ | ||
39 | extern int post_office_wait(struct zoran *zr); | ||
40 | extern int post_office_write(struct zoran *zr, | ||
41 | unsigned guest, | ||
42 | unsigned reg, | ||
43 | unsigned value); | ||
44 | extern int post_office_read(struct zoran *zr, | ||
45 | unsigned guest, | ||
46 | unsigned reg); | ||
47 | |||
48 | extern void detect_guest_activity(struct zoran *zr); | ||
49 | |||
50 | extern void jpeg_codec_sleep(struct zoran *zr, | ||
51 | int sleep); | ||
52 | extern int jpeg_codec_reset(struct zoran *zr); | ||
53 | |||
54 | /* zr360x7 access to raw capture */ | ||
55 | extern void zr36057_overlay(struct zoran *zr, | ||
56 | int on); | ||
57 | extern void write_overlay_mask(struct zoran_fh *fh, | ||
58 | struct v4l2_clip *vp, | ||
59 | int count); | ||
60 | extern void zr36057_set_memgrab(struct zoran *zr, | ||
61 | int mode); | ||
62 | extern int wait_grab_pending(struct zoran *zr); | ||
63 | |||
64 | /* interrupts */ | ||
65 | extern void print_interrupts(struct zoran *zr); | ||
66 | extern void clear_interrupt_counters(struct zoran *zr); | ||
67 | extern irqreturn_t zoran_irq(int irq, void *dev_id); | ||
68 | |||
69 | /* JPEG codec access */ | ||
70 | extern void jpeg_start(struct zoran *zr); | ||
71 | extern void zr36057_enable_jpg(struct zoran *zr, | ||
72 | enum zoran_codec_mode mode); | ||
73 | extern void zoran_feed_stat_com(struct zoran *zr); | ||
74 | |||
75 | /* general */ | ||
76 | extern void zoran_set_pci_master(struct zoran *zr, | ||
77 | int set_master); | ||
78 | extern void zoran_init_hardware(struct zoran *zr); | ||
79 | extern void zr36057_restart(struct zoran *zr); | ||
80 | |||
81 | extern const struct zoran_format zoran_formats[]; | ||
82 | |||
83 | extern int v4l_nbufs; | ||
84 | extern int v4l_bufsize; | ||
85 | extern int jpg_nbufs; | ||
86 | extern int jpg_bufsize; | ||
87 | extern int pass_through; | ||
88 | |||
89 | /* i2c */ | ||
90 | #define decoder_call(zr, o, f, args...) \ | ||
91 | v4l2_subdev_call(zr->decoder, o, f, ##args) | ||
92 | #define encoder_call(zr, o, f, args...) \ | ||
93 | v4l2_subdev_call(zr->encoder, o, f, ##args) | ||
94 | |||
95 | #endif /* __ZORAN_DEVICE_H__ */ | ||
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c deleted file mode 100644 index c6ccdeb6d8d6..000000000000 --- a/drivers/media/video/zoran/zoran_driver.c +++ /dev/null | |||
@@ -1,3090 +0,0 @@ | |||
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 | * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx> | ||
7 | * | ||
8 | * Changes for BUZ by Wolfgang Scherr <scherr@net4you.net> | ||
9 | * | ||
10 | * Changes for DC10/DC30 by Laurent Pinchart <laurent.pinchart@skynet.be> | ||
11 | * | ||
12 | * Changes for LML33R10 by Maxim Yevtyushkin <max@linuxmedialabs.com> | ||
13 | * | ||
14 | * Changes for videodev2/v4l2 by Ronald Bultje <rbultje@ronald.bitfreak.net> | ||
15 | * | ||
16 | * Based on | ||
17 | * | ||
18 | * Miro DC10 driver | ||
19 | * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net> | ||
20 | * | ||
21 | * Iomega Buz driver version 1.0 | ||
22 | * Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de> | ||
23 | * | ||
24 | * buz.0.0.3 | ||
25 | * Copyright (C) 1998 Dave Perks <dperks@ibm.net> | ||
26 | * | ||
27 | * bttv - Bt848 frame grabber driver | ||
28 | * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) | ||
29 | * & Marcus Metzler (mocm@thp.uni-koeln.de) | ||
30 | * | ||
31 | * | ||
32 | * This program is free software; you can redistribute it and/or modify | ||
33 | * it under the terms of the GNU General Public License as published by | ||
34 | * the Free Software Foundation; either version 2 of the License, or | ||
35 | * (at your option) any later version. | ||
36 | * | ||
37 | * This program is distributed in the hope that it will be useful, | ||
38 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
39 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
40 | * GNU General Public License for more details. | ||
41 | * | ||
42 | * You should have received a copy of the GNU General Public License | ||
43 | * along with this program; if not, write to the Free Software | ||
44 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
45 | */ | ||
46 | |||
47 | #include <linux/init.h> | ||
48 | #include <linux/module.h> | ||
49 | #include <linux/delay.h> | ||
50 | #include <linux/slab.h> | ||
51 | #include <linux/pci.h> | ||
52 | #include <linux/vmalloc.h> | ||
53 | #include <linux/wait.h> | ||
54 | |||
55 | #include <linux/interrupt.h> | ||
56 | #include <linux/i2c.h> | ||
57 | #include <linux/i2c-algo-bit.h> | ||
58 | |||
59 | #include <linux/spinlock.h> | ||
60 | |||
61 | #include <linux/videodev2.h> | ||
62 | #include <media/v4l2-common.h> | ||
63 | #include <media/v4l2-ioctl.h> | ||
64 | #include "videocodec.h" | ||
65 | |||
66 | #include <asm/byteorder.h> | ||
67 | #include <asm/io.h> | ||
68 | #include <asm/uaccess.h> | ||
69 | #include <linux/proc_fs.h> | ||
70 | |||
71 | #include <linux/mutex.h> | ||
72 | #include "zoran.h" | ||
73 | #include "zoran_device.h" | ||
74 | #include "zoran_card.h" | ||
75 | |||
76 | |||
77 | const struct zoran_format zoran_formats[] = { | ||
78 | { | ||
79 | .name = "15-bit RGB LE", | ||
80 | .fourcc = V4L2_PIX_FMT_RGB555, | ||
81 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
82 | .depth = 15, | ||
83 | .flags = ZORAN_FORMAT_CAPTURE | | ||
84 | ZORAN_FORMAT_OVERLAY, | ||
85 | .vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif| | ||
86 | ZR36057_VFESPFR_LittleEndian, | ||
87 | }, { | ||
88 | .name = "15-bit RGB BE", | ||
89 | .fourcc = V4L2_PIX_FMT_RGB555X, | ||
90 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
91 | .depth = 15, | ||
92 | .flags = ZORAN_FORMAT_CAPTURE | | ||
93 | ZORAN_FORMAT_OVERLAY, | ||
94 | .vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif, | ||
95 | }, { | ||
96 | .name = "16-bit RGB LE", | ||
97 | .fourcc = V4L2_PIX_FMT_RGB565, | ||
98 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
99 | .depth = 16, | ||
100 | .flags = ZORAN_FORMAT_CAPTURE | | ||
101 | ZORAN_FORMAT_OVERLAY, | ||
102 | .vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif| | ||
103 | ZR36057_VFESPFR_LittleEndian, | ||
104 | }, { | ||
105 | .name = "16-bit RGB BE", | ||
106 | .fourcc = V4L2_PIX_FMT_RGB565X, | ||
107 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
108 | .depth = 16, | ||
109 | .flags = ZORAN_FORMAT_CAPTURE | | ||
110 | ZORAN_FORMAT_OVERLAY, | ||
111 | .vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif, | ||
112 | }, { | ||
113 | .name = "24-bit RGB", | ||
114 | .fourcc = V4L2_PIX_FMT_BGR24, | ||
115 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
116 | .depth = 24, | ||
117 | .flags = ZORAN_FORMAT_CAPTURE | | ||
118 | ZORAN_FORMAT_OVERLAY, | ||
119 | .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_Pack24, | ||
120 | }, { | ||
121 | .name = "32-bit RGB LE", | ||
122 | .fourcc = V4L2_PIX_FMT_BGR32, | ||
123 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
124 | .depth = 32, | ||
125 | .flags = ZORAN_FORMAT_CAPTURE | | ||
126 | ZORAN_FORMAT_OVERLAY, | ||
127 | .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_LittleEndian, | ||
128 | }, { | ||
129 | .name = "32-bit RGB BE", | ||
130 | .fourcc = V4L2_PIX_FMT_RGB32, | ||
131 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
132 | .depth = 32, | ||
133 | .flags = ZORAN_FORMAT_CAPTURE | | ||
134 | ZORAN_FORMAT_OVERLAY, | ||
135 | .vfespfr = ZR36057_VFESPFR_RGB888, | ||
136 | }, { | ||
137 | .name = "4:2:2, packed, YUYV", | ||
138 | .fourcc = V4L2_PIX_FMT_YUYV, | ||
139 | .colorspace = V4L2_COLORSPACE_SMPTE170M, | ||
140 | .depth = 16, | ||
141 | .flags = ZORAN_FORMAT_CAPTURE | | ||
142 | ZORAN_FORMAT_OVERLAY, | ||
143 | .vfespfr = ZR36057_VFESPFR_YUV422, | ||
144 | }, { | ||
145 | .name = "4:2:2, packed, UYVY", | ||
146 | .fourcc = V4L2_PIX_FMT_UYVY, | ||
147 | .colorspace = V4L2_COLORSPACE_SMPTE170M, | ||
148 | .depth = 16, | ||
149 | .flags = ZORAN_FORMAT_CAPTURE | | ||
150 | ZORAN_FORMAT_OVERLAY, | ||
151 | .vfespfr = ZR36057_VFESPFR_YUV422|ZR36057_VFESPFR_LittleEndian, | ||
152 | }, { | ||
153 | .name = "Hardware-encoded Motion-JPEG", | ||
154 | .fourcc = V4L2_PIX_FMT_MJPEG, | ||
155 | .colorspace = V4L2_COLORSPACE_SMPTE170M, | ||
156 | .depth = 0, | ||
157 | .flags = ZORAN_FORMAT_CAPTURE | | ||
158 | ZORAN_FORMAT_PLAYBACK | | ||
159 | ZORAN_FORMAT_COMPRESSED, | ||
160 | } | ||
161 | }; | ||
162 | #define NUM_FORMATS ARRAY_SIZE(zoran_formats) | ||
163 | |||
164 | /* small helper function for calculating buffersizes for v4l2 | ||
165 | * we calculate the nearest higher power-of-two, which | ||
166 | * will be the recommended buffersize */ | ||
167 | static __u32 | ||
168 | zoran_v4l2_calc_bufsize (struct zoran_jpg_settings *settings) | ||
169 | { | ||
170 | __u8 div = settings->VerDcm * settings->HorDcm * settings->TmpDcm; | ||
171 | __u32 num = (1024 * 512) / (div); | ||
172 | __u32 result = 2; | ||
173 | |||
174 | num--; | ||
175 | while (num) { | ||
176 | num >>= 1; | ||
177 | result <<= 1; | ||
178 | } | ||
179 | |||
180 | if (result > jpg_bufsize) | ||
181 | return jpg_bufsize; | ||
182 | if (result < 8192) | ||
183 | return 8192; | ||
184 | return result; | ||
185 | } | ||
186 | |||
187 | /* forward references */ | ||
188 | static void v4l_fbuffer_free(struct zoran_fh *fh); | ||
189 | static void jpg_fbuffer_free(struct zoran_fh *fh); | ||
190 | |||
191 | /* Set mapping mode */ | ||
192 | static void map_mode_raw(struct zoran_fh *fh) | ||
193 | { | ||
194 | fh->map_mode = ZORAN_MAP_MODE_RAW; | ||
195 | fh->buffers.buffer_size = v4l_bufsize; | ||
196 | fh->buffers.num_buffers = v4l_nbufs; | ||
197 | } | ||
198 | static void map_mode_jpg(struct zoran_fh *fh, int play) | ||
199 | { | ||
200 | fh->map_mode = play ? ZORAN_MAP_MODE_JPG_PLAY : ZORAN_MAP_MODE_JPG_REC; | ||
201 | fh->buffers.buffer_size = jpg_bufsize; | ||
202 | fh->buffers.num_buffers = jpg_nbufs; | ||
203 | } | ||
204 | static inline const char *mode_name(enum zoran_map_mode mode) | ||
205 | { | ||
206 | return mode == ZORAN_MAP_MODE_RAW ? "V4L" : "JPG"; | ||
207 | } | ||
208 | |||
209 | /* | ||
210 | * Allocate the V4L grab buffers | ||
211 | * | ||
212 | * These have to be pysically contiguous. | ||
213 | */ | ||
214 | |||
215 | static int v4l_fbuffer_alloc(struct zoran_fh *fh) | ||
216 | { | ||
217 | struct zoran *zr = fh->zr; | ||
218 | int i, off; | ||
219 | unsigned char *mem; | ||
220 | |||
221 | for (i = 0; i < fh->buffers.num_buffers; i++) { | ||
222 | if (fh->buffers.buffer[i].v4l.fbuffer) | ||
223 | dprintk(2, | ||
224 | KERN_WARNING | ||
225 | "%s: %s - buffer %d already allocated!?\n", | ||
226 | ZR_DEVNAME(zr), __func__, i); | ||
227 | |||
228 | //udelay(20); | ||
229 | mem = kmalloc(fh->buffers.buffer_size, | ||
230 | GFP_KERNEL | __GFP_NOWARN); | ||
231 | if (!mem) { | ||
232 | dprintk(1, | ||
233 | KERN_ERR | ||
234 | "%s: %s - kmalloc for V4L buf %d failed\n", | ||
235 | ZR_DEVNAME(zr), __func__, i); | ||
236 | v4l_fbuffer_free(fh); | ||
237 | return -ENOBUFS; | ||
238 | } | ||
239 | fh->buffers.buffer[i].v4l.fbuffer = mem; | ||
240 | fh->buffers.buffer[i].v4l.fbuffer_phys = virt_to_phys(mem); | ||
241 | fh->buffers.buffer[i].v4l.fbuffer_bus = virt_to_bus(mem); | ||
242 | for (off = 0; off < fh->buffers.buffer_size; | ||
243 | off += PAGE_SIZE) | ||
244 | SetPageReserved(virt_to_page(mem + off)); | ||
245 | dprintk(4, | ||
246 | KERN_INFO | ||
247 | "%s: %s - V4L frame %d mem 0x%lx (bus: 0x%llx)\n", | ||
248 | ZR_DEVNAME(zr), __func__, i, (unsigned long) mem, | ||
249 | (unsigned long long)virt_to_bus(mem)); | ||
250 | } | ||
251 | |||
252 | fh->buffers.allocated = 1; | ||
253 | |||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | /* free the V4L grab buffers */ | ||
258 | static void v4l_fbuffer_free(struct zoran_fh *fh) | ||
259 | { | ||
260 | struct zoran *zr = fh->zr; | ||
261 | int i, off; | ||
262 | unsigned char *mem; | ||
263 | |||
264 | dprintk(4, KERN_INFO "%s: %s\n", ZR_DEVNAME(zr), __func__); | ||
265 | |||
266 | for (i = 0; i < fh->buffers.num_buffers; i++) { | ||
267 | if (!fh->buffers.buffer[i].v4l.fbuffer) | ||
268 | continue; | ||
269 | |||
270 | mem = fh->buffers.buffer[i].v4l.fbuffer; | ||
271 | for (off = 0; off < fh->buffers.buffer_size; | ||
272 | off += PAGE_SIZE) | ||
273 | ClearPageReserved(virt_to_page(mem + off)); | ||
274 | kfree(fh->buffers.buffer[i].v4l.fbuffer); | ||
275 | fh->buffers.buffer[i].v4l.fbuffer = NULL; | ||
276 | } | ||
277 | |||
278 | fh->buffers.allocated = 0; | ||
279 | } | ||
280 | |||
281 | /* | ||
282 | * Allocate the MJPEG grab buffers. | ||
283 | * | ||
284 | * If a Natoma chipset is present and this is a revision 1 zr36057, | ||
285 | * each MJPEG buffer needs to be physically contiguous. | ||
286 | * (RJ: This statement is from Dave Perks' original driver, | ||
287 | * I could never check it because I have a zr36067) | ||
288 | * | ||
289 | * RJ: The contents grab buffers needs never be accessed in the driver. | ||
290 | * Therefore there is no need to allocate them with vmalloc in order | ||
291 | * to get a contiguous virtual memory space. | ||
292 | * I don't understand why many other drivers first allocate them with | ||
293 | * vmalloc (which uses internally also get_zeroed_page, but delivers you | ||
294 | * virtual addresses) and then again have to make a lot of efforts | ||
295 | * to get the physical address. | ||
296 | * | ||
297 | * Ben Capper: | ||
298 | * On big-endian architectures (such as ppc) some extra steps | ||
299 | * are needed. When reading and writing to the stat_com array | ||
300 | * and fragment buffers, the device expects to see little- | ||
301 | * endian values. The use of cpu_to_le32() and le32_to_cpu() | ||
302 | * in this function (and one or two others in zoran_device.c) | ||
303 | * ensure that these values are always stored in little-endian | ||
304 | * form, regardless of architecture. The zr36057 does Very Bad | ||
305 | * Things on big endian architectures if the stat_com array | ||
306 | * and fragment buffers are not little-endian. | ||
307 | */ | ||
308 | |||
309 | static int jpg_fbuffer_alloc(struct zoran_fh *fh) | ||
310 | { | ||
311 | struct zoran *zr = fh->zr; | ||
312 | int i, j, off; | ||
313 | u8 *mem; | ||
314 | |||
315 | for (i = 0; i < fh->buffers.num_buffers; i++) { | ||
316 | if (fh->buffers.buffer[i].jpg.frag_tab) | ||
317 | dprintk(2, | ||
318 | KERN_WARNING | ||
319 | "%s: %s - buffer %d already allocated!?\n", | ||
320 | ZR_DEVNAME(zr), __func__, i); | ||
321 | |||
322 | /* Allocate fragment table for this buffer */ | ||
323 | |||
324 | mem = (void *)get_zeroed_page(GFP_KERNEL); | ||
325 | if (!mem) { | ||
326 | dprintk(1, | ||
327 | KERN_ERR | ||
328 | "%s: %s - get_zeroed_page (frag_tab) failed for buffer %d\n", | ||
329 | ZR_DEVNAME(zr), __func__, i); | ||
330 | jpg_fbuffer_free(fh); | ||
331 | return -ENOBUFS; | ||
332 | } | ||
333 | fh->buffers.buffer[i].jpg.frag_tab = (__le32 *)mem; | ||
334 | fh->buffers.buffer[i].jpg.frag_tab_bus = virt_to_bus(mem); | ||
335 | |||
336 | if (fh->buffers.need_contiguous) { | ||
337 | mem = kmalloc(fh->buffers.buffer_size, GFP_KERNEL); | ||
338 | if (mem == NULL) { | ||
339 | dprintk(1, | ||
340 | KERN_ERR | ||
341 | "%s: %s - kmalloc failed for buffer %d\n", | ||
342 | ZR_DEVNAME(zr), __func__, i); | ||
343 | jpg_fbuffer_free(fh); | ||
344 | return -ENOBUFS; | ||
345 | } | ||
346 | fh->buffers.buffer[i].jpg.frag_tab[0] = | ||
347 | cpu_to_le32(virt_to_bus(mem)); | ||
348 | fh->buffers.buffer[i].jpg.frag_tab[1] = | ||
349 | cpu_to_le32((fh->buffers.buffer_size >> 1) | 1); | ||
350 | for (off = 0; off < fh->buffers.buffer_size; off += PAGE_SIZE) | ||
351 | SetPageReserved(virt_to_page(mem + off)); | ||
352 | } else { | ||
353 | /* jpg_bufsize is already page aligned */ | ||
354 | for (j = 0; j < fh->buffers.buffer_size / PAGE_SIZE; j++) { | ||
355 | mem = (void *)get_zeroed_page(GFP_KERNEL); | ||
356 | if (mem == NULL) { | ||
357 | dprintk(1, | ||
358 | KERN_ERR | ||
359 | "%s: %s - get_zeroed_page failed for buffer %d\n", | ||
360 | ZR_DEVNAME(zr), __func__, i); | ||
361 | jpg_fbuffer_free(fh); | ||
362 | return -ENOBUFS; | ||
363 | } | ||
364 | |||
365 | fh->buffers.buffer[i].jpg.frag_tab[2 * j] = | ||
366 | cpu_to_le32(virt_to_bus(mem)); | ||
367 | fh->buffers.buffer[i].jpg.frag_tab[2 * j + 1] = | ||
368 | cpu_to_le32((PAGE_SIZE >> 2) << 1); | ||
369 | SetPageReserved(virt_to_page(mem)); | ||
370 | } | ||
371 | |||
372 | fh->buffers.buffer[i].jpg.frag_tab[2 * j - 1] |= cpu_to_le32(1); | ||
373 | } | ||
374 | } | ||
375 | |||
376 | dprintk(4, | ||
377 | KERN_DEBUG "%s: %s - %d KB allocated\n", | ||
378 | ZR_DEVNAME(zr), __func__, | ||
379 | (fh->buffers.num_buffers * fh->buffers.buffer_size) >> 10); | ||
380 | |||
381 | fh->buffers.allocated = 1; | ||
382 | |||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | /* free the MJPEG grab buffers */ | ||
387 | static void jpg_fbuffer_free(struct zoran_fh *fh) | ||
388 | { | ||
389 | struct zoran *zr = fh->zr; | ||
390 | int i, j, off; | ||
391 | unsigned char *mem; | ||
392 | __le32 frag_tab; | ||
393 | struct zoran_buffer *buffer; | ||
394 | |||
395 | dprintk(4, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__); | ||
396 | |||
397 | for (i = 0, buffer = &fh->buffers.buffer[0]; | ||
398 | i < fh->buffers.num_buffers; i++, buffer++) { | ||
399 | if (!buffer->jpg.frag_tab) | ||
400 | continue; | ||
401 | |||
402 | if (fh->buffers.need_contiguous) { | ||
403 | frag_tab = buffer->jpg.frag_tab[0]; | ||
404 | |||
405 | if (frag_tab) { | ||
406 | mem = bus_to_virt(le32_to_cpu(frag_tab)); | ||
407 | for (off = 0; off < fh->buffers.buffer_size; off += PAGE_SIZE) | ||
408 | ClearPageReserved(virt_to_page(mem + off)); | ||
409 | kfree(mem); | ||
410 | buffer->jpg.frag_tab[0] = 0; | ||
411 | buffer->jpg.frag_tab[1] = 0; | ||
412 | } | ||
413 | } else { | ||
414 | for (j = 0; j < fh->buffers.buffer_size / PAGE_SIZE; j++) { | ||
415 | frag_tab = buffer->jpg.frag_tab[2 * j]; | ||
416 | |||
417 | if (!frag_tab) | ||
418 | break; | ||
419 | ClearPageReserved(virt_to_page(bus_to_virt(le32_to_cpu(frag_tab)))); | ||
420 | free_page((unsigned long)bus_to_virt(le32_to_cpu(frag_tab))); | ||
421 | buffer->jpg.frag_tab[2 * j] = 0; | ||
422 | buffer->jpg.frag_tab[2 * j + 1] = 0; | ||
423 | } | ||
424 | } | ||
425 | |||
426 | free_page((unsigned long)buffer->jpg.frag_tab); | ||
427 | buffer->jpg.frag_tab = NULL; | ||
428 | } | ||
429 | |||
430 | fh->buffers.allocated = 0; | ||
431 | } | ||
432 | |||
433 | /* | ||
434 | * V4L Buffer grabbing | ||
435 | */ | ||
436 | |||
437 | static int | ||
438 | zoran_v4l_set_format (struct zoran_fh *fh, | ||
439 | int width, | ||
440 | int height, | ||
441 | const struct zoran_format *format) | ||
442 | { | ||
443 | struct zoran *zr = fh->zr; | ||
444 | int bpp; | ||
445 | |||
446 | /* Check size and format of the grab wanted */ | ||
447 | |||
448 | if (height < BUZ_MIN_HEIGHT || width < BUZ_MIN_WIDTH || | ||
449 | height > BUZ_MAX_HEIGHT || width > BUZ_MAX_WIDTH) { | ||
450 | dprintk(1, | ||
451 | KERN_ERR | ||
452 | "%s: %s - wrong frame size (%dx%d)\n", | ||
453 | ZR_DEVNAME(zr), __func__, width, height); | ||
454 | return -EINVAL; | ||
455 | } | ||
456 | |||
457 | bpp = (format->depth + 7) / 8; | ||
458 | |||
459 | /* Check against available buffer size */ | ||
460 | if (height * width * bpp > fh->buffers.buffer_size) { | ||
461 | dprintk(1, | ||
462 | KERN_ERR | ||
463 | "%s: %s - video buffer size (%d kB) is too small\n", | ||
464 | ZR_DEVNAME(zr), __func__, fh->buffers.buffer_size >> 10); | ||
465 | return -EINVAL; | ||
466 | } | ||
467 | |||
468 | /* The video front end needs 4-byte alinged line sizes */ | ||
469 | |||
470 | if ((bpp == 2 && (width & 1)) || (bpp == 3 && (width & 3))) { | ||
471 | dprintk(1, | ||
472 | KERN_ERR | ||
473 | "%s: %s - wrong frame alignment\n", | ||
474 | ZR_DEVNAME(zr), __func__); | ||
475 | return -EINVAL; | ||
476 | } | ||
477 | |||
478 | fh->v4l_settings.width = width; | ||
479 | fh->v4l_settings.height = height; | ||
480 | fh->v4l_settings.format = format; | ||
481 | fh->v4l_settings.bytesperline = bpp * fh->v4l_settings.width; | ||
482 | |||
483 | return 0; | ||
484 | } | ||
485 | |||
486 | static int zoran_v4l_queue_frame(struct zoran_fh *fh, int num) | ||
487 | { | ||
488 | struct zoran *zr = fh->zr; | ||
489 | unsigned long flags; | ||
490 | int res = 0; | ||
491 | |||
492 | if (!fh->buffers.allocated) { | ||
493 | dprintk(1, | ||
494 | KERN_ERR | ||
495 | "%s: %s - buffers not yet allocated\n", | ||
496 | ZR_DEVNAME(zr), __func__); | ||
497 | res = -ENOMEM; | ||
498 | } | ||
499 | |||
500 | /* No grabbing outside the buffer range! */ | ||
501 | if (num >= fh->buffers.num_buffers || num < 0) { | ||
502 | dprintk(1, | ||
503 | KERN_ERR | ||
504 | "%s: %s - buffer %d is out of range\n", | ||
505 | ZR_DEVNAME(zr), __func__, num); | ||
506 | res = -EINVAL; | ||
507 | } | ||
508 | |||
509 | spin_lock_irqsave(&zr->spinlock, flags); | ||
510 | |||
511 | if (fh->buffers.active == ZORAN_FREE) { | ||
512 | if (zr->v4l_buffers.active == ZORAN_FREE) { | ||
513 | zr->v4l_buffers = fh->buffers; | ||
514 | fh->buffers.active = ZORAN_ACTIVE; | ||
515 | } else { | ||
516 | dprintk(1, | ||
517 | KERN_ERR | ||
518 | "%s: %s - another session is already capturing\n", | ||
519 | ZR_DEVNAME(zr), __func__); | ||
520 | res = -EBUSY; | ||
521 | } | ||
522 | } | ||
523 | |||
524 | /* make sure a grab isn't going on currently with this buffer */ | ||
525 | if (!res) { | ||
526 | switch (zr->v4l_buffers.buffer[num].state) { | ||
527 | default: | ||
528 | case BUZ_STATE_PEND: | ||
529 | if (zr->v4l_buffers.active == ZORAN_FREE) { | ||
530 | fh->buffers.active = ZORAN_FREE; | ||
531 | zr->v4l_buffers.allocated = 0; | ||
532 | } | ||
533 | res = -EBUSY; /* what are you doing? */ | ||
534 | break; | ||
535 | case BUZ_STATE_DONE: | ||
536 | dprintk(2, | ||
537 | KERN_WARNING | ||
538 | "%s: %s - queueing buffer %d in state DONE!?\n", | ||
539 | ZR_DEVNAME(zr), __func__, num); | ||
540 | case BUZ_STATE_USER: | ||
541 | /* since there is at least one unused buffer there's room for at least | ||
542 | * one more pend[] entry */ | ||
543 | zr->v4l_pend[zr->v4l_pend_head++ & V4L_MASK_FRAME] = num; | ||
544 | zr->v4l_buffers.buffer[num].state = BUZ_STATE_PEND; | ||
545 | zr->v4l_buffers.buffer[num].bs.length = | ||
546 | fh->v4l_settings.bytesperline * | ||
547 | zr->v4l_settings.height; | ||
548 | fh->buffers.buffer[num] = zr->v4l_buffers.buffer[num]; | ||
549 | break; | ||
550 | } | ||
551 | } | ||
552 | |||
553 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
554 | |||
555 | if (!res && zr->v4l_buffers.active == ZORAN_FREE) | ||
556 | zr->v4l_buffers.active = fh->buffers.active; | ||
557 | |||
558 | return res; | ||
559 | } | ||
560 | |||
561 | /* | ||
562 | * Sync on a V4L buffer | ||
563 | */ | ||
564 | |||
565 | static int v4l_sync(struct zoran_fh *fh, int frame) | ||
566 | { | ||
567 | struct zoran *zr = fh->zr; | ||
568 | unsigned long flags; | ||
569 | |||
570 | if (fh->buffers.active == ZORAN_FREE) { | ||
571 | dprintk(1, | ||
572 | KERN_ERR | ||
573 | "%s: %s - no grab active for this session\n", | ||
574 | ZR_DEVNAME(zr), __func__); | ||
575 | return -EINVAL; | ||
576 | } | ||
577 | |||
578 | /* check passed-in frame number */ | ||
579 | if (frame >= fh->buffers.num_buffers || frame < 0) { | ||
580 | dprintk(1, | ||
581 | KERN_ERR "%s: %s - frame %d is invalid\n", | ||
582 | ZR_DEVNAME(zr), __func__, frame); | ||
583 | return -EINVAL; | ||
584 | } | ||
585 | |||
586 | /* Check if is buffer was queued at all */ | ||
587 | if (zr->v4l_buffers.buffer[frame].state == BUZ_STATE_USER) { | ||
588 | dprintk(1, | ||
589 | KERN_ERR | ||
590 | "%s: %s - attempt to sync on a buffer which was not queued?\n", | ||
591 | ZR_DEVNAME(zr), __func__); | ||
592 | return -EPROTO; | ||
593 | } | ||
594 | |||
595 | /* wait on this buffer to get ready */ | ||
596 | if (!wait_event_interruptible_timeout(zr->v4l_capq, | ||
597 | (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_PEND), 10*HZ)) | ||
598 | return -ETIME; | ||
599 | if (signal_pending(current)) | ||
600 | return -ERESTARTSYS; | ||
601 | |||
602 | /* buffer should now be in BUZ_STATE_DONE */ | ||
603 | if (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_DONE) | ||
604 | dprintk(2, | ||
605 | KERN_ERR "%s: %s - internal state error\n", | ||
606 | ZR_DEVNAME(zr), __func__); | ||
607 | |||
608 | zr->v4l_buffers.buffer[frame].state = BUZ_STATE_USER; | ||
609 | fh->buffers.buffer[frame] = zr->v4l_buffers.buffer[frame]; | ||
610 | |||
611 | spin_lock_irqsave(&zr->spinlock, flags); | ||
612 | |||
613 | /* Check if streaming capture has finished */ | ||
614 | if (zr->v4l_pend_tail == zr->v4l_pend_head) { | ||
615 | zr36057_set_memgrab(zr, 0); | ||
616 | if (zr->v4l_buffers.active == ZORAN_ACTIVE) { | ||
617 | fh->buffers.active = zr->v4l_buffers.active = ZORAN_FREE; | ||
618 | zr->v4l_buffers.allocated = 0; | ||
619 | } | ||
620 | } | ||
621 | |||
622 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
623 | |||
624 | return 0; | ||
625 | } | ||
626 | |||
627 | /* | ||
628 | * Queue a MJPEG buffer for capture/playback | ||
629 | */ | ||
630 | |||
631 | static int zoran_jpg_queue_frame(struct zoran_fh *fh, int num, | ||
632 | enum zoran_codec_mode mode) | ||
633 | { | ||
634 | struct zoran *zr = fh->zr; | ||
635 | unsigned long flags; | ||
636 | int res = 0; | ||
637 | |||
638 | /* Check if buffers are allocated */ | ||
639 | if (!fh->buffers.allocated) { | ||
640 | dprintk(1, | ||
641 | KERN_ERR | ||
642 | "%s: %s - buffers not yet allocated\n", | ||
643 | ZR_DEVNAME(zr), __func__); | ||
644 | return -ENOMEM; | ||
645 | } | ||
646 | |||
647 | /* No grabbing outside the buffer range! */ | ||
648 | if (num >= fh->buffers.num_buffers || num < 0) { | ||
649 | dprintk(1, | ||
650 | KERN_ERR | ||
651 | "%s: %s - buffer %d out of range\n", | ||
652 | ZR_DEVNAME(zr), __func__, num); | ||
653 | return -EINVAL; | ||
654 | } | ||
655 | |||
656 | /* what is the codec mode right now? */ | ||
657 | if (zr->codec_mode == BUZ_MODE_IDLE) { | ||
658 | zr->jpg_settings = fh->jpg_settings; | ||
659 | } else if (zr->codec_mode != mode) { | ||
660 | /* wrong codec mode active - invalid */ | ||
661 | dprintk(1, | ||
662 | KERN_ERR | ||
663 | "%s: %s - codec in wrong mode\n", | ||
664 | ZR_DEVNAME(zr), __func__); | ||
665 | return -EINVAL; | ||
666 | } | ||
667 | |||
668 | if (fh->buffers.active == ZORAN_FREE) { | ||
669 | if (zr->jpg_buffers.active == ZORAN_FREE) { | ||
670 | zr->jpg_buffers = fh->buffers; | ||
671 | fh->buffers.active = ZORAN_ACTIVE; | ||
672 | } else { | ||
673 | dprintk(1, | ||
674 | KERN_ERR | ||
675 | "%s: %s - another session is already capturing\n", | ||
676 | ZR_DEVNAME(zr), __func__); | ||
677 | res = -EBUSY; | ||
678 | } | ||
679 | } | ||
680 | |||
681 | if (!res && zr->codec_mode == BUZ_MODE_IDLE) { | ||
682 | /* Ok load up the jpeg codec */ | ||
683 | zr36057_enable_jpg(zr, mode); | ||
684 | } | ||
685 | |||
686 | spin_lock_irqsave(&zr->spinlock, flags); | ||
687 | |||
688 | if (!res) { | ||
689 | switch (zr->jpg_buffers.buffer[num].state) { | ||
690 | case BUZ_STATE_DONE: | ||
691 | dprintk(2, | ||
692 | KERN_WARNING | ||
693 | "%s: %s - queing frame in BUZ_STATE_DONE state!?\n", | ||
694 | ZR_DEVNAME(zr), __func__); | ||
695 | case BUZ_STATE_USER: | ||
696 | /* since there is at least one unused buffer there's room for at | ||
697 | *least one more pend[] entry */ | ||
698 | zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] = num; | ||
699 | zr->jpg_buffers.buffer[num].state = BUZ_STATE_PEND; | ||
700 | fh->buffers.buffer[num] = zr->jpg_buffers.buffer[num]; | ||
701 | zoran_feed_stat_com(zr); | ||
702 | break; | ||
703 | default: | ||
704 | case BUZ_STATE_DMA: | ||
705 | case BUZ_STATE_PEND: | ||
706 | if (zr->jpg_buffers.active == ZORAN_FREE) { | ||
707 | fh->buffers.active = ZORAN_FREE; | ||
708 | zr->jpg_buffers.allocated = 0; | ||
709 | } | ||
710 | res = -EBUSY; /* what are you doing? */ | ||
711 | break; | ||
712 | } | ||
713 | } | ||
714 | |||
715 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
716 | |||
717 | if (!res && zr->jpg_buffers.active == ZORAN_FREE) | ||
718 | zr->jpg_buffers.active = fh->buffers.active; | ||
719 | |||
720 | return res; | ||
721 | } | ||
722 | |||
723 | static int jpg_qbuf(struct zoran_fh *fh, int frame, enum zoran_codec_mode mode) | ||
724 | { | ||
725 | struct zoran *zr = fh->zr; | ||
726 | int res = 0; | ||
727 | |||
728 | /* Does the user want to stop streaming? */ | ||
729 | if (frame < 0) { | ||
730 | if (zr->codec_mode == mode) { | ||
731 | if (fh->buffers.active == ZORAN_FREE) { | ||
732 | dprintk(1, | ||
733 | KERN_ERR | ||
734 | "%s: %s(-1) - session not active\n", | ||
735 | ZR_DEVNAME(zr), __func__); | ||
736 | return -EINVAL; | ||
737 | } | ||
738 | fh->buffers.active = zr->jpg_buffers.active = ZORAN_FREE; | ||
739 | zr->jpg_buffers.allocated = 0; | ||
740 | zr36057_enable_jpg(zr, BUZ_MODE_IDLE); | ||
741 | return 0; | ||
742 | } else { | ||
743 | dprintk(1, | ||
744 | KERN_ERR | ||
745 | "%s: %s - stop streaming but not in streaming mode\n", | ||
746 | ZR_DEVNAME(zr), __func__); | ||
747 | return -EINVAL; | ||
748 | } | ||
749 | } | ||
750 | |||
751 | if ((res = zoran_jpg_queue_frame(fh, frame, mode))) | ||
752 | return res; | ||
753 | |||
754 | /* Start the jpeg codec when the first frame is queued */ | ||
755 | if (!res && zr->jpg_que_head == 1) | ||
756 | jpeg_start(zr); | ||
757 | |||
758 | return res; | ||
759 | } | ||
760 | |||
761 | /* | ||
762 | * Sync on a MJPEG buffer | ||
763 | */ | ||
764 | |||
765 | static int jpg_sync(struct zoran_fh *fh, struct zoran_sync *bs) | ||
766 | { | ||
767 | struct zoran *zr = fh->zr; | ||
768 | unsigned long flags; | ||
769 | int frame; | ||
770 | |||
771 | if (fh->buffers.active == ZORAN_FREE) { | ||
772 | dprintk(1, | ||
773 | KERN_ERR | ||
774 | "%s: %s - capture is not currently active\n", | ||
775 | ZR_DEVNAME(zr), __func__); | ||
776 | return -EINVAL; | ||
777 | } | ||
778 | if (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS && | ||
779 | zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) { | ||
780 | dprintk(1, | ||
781 | KERN_ERR | ||
782 | "%s: %s - codec not in streaming mode\n", | ||
783 | ZR_DEVNAME(zr), __func__); | ||
784 | return -EINVAL; | ||
785 | } | ||
786 | if (!wait_event_interruptible_timeout(zr->jpg_capq, | ||
787 | (zr->jpg_que_tail != zr->jpg_dma_tail || | ||
788 | zr->jpg_dma_tail == zr->jpg_dma_head), | ||
789 | 10*HZ)) { | ||
790 | int isr; | ||
791 | |||
792 | btand(~ZR36057_JMC_Go_en, ZR36057_JMC); | ||
793 | udelay(1); | ||
794 | zr->codec->control(zr->codec, CODEC_G_STATUS, | ||
795 | sizeof(isr), &isr); | ||
796 | dprintk(1, | ||
797 | KERN_ERR | ||
798 | "%s: %s - timeout: codec isr=0x%02x\n", | ||
799 | ZR_DEVNAME(zr), __func__, isr); | ||
800 | |||
801 | return -ETIME; | ||
802 | |||
803 | } | ||
804 | if (signal_pending(current)) | ||
805 | return -ERESTARTSYS; | ||
806 | |||
807 | spin_lock_irqsave(&zr->spinlock, flags); | ||
808 | |||
809 | if (zr->jpg_dma_tail != zr->jpg_dma_head) | ||
810 | frame = zr->jpg_pend[zr->jpg_que_tail++ & BUZ_MASK_FRAME]; | ||
811 | else | ||
812 | frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME]; | ||
813 | |||
814 | /* buffer should now be in BUZ_STATE_DONE */ | ||
815 | if (zr->jpg_buffers.buffer[frame].state != BUZ_STATE_DONE) | ||
816 | dprintk(2, | ||
817 | KERN_ERR "%s: %s - internal state error\n", | ||
818 | ZR_DEVNAME(zr), __func__); | ||
819 | |||
820 | *bs = zr->jpg_buffers.buffer[frame].bs; | ||
821 | bs->frame = frame; | ||
822 | zr->jpg_buffers.buffer[frame].state = BUZ_STATE_USER; | ||
823 | fh->buffers.buffer[frame] = zr->jpg_buffers.buffer[frame]; | ||
824 | |||
825 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
826 | |||
827 | return 0; | ||
828 | } | ||
829 | |||
830 | static void zoran_open_init_session(struct zoran_fh *fh) | ||
831 | { | ||
832 | int i; | ||
833 | struct zoran *zr = fh->zr; | ||
834 | |||
835 | /* Per default, map the V4L Buffers */ | ||
836 | map_mode_raw(fh); | ||
837 | |||
838 | /* take over the card's current settings */ | ||
839 | fh->overlay_settings = zr->overlay_settings; | ||
840 | fh->overlay_settings.is_set = 0; | ||
841 | fh->overlay_settings.format = zr->overlay_settings.format; | ||
842 | fh->overlay_active = ZORAN_FREE; | ||
843 | |||
844 | /* v4l settings */ | ||
845 | fh->v4l_settings = zr->v4l_settings; | ||
846 | /* jpg settings */ | ||
847 | fh->jpg_settings = zr->jpg_settings; | ||
848 | |||
849 | /* buffers */ | ||
850 | memset(&fh->buffers, 0, sizeof(fh->buffers)); | ||
851 | for (i = 0; i < MAX_FRAME; i++) { | ||
852 | fh->buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */ | ||
853 | fh->buffers.buffer[i].bs.frame = i; | ||
854 | } | ||
855 | fh->buffers.allocated = 0; | ||
856 | fh->buffers.active = ZORAN_FREE; | ||
857 | } | ||
858 | |||
859 | static void zoran_close_end_session(struct zoran_fh *fh) | ||
860 | { | ||
861 | struct zoran *zr = fh->zr; | ||
862 | |||
863 | /* overlay */ | ||
864 | if (fh->overlay_active != ZORAN_FREE) { | ||
865 | fh->overlay_active = zr->overlay_active = ZORAN_FREE; | ||
866 | zr->v4l_overlay_active = 0; | ||
867 | if (!zr->v4l_memgrab_active) | ||
868 | zr36057_overlay(zr, 0); | ||
869 | zr->overlay_mask = NULL; | ||
870 | } | ||
871 | |||
872 | if (fh->map_mode == ZORAN_MAP_MODE_RAW) { | ||
873 | /* v4l capture */ | ||
874 | if (fh->buffers.active != ZORAN_FREE) { | ||
875 | unsigned long flags; | ||
876 | |||
877 | spin_lock_irqsave(&zr->spinlock, flags); | ||
878 | zr36057_set_memgrab(zr, 0); | ||
879 | zr->v4l_buffers.allocated = 0; | ||
880 | zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE; | ||
881 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
882 | } | ||
883 | |||
884 | /* v4l buffers */ | ||
885 | if (fh->buffers.allocated) | ||
886 | v4l_fbuffer_free(fh); | ||
887 | } else { | ||
888 | /* jpg capture */ | ||
889 | if (fh->buffers.active != ZORAN_FREE) { | ||
890 | zr36057_enable_jpg(zr, BUZ_MODE_IDLE); | ||
891 | zr->jpg_buffers.allocated = 0; | ||
892 | zr->jpg_buffers.active = fh->buffers.active = ZORAN_FREE; | ||
893 | } | ||
894 | |||
895 | /* jpg buffers */ | ||
896 | if (fh->buffers.allocated) | ||
897 | jpg_fbuffer_free(fh); | ||
898 | } | ||
899 | } | ||
900 | |||
901 | /* | ||
902 | * Open a zoran card. Right now the flags stuff is just playing | ||
903 | */ | ||
904 | |||
905 | static int zoran_open(struct file *file) | ||
906 | { | ||
907 | struct zoran *zr = video_drvdata(file); | ||
908 | struct zoran_fh *fh; | ||
909 | int res, first_open = 0; | ||
910 | |||
911 | dprintk(2, KERN_INFO "%s: %s(%s, pid=[%d]), users(-)=%d\n", | ||
912 | ZR_DEVNAME(zr), __func__, current->comm, task_pid_nr(current), zr->user + 1); | ||
913 | |||
914 | mutex_lock(&zr->other_lock); | ||
915 | |||
916 | if (zr->user >= 2048) { | ||
917 | dprintk(1, KERN_ERR "%s: too many users (%d) on device\n", | ||
918 | ZR_DEVNAME(zr), zr->user); | ||
919 | res = -EBUSY; | ||
920 | goto fail_unlock; | ||
921 | } | ||
922 | |||
923 | /* now, create the open()-specific file_ops struct */ | ||
924 | fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL); | ||
925 | if (!fh) { | ||
926 | dprintk(1, | ||
927 | KERN_ERR | ||
928 | "%s: %s - allocation of zoran_fh failed\n", | ||
929 | ZR_DEVNAME(zr), __func__); | ||
930 | res = -ENOMEM; | ||
931 | goto fail_unlock; | ||
932 | } | ||
933 | /* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows | ||
934 | * on norm-change! */ | ||
935 | fh->overlay_mask = | ||
936 | kmalloc(((768 + 31) / 32) * 576 * 4, GFP_KERNEL); | ||
937 | if (!fh->overlay_mask) { | ||
938 | dprintk(1, | ||
939 | KERN_ERR | ||
940 | "%s: %s - allocation of overlay_mask failed\n", | ||
941 | ZR_DEVNAME(zr), __func__); | ||
942 | res = -ENOMEM; | ||
943 | goto fail_fh; | ||
944 | } | ||
945 | |||
946 | if (zr->user++ == 0) | ||
947 | first_open = 1; | ||
948 | |||
949 | /*mutex_unlock(&zr->resource_lock);*/ | ||
950 | |||
951 | /* default setup - TODO: look at flags */ | ||
952 | if (first_open) { /* First device open */ | ||
953 | zr36057_restart(zr); | ||
954 | zoran_open_init_params(zr); | ||
955 | zoran_init_hardware(zr); | ||
956 | |||
957 | btor(ZR36057_ICR_IntPinEn, ZR36057_ICR); | ||
958 | } | ||
959 | |||
960 | /* set file_ops stuff */ | ||
961 | file->private_data = fh; | ||
962 | fh->zr = zr; | ||
963 | zoran_open_init_session(fh); | ||
964 | mutex_unlock(&zr->other_lock); | ||
965 | |||
966 | return 0; | ||
967 | |||
968 | fail_fh: | ||
969 | kfree(fh); | ||
970 | fail_unlock: | ||
971 | mutex_unlock(&zr->other_lock); | ||
972 | |||
973 | dprintk(2, KERN_INFO "%s: open failed (%d), users(-)=%d\n", | ||
974 | ZR_DEVNAME(zr), res, zr->user); | ||
975 | |||
976 | return res; | ||
977 | } | ||
978 | |||
979 | static int | ||
980 | zoran_close(struct file *file) | ||
981 | { | ||
982 | struct zoran_fh *fh = file->private_data; | ||
983 | struct zoran *zr = fh->zr; | ||
984 | |||
985 | dprintk(2, KERN_INFO "%s: %s(%s, pid=[%d]), users(+)=%d\n", | ||
986 | ZR_DEVNAME(zr), __func__, current->comm, task_pid_nr(current), zr->user - 1); | ||
987 | |||
988 | /* kernel locks (fs/device.c), so don't do that ourselves | ||
989 | * (prevents deadlocks) */ | ||
990 | mutex_lock(&zr->other_lock); | ||
991 | |||
992 | zoran_close_end_session(fh); | ||
993 | |||
994 | if (zr->user-- == 1) { /* Last process */ | ||
995 | /* Clean up JPEG process */ | ||
996 | wake_up_interruptible(&zr->jpg_capq); | ||
997 | zr36057_enable_jpg(zr, BUZ_MODE_IDLE); | ||
998 | zr->jpg_buffers.allocated = 0; | ||
999 | zr->jpg_buffers.active = ZORAN_FREE; | ||
1000 | |||
1001 | /* disable interrupts */ | ||
1002 | btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR); | ||
1003 | |||
1004 | if (zr36067_debug > 1) | ||
1005 | print_interrupts(zr); | ||
1006 | |||
1007 | /* Overlay off */ | ||
1008 | zr->v4l_overlay_active = 0; | ||
1009 | zr36057_overlay(zr, 0); | ||
1010 | zr->overlay_mask = NULL; | ||
1011 | |||
1012 | /* capture off */ | ||
1013 | wake_up_interruptible(&zr->v4l_capq); | ||
1014 | zr36057_set_memgrab(zr, 0); | ||
1015 | zr->v4l_buffers.allocated = 0; | ||
1016 | zr->v4l_buffers.active = ZORAN_FREE; | ||
1017 | zoran_set_pci_master(zr, 0); | ||
1018 | |||
1019 | if (!pass_through) { /* Switch to color bar */ | ||
1020 | decoder_call(zr, video, s_stream, 0); | ||
1021 | encoder_call(zr, video, s_routing, 2, 0, 0); | ||
1022 | } | ||
1023 | } | ||
1024 | mutex_unlock(&zr->other_lock); | ||
1025 | |||
1026 | file->private_data = NULL; | ||
1027 | kfree(fh->overlay_mask); | ||
1028 | kfree(fh); | ||
1029 | |||
1030 | dprintk(4, KERN_INFO "%s: %s done\n", ZR_DEVNAME(zr), __func__); | ||
1031 | |||
1032 | return 0; | ||
1033 | } | ||
1034 | |||
1035 | |||
1036 | static ssize_t | ||
1037 | zoran_read (struct file *file, | ||
1038 | char __user *data, | ||
1039 | size_t count, | ||
1040 | loff_t *ppos) | ||
1041 | { | ||
1042 | /* we simply don't support read() (yet)... */ | ||
1043 | |||
1044 | return -EINVAL; | ||
1045 | } | ||
1046 | |||
1047 | static ssize_t | ||
1048 | zoran_write (struct file *file, | ||
1049 | const char __user *data, | ||
1050 | size_t count, | ||
1051 | loff_t *ppos) | ||
1052 | { | ||
1053 | /* ...and the same goes for write() */ | ||
1054 | |||
1055 | return -EINVAL; | ||
1056 | } | ||
1057 | |||
1058 | static int setup_fbuffer(struct zoran_fh *fh, | ||
1059 | void *base, | ||
1060 | const struct zoran_format *fmt, | ||
1061 | int width, | ||
1062 | int height, | ||
1063 | int bytesperline) | ||
1064 | { | ||
1065 | struct zoran *zr = fh->zr; | ||
1066 | |||
1067 | /* (Ronald) v4l/v4l2 guidelines */ | ||
1068 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO)) | ||
1069 | return -EPERM; | ||
1070 | |||
1071 | /* Don't allow frame buffer overlay if PCI or AGP is buggy, or on | ||
1072 | ALi Magik (that needs very low latency while the card needs a | ||
1073 | higher value always) */ | ||
1074 | |||
1075 | if (pci_pci_problems & (PCIPCI_FAIL | PCIAGP_FAIL | PCIPCI_ALIMAGIK)) | ||
1076 | return -ENXIO; | ||
1077 | |||
1078 | /* we need a bytesperline value, even if not given */ | ||
1079 | if (!bytesperline) | ||
1080 | bytesperline = width * ((fmt->depth + 7) & ~7) / 8; | ||
1081 | |||
1082 | #if 0 | ||
1083 | if (zr->overlay_active) { | ||
1084 | /* dzjee... stupid users... don't even bother to turn off | ||
1085 | * overlay before changing the memory location... | ||
1086 | * normally, we would return errors here. However, one of | ||
1087 | * the tools that does this is... xawtv! and since xawtv | ||
1088 | * is used by +/- 99% of the users, we'd rather be user- | ||
1089 | * friendly and silently do as if nothing went wrong */ | ||
1090 | dprintk(3, | ||
1091 | KERN_ERR | ||
1092 | "%s: %s - forced overlay turnoff because framebuffer changed\n", | ||
1093 | ZR_DEVNAME(zr), __func__); | ||
1094 | zr36057_overlay(zr, 0); | ||
1095 | } | ||
1096 | #endif | ||
1097 | |||
1098 | if (!(fmt->flags & ZORAN_FORMAT_OVERLAY)) { | ||
1099 | dprintk(1, | ||
1100 | KERN_ERR | ||
1101 | "%s: %s - no valid overlay format given\n", | ||
1102 | ZR_DEVNAME(zr), __func__); | ||
1103 | return -EINVAL; | ||
1104 | } | ||
1105 | if (height <= 0 || width <= 0 || bytesperline <= 0) { | ||
1106 | dprintk(1, | ||
1107 | KERN_ERR | ||
1108 | "%s: %s - invalid height/width/bpl value (%d|%d|%d)\n", | ||
1109 | ZR_DEVNAME(zr), __func__, width, height, bytesperline); | ||
1110 | return -EINVAL; | ||
1111 | } | ||
1112 | if (bytesperline & 3) { | ||
1113 | dprintk(1, | ||
1114 | KERN_ERR | ||
1115 | "%s: %s - bytesperline (%d) must be 4-byte aligned\n", | ||
1116 | ZR_DEVNAME(zr), __func__, bytesperline); | ||
1117 | return -EINVAL; | ||
1118 | } | ||
1119 | |||
1120 | zr->vbuf_base = (void *) ((unsigned long) base & ~3); | ||
1121 | zr->vbuf_height = height; | ||
1122 | zr->vbuf_width = width; | ||
1123 | zr->vbuf_depth = fmt->depth; | ||
1124 | zr->overlay_settings.format = fmt; | ||
1125 | zr->vbuf_bytesperline = bytesperline; | ||
1126 | |||
1127 | /* The user should set new window parameters */ | ||
1128 | zr->overlay_settings.is_set = 0; | ||
1129 | |||
1130 | return 0; | ||
1131 | } | ||
1132 | |||
1133 | |||
1134 | static int setup_window(struct zoran_fh *fh, | ||
1135 | int x, | ||
1136 | int y, | ||
1137 | int width, | ||
1138 | int height, | ||
1139 | struct v4l2_clip __user *clips, | ||
1140 | unsigned int clipcount, | ||
1141 | void __user *bitmap) | ||
1142 | { | ||
1143 | struct zoran *zr = fh->zr; | ||
1144 | struct v4l2_clip *vcp = NULL; | ||
1145 | int on, end; | ||
1146 | |||
1147 | |||
1148 | if (!zr->vbuf_base) { | ||
1149 | dprintk(1, | ||
1150 | KERN_ERR | ||
1151 | "%s: %s - frame buffer has to be set first\n", | ||
1152 | ZR_DEVNAME(zr), __func__); | ||
1153 | return -EINVAL; | ||
1154 | } | ||
1155 | |||
1156 | if (!fh->overlay_settings.format) { | ||
1157 | dprintk(1, | ||
1158 | KERN_ERR | ||
1159 | "%s: %s - no overlay format set\n", | ||
1160 | ZR_DEVNAME(zr), __func__); | ||
1161 | return -EINVAL; | ||
1162 | } | ||
1163 | |||
1164 | if (clipcount > 2048) { | ||
1165 | dprintk(1, | ||
1166 | KERN_ERR | ||
1167 | "%s: %s - invalid clipcount\n", | ||
1168 | ZR_DEVNAME(zr), __func__); | ||
1169 | return -EINVAL; | ||
1170 | } | ||
1171 | |||
1172 | /* | ||
1173 | * The video front end needs 4-byte alinged line sizes, we correct that | ||
1174 | * silently here if necessary | ||
1175 | */ | ||
1176 | if (zr->vbuf_depth == 15 || zr->vbuf_depth == 16) { | ||
1177 | end = (x + width) & ~1; /* round down */ | ||
1178 | x = (x + 1) & ~1; /* round up */ | ||
1179 | width = end - x; | ||
1180 | } | ||
1181 | |||
1182 | if (zr->vbuf_depth == 24) { | ||
1183 | end = (x + width) & ~3; /* round down */ | ||
1184 | x = (x + 3) & ~3; /* round up */ | ||
1185 | width = end - x; | ||
1186 | } | ||
1187 | |||
1188 | if (width > BUZ_MAX_WIDTH) | ||
1189 | width = BUZ_MAX_WIDTH; | ||
1190 | if (height > BUZ_MAX_HEIGHT) | ||
1191 | height = BUZ_MAX_HEIGHT; | ||
1192 | |||
1193 | /* Check for invalid parameters */ | ||
1194 | if (width < BUZ_MIN_WIDTH || height < BUZ_MIN_HEIGHT || | ||
1195 | width > BUZ_MAX_WIDTH || height > BUZ_MAX_HEIGHT) { | ||
1196 | dprintk(1, | ||
1197 | KERN_ERR | ||
1198 | "%s: %s - width = %d or height = %d invalid\n", | ||
1199 | ZR_DEVNAME(zr), __func__, width, height); | ||
1200 | return -EINVAL; | ||
1201 | } | ||
1202 | |||
1203 | fh->overlay_settings.x = x; | ||
1204 | fh->overlay_settings.y = y; | ||
1205 | fh->overlay_settings.width = width; | ||
1206 | fh->overlay_settings.height = height; | ||
1207 | fh->overlay_settings.clipcount = clipcount; | ||
1208 | |||
1209 | /* | ||
1210 | * If an overlay is running, we have to switch it off | ||
1211 | * and switch it on again in order to get the new settings in effect. | ||
1212 | * | ||
1213 | * We also want to avoid that the overlay mask is written | ||
1214 | * when an overlay is running. | ||
1215 | */ | ||
1216 | |||
1217 | on = zr->v4l_overlay_active && !zr->v4l_memgrab_active && | ||
1218 | zr->overlay_active != ZORAN_FREE && | ||
1219 | fh->overlay_active != ZORAN_FREE; | ||
1220 | if (on) | ||
1221 | zr36057_overlay(zr, 0); | ||
1222 | |||
1223 | /* | ||
1224 | * Write the overlay mask if clips are wanted. | ||
1225 | * We prefer a bitmap. | ||
1226 | */ | ||
1227 | if (bitmap) { | ||
1228 | /* fake value - it just means we want clips */ | ||
1229 | fh->overlay_settings.clipcount = 1; | ||
1230 | |||
1231 | if (copy_from_user(fh->overlay_mask, bitmap, | ||
1232 | (width * height + 7) / 8)) { | ||
1233 | return -EFAULT; | ||
1234 | } | ||
1235 | } else if (clipcount) { | ||
1236 | /* write our own bitmap from the clips */ | ||
1237 | vcp = vmalloc(sizeof(struct v4l2_clip) * (clipcount + 4)); | ||
1238 | if (vcp == NULL) { | ||
1239 | dprintk(1, | ||
1240 | KERN_ERR | ||
1241 | "%s: %s - Alloc of clip mask failed\n", | ||
1242 | ZR_DEVNAME(zr), __func__); | ||
1243 | return -ENOMEM; | ||
1244 | } | ||
1245 | if (copy_from_user | ||
1246 | (vcp, clips, sizeof(struct v4l2_clip) * clipcount)) { | ||
1247 | vfree(vcp); | ||
1248 | return -EFAULT; | ||
1249 | } | ||
1250 | write_overlay_mask(fh, vcp, clipcount); | ||
1251 | vfree(vcp); | ||
1252 | } | ||
1253 | |||
1254 | fh->overlay_settings.is_set = 1; | ||
1255 | if (fh->overlay_active != ZORAN_FREE && | ||
1256 | zr->overlay_active != ZORAN_FREE) | ||
1257 | zr->overlay_settings = fh->overlay_settings; | ||
1258 | |||
1259 | if (on) | ||
1260 | zr36057_overlay(zr, 1); | ||
1261 | |||
1262 | /* Make sure the changes come into effect */ | ||
1263 | return wait_grab_pending(zr); | ||
1264 | } | ||
1265 | |||
1266 | static int setup_overlay(struct zoran_fh *fh, int on) | ||
1267 | { | ||
1268 | struct zoran *zr = fh->zr; | ||
1269 | |||
1270 | /* If there is nothing to do, return immediately */ | ||
1271 | if ((on && fh->overlay_active != ZORAN_FREE) || | ||
1272 | (!on && fh->overlay_active == ZORAN_FREE)) | ||
1273 | return 0; | ||
1274 | |||
1275 | /* check whether we're touching someone else's overlay */ | ||
1276 | if (on && zr->overlay_active != ZORAN_FREE && | ||
1277 | fh->overlay_active == ZORAN_FREE) { | ||
1278 | dprintk(1, | ||
1279 | KERN_ERR | ||
1280 | "%s: %s - overlay is already active for another session\n", | ||
1281 | ZR_DEVNAME(zr), __func__); | ||
1282 | return -EBUSY; | ||
1283 | } | ||
1284 | if (!on && zr->overlay_active != ZORAN_FREE && | ||
1285 | fh->overlay_active == ZORAN_FREE) { | ||
1286 | dprintk(1, | ||
1287 | KERN_ERR | ||
1288 | "%s: %s - you cannot cancel someone else's session\n", | ||
1289 | ZR_DEVNAME(zr), __func__); | ||
1290 | return -EPERM; | ||
1291 | } | ||
1292 | |||
1293 | if (on == 0) { | ||
1294 | zr->overlay_active = fh->overlay_active = ZORAN_FREE; | ||
1295 | zr->v4l_overlay_active = 0; | ||
1296 | /* When a grab is running, the video simply | ||
1297 | * won't be switched on any more */ | ||
1298 | if (!zr->v4l_memgrab_active) | ||
1299 | zr36057_overlay(zr, 0); | ||
1300 | zr->overlay_mask = NULL; | ||
1301 | } else { | ||
1302 | if (!zr->vbuf_base || !fh->overlay_settings.is_set) { | ||
1303 | dprintk(1, | ||
1304 | KERN_ERR | ||
1305 | "%s: %s - buffer or window not set\n", | ||
1306 | ZR_DEVNAME(zr), __func__); | ||
1307 | return -EINVAL; | ||
1308 | } | ||
1309 | if (!fh->overlay_settings.format) { | ||
1310 | dprintk(1, | ||
1311 | KERN_ERR | ||
1312 | "%s: %s - no overlay format set\n", | ||
1313 | ZR_DEVNAME(zr), __func__); | ||
1314 | return -EINVAL; | ||
1315 | } | ||
1316 | zr->overlay_active = fh->overlay_active = ZORAN_LOCKED; | ||
1317 | zr->v4l_overlay_active = 1; | ||
1318 | zr->overlay_mask = fh->overlay_mask; | ||
1319 | zr->overlay_settings = fh->overlay_settings; | ||
1320 | if (!zr->v4l_memgrab_active) | ||
1321 | zr36057_overlay(zr, 1); | ||
1322 | /* When a grab is running, the video will be | ||
1323 | * switched on when grab is finished */ | ||
1324 | } | ||
1325 | |||
1326 | /* Make sure the changes come into effect */ | ||
1327 | return wait_grab_pending(zr); | ||
1328 | } | ||
1329 | |||
1330 | /* get the status of a buffer in the clients buffer queue */ | ||
1331 | static int zoran_v4l2_buffer_status(struct zoran_fh *fh, | ||
1332 | struct v4l2_buffer *buf, int num) | ||
1333 | { | ||
1334 | struct zoran *zr = fh->zr; | ||
1335 | unsigned long flags; | ||
1336 | |||
1337 | buf->flags = V4L2_BUF_FLAG_MAPPED; | ||
1338 | |||
1339 | switch (fh->map_mode) { | ||
1340 | case ZORAN_MAP_MODE_RAW: | ||
1341 | /* check range */ | ||
1342 | if (num < 0 || num >= fh->buffers.num_buffers || | ||
1343 | !fh->buffers.allocated) { | ||
1344 | dprintk(1, | ||
1345 | KERN_ERR | ||
1346 | "%s: %s - wrong number or buffers not allocated\n", | ||
1347 | ZR_DEVNAME(zr), __func__); | ||
1348 | return -EINVAL; | ||
1349 | } | ||
1350 | |||
1351 | spin_lock_irqsave(&zr->spinlock, flags); | ||
1352 | dprintk(3, | ||
1353 | KERN_DEBUG | ||
1354 | "%s: %s() - raw active=%c, buffer %d: state=%c, map=%c\n", | ||
1355 | ZR_DEVNAME(zr), __func__, | ||
1356 | "FAL"[fh->buffers.active], num, | ||
1357 | "UPMD"[zr->v4l_buffers.buffer[num].state], | ||
1358 | fh->buffers.buffer[num].map ? 'Y' : 'N'); | ||
1359 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
1360 | |||
1361 | buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1362 | buf->length = fh->buffers.buffer_size; | ||
1363 | |||
1364 | /* get buffer */ | ||
1365 | buf->bytesused = fh->buffers.buffer[num].bs.length; | ||
1366 | if (fh->buffers.buffer[num].state == BUZ_STATE_DONE || | ||
1367 | fh->buffers.buffer[num].state == BUZ_STATE_USER) { | ||
1368 | buf->sequence = fh->buffers.buffer[num].bs.seq; | ||
1369 | buf->flags |= V4L2_BUF_FLAG_DONE; | ||
1370 | buf->timestamp = fh->buffers.buffer[num].bs.timestamp; | ||
1371 | } else { | ||
1372 | buf->flags |= V4L2_BUF_FLAG_QUEUED; | ||
1373 | } | ||
1374 | |||
1375 | if (fh->v4l_settings.height <= BUZ_MAX_HEIGHT / 2) | ||
1376 | buf->field = V4L2_FIELD_TOP; | ||
1377 | else | ||
1378 | buf->field = V4L2_FIELD_INTERLACED; | ||
1379 | |||
1380 | break; | ||
1381 | |||
1382 | case ZORAN_MAP_MODE_JPG_REC: | ||
1383 | case ZORAN_MAP_MODE_JPG_PLAY: | ||
1384 | |||
1385 | /* check range */ | ||
1386 | if (num < 0 || num >= fh->buffers.num_buffers || | ||
1387 | !fh->buffers.allocated) { | ||
1388 | dprintk(1, | ||
1389 | KERN_ERR | ||
1390 | "%s: %s - wrong number or buffers not allocated\n", | ||
1391 | ZR_DEVNAME(zr), __func__); | ||
1392 | return -EINVAL; | ||
1393 | } | ||
1394 | |||
1395 | buf->type = (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ? | ||
1396 | V4L2_BUF_TYPE_VIDEO_CAPTURE : | ||
1397 | V4L2_BUF_TYPE_VIDEO_OUTPUT; | ||
1398 | buf->length = fh->buffers.buffer_size; | ||
1399 | |||
1400 | /* these variables are only written after frame has been captured */ | ||
1401 | if (fh->buffers.buffer[num].state == BUZ_STATE_DONE || | ||
1402 | fh->buffers.buffer[num].state == BUZ_STATE_USER) { | ||
1403 | buf->sequence = fh->buffers.buffer[num].bs.seq; | ||
1404 | buf->timestamp = fh->buffers.buffer[num].bs.timestamp; | ||
1405 | buf->bytesused = fh->buffers.buffer[num].bs.length; | ||
1406 | buf->flags |= V4L2_BUF_FLAG_DONE; | ||
1407 | } else { | ||
1408 | buf->flags |= V4L2_BUF_FLAG_QUEUED; | ||
1409 | } | ||
1410 | |||
1411 | /* which fields are these? */ | ||
1412 | if (fh->jpg_settings.TmpDcm != 1) | ||
1413 | buf->field = fh->jpg_settings.odd_even ? | ||
1414 | V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM; | ||
1415 | else | ||
1416 | buf->field = fh->jpg_settings.odd_even ? | ||
1417 | V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT; | ||
1418 | |||
1419 | break; | ||
1420 | |||
1421 | default: | ||
1422 | |||
1423 | dprintk(5, | ||
1424 | KERN_ERR | ||
1425 | "%s: %s - invalid buffer type|map_mode (%d|%d)\n", | ||
1426 | ZR_DEVNAME(zr), __func__, buf->type, fh->map_mode); | ||
1427 | return -EINVAL; | ||
1428 | } | ||
1429 | |||
1430 | buf->memory = V4L2_MEMORY_MMAP; | ||
1431 | buf->index = num; | ||
1432 | buf->m.offset = buf->length * num; | ||
1433 | |||
1434 | return 0; | ||
1435 | } | ||
1436 | |||
1437 | static int | ||
1438 | zoran_set_norm (struct zoran *zr, | ||
1439 | v4l2_std_id norm) | ||
1440 | { | ||
1441 | int on; | ||
1442 | |||
1443 | if (zr->v4l_buffers.active != ZORAN_FREE || | ||
1444 | zr->jpg_buffers.active != ZORAN_FREE) { | ||
1445 | dprintk(1, | ||
1446 | KERN_WARNING | ||
1447 | "%s: %s called while in playback/capture mode\n", | ||
1448 | ZR_DEVNAME(zr), __func__); | ||
1449 | return -EBUSY; | ||
1450 | } | ||
1451 | |||
1452 | if (!(norm & zr->card.norms)) { | ||
1453 | dprintk(1, | ||
1454 | KERN_ERR "%s: %s - unsupported norm %llx\n", | ||
1455 | ZR_DEVNAME(zr), __func__, norm); | ||
1456 | return -EINVAL; | ||
1457 | } | ||
1458 | |||
1459 | if (norm == V4L2_STD_ALL) { | ||
1460 | unsigned int status = 0; | ||
1461 | v4l2_std_id std = 0; | ||
1462 | |||
1463 | decoder_call(zr, video, querystd, &std); | ||
1464 | decoder_call(zr, core, s_std, std); | ||
1465 | |||
1466 | /* let changes come into effect */ | ||
1467 | ssleep(2); | ||
1468 | |||
1469 | decoder_call(zr, video, g_input_status, &status); | ||
1470 | if (status & V4L2_IN_ST_NO_SIGNAL) { | ||
1471 | dprintk(1, | ||
1472 | KERN_ERR | ||
1473 | "%s: %s - no norm detected\n", | ||
1474 | ZR_DEVNAME(zr), __func__); | ||
1475 | /* reset norm */ | ||
1476 | decoder_call(zr, core, s_std, zr->norm); | ||
1477 | return -EIO; | ||
1478 | } | ||
1479 | |||
1480 | norm = std; | ||
1481 | } | ||
1482 | if (norm & V4L2_STD_SECAM) | ||
1483 | zr->timing = zr->card.tvn[2]; | ||
1484 | else if (norm & V4L2_STD_NTSC) | ||
1485 | zr->timing = zr->card.tvn[1]; | ||
1486 | else | ||
1487 | zr->timing = zr->card.tvn[0]; | ||
1488 | |||
1489 | /* We switch overlay off and on since a change in the | ||
1490 | * norm needs different VFE settings */ | ||
1491 | on = zr->overlay_active && !zr->v4l_memgrab_active; | ||
1492 | if (on) | ||
1493 | zr36057_overlay(zr, 0); | ||
1494 | |||
1495 | decoder_call(zr, core, s_std, norm); | ||
1496 | encoder_call(zr, video, s_std_output, norm); | ||
1497 | |||
1498 | if (on) | ||
1499 | zr36057_overlay(zr, 1); | ||
1500 | |||
1501 | /* Make sure the changes come into effect */ | ||
1502 | zr->norm = norm; | ||
1503 | |||
1504 | return 0; | ||
1505 | } | ||
1506 | |||
1507 | static int | ||
1508 | zoran_set_input (struct zoran *zr, | ||
1509 | int input) | ||
1510 | { | ||
1511 | if (input == zr->input) { | ||
1512 | return 0; | ||
1513 | } | ||
1514 | |||
1515 | if (zr->v4l_buffers.active != ZORAN_FREE || | ||
1516 | zr->jpg_buffers.active != ZORAN_FREE) { | ||
1517 | dprintk(1, | ||
1518 | KERN_WARNING | ||
1519 | "%s: %s called while in playback/capture mode\n", | ||
1520 | ZR_DEVNAME(zr), __func__); | ||
1521 | return -EBUSY; | ||
1522 | } | ||
1523 | |||
1524 | if (input < 0 || input >= zr->card.inputs) { | ||
1525 | dprintk(1, | ||
1526 | KERN_ERR | ||
1527 | "%s: %s - unnsupported input %d\n", | ||
1528 | ZR_DEVNAME(zr), __func__, input); | ||
1529 | return -EINVAL; | ||
1530 | } | ||
1531 | |||
1532 | zr->input = input; | ||
1533 | |||
1534 | decoder_call(zr, video, s_routing, | ||
1535 | zr->card.input[input].muxsel, 0, 0); | ||
1536 | |||
1537 | return 0; | ||
1538 | } | ||
1539 | |||
1540 | /* | ||
1541 | * ioctl routine | ||
1542 | */ | ||
1543 | |||
1544 | static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap) | ||
1545 | { | ||
1546 | struct zoran_fh *fh = __fh; | ||
1547 | struct zoran *zr = fh->zr; | ||
1548 | |||
1549 | memset(cap, 0, sizeof(*cap)); | ||
1550 | strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1); | ||
1551 | strncpy(cap->driver, "zoran", sizeof(cap->driver)-1); | ||
1552 | snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", | ||
1553 | pci_name(zr->pci_dev)); | ||
1554 | cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE | | ||
1555 | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OVERLAY; | ||
1556 | return 0; | ||
1557 | } | ||
1558 | |||
1559 | static int zoran_enum_fmt(struct zoran *zr, struct v4l2_fmtdesc *fmt, int flag) | ||
1560 | { | ||
1561 | unsigned int num, i; | ||
1562 | |||
1563 | for (num = i = 0; i < NUM_FORMATS; i++) { | ||
1564 | if (zoran_formats[i].flags & flag && num++ == fmt->index) { | ||
1565 | strncpy(fmt->description, zoran_formats[i].name, | ||
1566 | sizeof(fmt->description) - 1); | ||
1567 | /* fmt struct pre-zeroed, so adding '\0' not needed */ | ||
1568 | fmt->pixelformat = zoran_formats[i].fourcc; | ||
1569 | if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED) | ||
1570 | fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; | ||
1571 | return 0; | ||
1572 | } | ||
1573 | } | ||
1574 | return -EINVAL; | ||
1575 | } | ||
1576 | |||
1577 | static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh, | ||
1578 | struct v4l2_fmtdesc *f) | ||
1579 | { | ||
1580 | struct zoran_fh *fh = __fh; | ||
1581 | struct zoran *zr = fh->zr; | ||
1582 | |||
1583 | return zoran_enum_fmt(zr, f, ZORAN_FORMAT_CAPTURE); | ||
1584 | } | ||
1585 | |||
1586 | static int zoran_enum_fmt_vid_out(struct file *file, void *__fh, | ||
1587 | struct v4l2_fmtdesc *f) | ||
1588 | { | ||
1589 | struct zoran_fh *fh = __fh; | ||
1590 | struct zoran *zr = fh->zr; | ||
1591 | |||
1592 | return zoran_enum_fmt(zr, f, ZORAN_FORMAT_PLAYBACK); | ||
1593 | } | ||
1594 | |||
1595 | static int zoran_enum_fmt_vid_overlay(struct file *file, void *__fh, | ||
1596 | struct v4l2_fmtdesc *f) | ||
1597 | { | ||
1598 | struct zoran_fh *fh = __fh; | ||
1599 | struct zoran *zr = fh->zr; | ||
1600 | |||
1601 | return zoran_enum_fmt(zr, f, ZORAN_FORMAT_OVERLAY); | ||
1602 | } | ||
1603 | |||
1604 | static int zoran_g_fmt_vid_out(struct file *file, void *__fh, | ||
1605 | struct v4l2_format *fmt) | ||
1606 | { | ||
1607 | struct zoran_fh *fh = __fh; | ||
1608 | struct zoran *zr = fh->zr; | ||
1609 | |||
1610 | mutex_lock(&zr->resource_lock); | ||
1611 | |||
1612 | fmt->fmt.pix.width = fh->jpg_settings.img_width / fh->jpg_settings.HorDcm; | ||
1613 | fmt->fmt.pix.height = fh->jpg_settings.img_height * 2 / | ||
1614 | (fh->jpg_settings.VerDcm * fh->jpg_settings.TmpDcm); | ||
1615 | fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&fh->jpg_settings); | ||
1616 | fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; | ||
1617 | if (fh->jpg_settings.TmpDcm == 1) | ||
1618 | fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? | ||
1619 | V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); | ||
1620 | else | ||
1621 | fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? | ||
1622 | V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); | ||
1623 | fmt->fmt.pix.bytesperline = 0; | ||
1624 | fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
1625 | |||
1626 | mutex_unlock(&zr->resource_lock); | ||
1627 | return 0; | ||
1628 | } | ||
1629 | |||
1630 | static int zoran_g_fmt_vid_cap(struct file *file, void *__fh, | ||
1631 | struct v4l2_format *fmt) | ||
1632 | { | ||
1633 | struct zoran_fh *fh = __fh; | ||
1634 | struct zoran *zr = fh->zr; | ||
1635 | |||
1636 | if (fh->map_mode != ZORAN_MAP_MODE_RAW) | ||
1637 | return zoran_g_fmt_vid_out(file, fh, fmt); | ||
1638 | |||
1639 | mutex_lock(&zr->resource_lock); | ||
1640 | fmt->fmt.pix.width = fh->v4l_settings.width; | ||
1641 | fmt->fmt.pix.height = fh->v4l_settings.height; | ||
1642 | fmt->fmt.pix.sizeimage = fh->v4l_settings.bytesperline * | ||
1643 | fh->v4l_settings.height; | ||
1644 | fmt->fmt.pix.pixelformat = fh->v4l_settings.format->fourcc; | ||
1645 | fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace; | ||
1646 | fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline; | ||
1647 | if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2)) | ||
1648 | fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; | ||
1649 | else | ||
1650 | fmt->fmt.pix.field = V4L2_FIELD_TOP; | ||
1651 | mutex_unlock(&zr->resource_lock); | ||
1652 | return 0; | ||
1653 | } | ||
1654 | |||
1655 | static int zoran_g_fmt_vid_overlay(struct file *file, void *__fh, | ||
1656 | struct v4l2_format *fmt) | ||
1657 | { | ||
1658 | struct zoran_fh *fh = __fh; | ||
1659 | struct zoran *zr = fh->zr; | ||
1660 | |||
1661 | mutex_lock(&zr->resource_lock); | ||
1662 | |||
1663 | fmt->fmt.win.w.left = fh->overlay_settings.x; | ||
1664 | fmt->fmt.win.w.top = fh->overlay_settings.y; | ||
1665 | fmt->fmt.win.w.width = fh->overlay_settings.width; | ||
1666 | fmt->fmt.win.w.height = fh->overlay_settings.height; | ||
1667 | if (fh->overlay_settings.width * 2 > BUZ_MAX_HEIGHT) | ||
1668 | fmt->fmt.win.field = V4L2_FIELD_INTERLACED; | ||
1669 | else | ||
1670 | fmt->fmt.win.field = V4L2_FIELD_TOP; | ||
1671 | |||
1672 | mutex_unlock(&zr->resource_lock); | ||
1673 | return 0; | ||
1674 | } | ||
1675 | |||
1676 | static int zoran_try_fmt_vid_overlay(struct file *file, void *__fh, | ||
1677 | struct v4l2_format *fmt) | ||
1678 | { | ||
1679 | struct zoran_fh *fh = __fh; | ||
1680 | struct zoran *zr = fh->zr; | ||
1681 | |||
1682 | mutex_lock(&zr->resource_lock); | ||
1683 | |||
1684 | if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH) | ||
1685 | fmt->fmt.win.w.width = BUZ_MAX_WIDTH; | ||
1686 | if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH) | ||
1687 | fmt->fmt.win.w.width = BUZ_MIN_WIDTH; | ||
1688 | if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT) | ||
1689 | fmt->fmt.win.w.height = BUZ_MAX_HEIGHT; | ||
1690 | if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT) | ||
1691 | fmt->fmt.win.w.height = BUZ_MIN_HEIGHT; | ||
1692 | |||
1693 | mutex_unlock(&zr->resource_lock); | ||
1694 | return 0; | ||
1695 | } | ||
1696 | |||
1697 | static int zoran_try_fmt_vid_out(struct file *file, void *__fh, | ||
1698 | struct v4l2_format *fmt) | ||
1699 | { | ||
1700 | struct zoran_fh *fh = __fh; | ||
1701 | struct zoran *zr = fh->zr; | ||
1702 | struct zoran_jpg_settings settings; | ||
1703 | int res = 0; | ||
1704 | |||
1705 | if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) | ||
1706 | return -EINVAL; | ||
1707 | |||
1708 | mutex_lock(&zr->resource_lock); | ||
1709 | settings = fh->jpg_settings; | ||
1710 | |||
1711 | /* we actually need to set 'real' parameters now */ | ||
1712 | if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT) | ||
1713 | settings.TmpDcm = 1; | ||
1714 | else | ||
1715 | settings.TmpDcm = 2; | ||
1716 | settings.decimation = 0; | ||
1717 | if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2) | ||
1718 | settings.VerDcm = 2; | ||
1719 | else | ||
1720 | settings.VerDcm = 1; | ||
1721 | if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4) | ||
1722 | settings.HorDcm = 4; | ||
1723 | else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2) | ||
1724 | settings.HorDcm = 2; | ||
1725 | else | ||
1726 | settings.HorDcm = 1; | ||
1727 | if (settings.TmpDcm == 1) | ||
1728 | settings.field_per_buff = 2; | ||
1729 | else | ||
1730 | settings.field_per_buff = 1; | ||
1731 | |||
1732 | if (settings.HorDcm > 1) { | ||
1733 | settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0; | ||
1734 | settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH; | ||
1735 | } else { | ||
1736 | settings.img_x = 0; | ||
1737 | settings.img_width = BUZ_MAX_WIDTH; | ||
1738 | } | ||
1739 | |||
1740 | /* check */ | ||
1741 | res = zoran_check_jpg_settings(zr, &settings, 1); | ||
1742 | if (res) | ||
1743 | goto tryfmt_unlock_and_return; | ||
1744 | |||
1745 | /* tell the user what we actually did */ | ||
1746 | fmt->fmt.pix.width = settings.img_width / settings.HorDcm; | ||
1747 | fmt->fmt.pix.height = settings.img_height * 2 / | ||
1748 | (settings.TmpDcm * settings.VerDcm); | ||
1749 | if (settings.TmpDcm == 1) | ||
1750 | fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? | ||
1751 | V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); | ||
1752 | else | ||
1753 | fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? | ||
1754 | V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); | ||
1755 | |||
1756 | fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&settings); | ||
1757 | fmt->fmt.pix.bytesperline = 0; | ||
1758 | fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
1759 | tryfmt_unlock_and_return: | ||
1760 | mutex_unlock(&zr->resource_lock); | ||
1761 | return res; | ||
1762 | } | ||
1763 | |||
1764 | static int zoran_try_fmt_vid_cap(struct file *file, void *__fh, | ||
1765 | struct v4l2_format *fmt) | ||
1766 | { | ||
1767 | struct zoran_fh *fh = __fh; | ||
1768 | struct zoran *zr = fh->zr; | ||
1769 | int bpp; | ||
1770 | int i; | ||
1771 | |||
1772 | if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) | ||
1773 | return zoran_try_fmt_vid_out(file, fh, fmt); | ||
1774 | |||
1775 | mutex_lock(&zr->resource_lock); | ||
1776 | |||
1777 | for (i = 0; i < NUM_FORMATS; i++) | ||
1778 | if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat) | ||
1779 | break; | ||
1780 | |||
1781 | if (i == NUM_FORMATS) { | ||
1782 | mutex_unlock(&zr->resource_lock); | ||
1783 | return -EINVAL; | ||
1784 | } | ||
1785 | |||
1786 | bpp = DIV_ROUND_UP(zoran_formats[i].depth, 8); | ||
1787 | v4l_bound_align_image( | ||
1788 | &fmt->fmt.pix.width, BUZ_MIN_WIDTH, BUZ_MAX_WIDTH, bpp == 2 ? 1 : 2, | ||
1789 | &fmt->fmt.pix.height, BUZ_MIN_HEIGHT, BUZ_MAX_HEIGHT, 0, 0); | ||
1790 | mutex_unlock(&zr->resource_lock); | ||
1791 | |||
1792 | return 0; | ||
1793 | } | ||
1794 | |||
1795 | static int zoran_s_fmt_vid_overlay(struct file *file, void *__fh, | ||
1796 | struct v4l2_format *fmt) | ||
1797 | { | ||
1798 | struct zoran_fh *fh = __fh; | ||
1799 | struct zoran *zr = fh->zr; | ||
1800 | int res; | ||
1801 | |||
1802 | dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n", | ||
1803 | fmt->fmt.win.w.left, fmt->fmt.win.w.top, | ||
1804 | fmt->fmt.win.w.width, | ||
1805 | fmt->fmt.win.w.height, | ||
1806 | fmt->fmt.win.clipcount, | ||
1807 | fmt->fmt.win.bitmap); | ||
1808 | mutex_lock(&zr->resource_lock); | ||
1809 | res = setup_window(fh, fmt->fmt.win.w.left, fmt->fmt.win.w.top, | ||
1810 | fmt->fmt.win.w.width, fmt->fmt.win.w.height, | ||
1811 | (struct v4l2_clip __user *)fmt->fmt.win.clips, | ||
1812 | fmt->fmt.win.clipcount, fmt->fmt.win.bitmap); | ||
1813 | mutex_unlock(&zr->resource_lock); | ||
1814 | return res; | ||
1815 | } | ||
1816 | |||
1817 | static int zoran_s_fmt_vid_out(struct file *file, void *__fh, | ||
1818 | struct v4l2_format *fmt) | ||
1819 | { | ||
1820 | struct zoran_fh *fh = __fh; | ||
1821 | struct zoran *zr = fh->zr; | ||
1822 | __le32 printformat = __cpu_to_le32(fmt->fmt.pix.pixelformat); | ||
1823 | struct zoran_jpg_settings settings; | ||
1824 | int res = 0; | ||
1825 | |||
1826 | dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n", | ||
1827 | fmt->fmt.pix.width, fmt->fmt.pix.height, | ||
1828 | fmt->fmt.pix.pixelformat, | ||
1829 | (char *) &printformat); | ||
1830 | if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) | ||
1831 | return -EINVAL; | ||
1832 | |||
1833 | mutex_lock(&zr->resource_lock); | ||
1834 | |||
1835 | if (fh->buffers.allocated) { | ||
1836 | dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n", | ||
1837 | ZR_DEVNAME(zr)); | ||
1838 | res = -EBUSY; | ||
1839 | goto sfmtjpg_unlock_and_return; | ||
1840 | } | ||
1841 | |||
1842 | settings = fh->jpg_settings; | ||
1843 | |||
1844 | /* we actually need to set 'real' parameters now */ | ||
1845 | if (fmt->fmt.pix.height * 2 > BUZ_MAX_HEIGHT) | ||
1846 | settings.TmpDcm = 1; | ||
1847 | else | ||
1848 | settings.TmpDcm = 2; | ||
1849 | settings.decimation = 0; | ||
1850 | if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2) | ||
1851 | settings.VerDcm = 2; | ||
1852 | else | ||
1853 | settings.VerDcm = 1; | ||
1854 | if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4) | ||
1855 | settings.HorDcm = 4; | ||
1856 | else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2) | ||
1857 | settings.HorDcm = 2; | ||
1858 | else | ||
1859 | settings.HorDcm = 1; | ||
1860 | if (settings.TmpDcm == 1) | ||
1861 | settings.field_per_buff = 2; | ||
1862 | else | ||
1863 | settings.field_per_buff = 1; | ||
1864 | |||
1865 | if (settings.HorDcm > 1) { | ||
1866 | settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0; | ||
1867 | settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH; | ||
1868 | } else { | ||
1869 | settings.img_x = 0; | ||
1870 | settings.img_width = BUZ_MAX_WIDTH; | ||
1871 | } | ||
1872 | |||
1873 | /* check */ | ||
1874 | res = zoran_check_jpg_settings(zr, &settings, 0); | ||
1875 | if (res) | ||
1876 | goto sfmtjpg_unlock_and_return; | ||
1877 | |||
1878 | /* it's ok, so set them */ | ||
1879 | fh->jpg_settings = settings; | ||
1880 | |||
1881 | map_mode_jpg(fh, fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT); | ||
1882 | fh->buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings); | ||
1883 | |||
1884 | /* tell the user what we actually did */ | ||
1885 | fmt->fmt.pix.width = settings.img_width / settings.HorDcm; | ||
1886 | fmt->fmt.pix.height = settings.img_height * 2 / | ||
1887 | (settings.TmpDcm * settings.VerDcm); | ||
1888 | if (settings.TmpDcm == 1) | ||
1889 | fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? | ||
1890 | V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); | ||
1891 | else | ||
1892 | fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? | ||
1893 | V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); | ||
1894 | fmt->fmt.pix.bytesperline = 0; | ||
1895 | fmt->fmt.pix.sizeimage = fh->buffers.buffer_size; | ||
1896 | fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
1897 | |||
1898 | sfmtjpg_unlock_and_return: | ||
1899 | mutex_unlock(&zr->resource_lock); | ||
1900 | return res; | ||
1901 | } | ||
1902 | |||
1903 | static int zoran_s_fmt_vid_cap(struct file *file, void *__fh, | ||
1904 | struct v4l2_format *fmt) | ||
1905 | { | ||
1906 | struct zoran_fh *fh = __fh; | ||
1907 | struct zoran *zr = fh->zr; | ||
1908 | int i; | ||
1909 | int res = 0; | ||
1910 | |||
1911 | if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) | ||
1912 | return zoran_s_fmt_vid_out(file, fh, fmt); | ||
1913 | |||
1914 | for (i = 0; i < NUM_FORMATS; i++) | ||
1915 | if (fmt->fmt.pix.pixelformat == zoran_formats[i].fourcc) | ||
1916 | break; | ||
1917 | if (i == NUM_FORMATS) { | ||
1918 | dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x\n", | ||
1919 | ZR_DEVNAME(zr), fmt->fmt.pix.pixelformat); | ||
1920 | return -EINVAL; | ||
1921 | } | ||
1922 | |||
1923 | mutex_lock(&zr->resource_lock); | ||
1924 | |||
1925 | if ((fh->map_mode != ZORAN_MAP_MODE_RAW && fh->buffers.allocated) || | ||
1926 | fh->buffers.active != ZORAN_FREE) { | ||
1927 | dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n", | ||
1928 | ZR_DEVNAME(zr)); | ||
1929 | res = -EBUSY; | ||
1930 | goto sfmtv4l_unlock_and_return; | ||
1931 | } | ||
1932 | if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) | ||
1933 | fmt->fmt.pix.height = BUZ_MAX_HEIGHT; | ||
1934 | if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) | ||
1935 | fmt->fmt.pix.width = BUZ_MAX_WIDTH; | ||
1936 | |||
1937 | map_mode_raw(fh); | ||
1938 | |||
1939 | res = zoran_v4l_set_format(fh, fmt->fmt.pix.width, fmt->fmt.pix.height, | ||
1940 | &zoran_formats[i]); | ||
1941 | if (res) | ||
1942 | goto sfmtv4l_unlock_and_return; | ||
1943 | |||
1944 | /* tell the user the results/missing stuff */ | ||
1945 | fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline; | ||
1946 | fmt->fmt.pix.sizeimage = fh->v4l_settings.height * fh->v4l_settings.bytesperline; | ||
1947 | fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace; | ||
1948 | if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2)) | ||
1949 | fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; | ||
1950 | else | ||
1951 | fmt->fmt.pix.field = V4L2_FIELD_TOP; | ||
1952 | |||
1953 | sfmtv4l_unlock_and_return: | ||
1954 | mutex_unlock(&zr->resource_lock); | ||
1955 | return res; | ||
1956 | } | ||
1957 | |||
1958 | static int zoran_g_fbuf(struct file *file, void *__fh, | ||
1959 | struct v4l2_framebuffer *fb) | ||
1960 | { | ||
1961 | struct zoran_fh *fh = __fh; | ||
1962 | struct zoran *zr = fh->zr; | ||
1963 | |||
1964 | memset(fb, 0, sizeof(*fb)); | ||
1965 | mutex_lock(&zr->resource_lock); | ||
1966 | fb->base = zr->vbuf_base; | ||
1967 | fb->fmt.width = zr->vbuf_width; | ||
1968 | fb->fmt.height = zr->vbuf_height; | ||
1969 | if (zr->overlay_settings.format) | ||
1970 | fb->fmt.pixelformat = fh->overlay_settings.format->fourcc; | ||
1971 | fb->fmt.bytesperline = zr->vbuf_bytesperline; | ||
1972 | mutex_unlock(&zr->resource_lock); | ||
1973 | fb->fmt.colorspace = V4L2_COLORSPACE_SRGB; | ||
1974 | fb->fmt.field = V4L2_FIELD_INTERLACED; | ||
1975 | fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; | ||
1976 | |||
1977 | return 0; | ||
1978 | } | ||
1979 | |||
1980 | static int zoran_s_fbuf(struct file *file, void *__fh, | ||
1981 | struct v4l2_framebuffer *fb) | ||
1982 | { | ||
1983 | struct zoran_fh *fh = __fh; | ||
1984 | struct zoran *zr = fh->zr; | ||
1985 | int i, res = 0; | ||
1986 | __le32 printformat = __cpu_to_le32(fb->fmt.pixelformat); | ||
1987 | |||
1988 | for (i = 0; i < NUM_FORMATS; i++) | ||
1989 | if (zoran_formats[i].fourcc == fb->fmt.pixelformat) | ||
1990 | break; | ||
1991 | if (i == NUM_FORMATS) { | ||
1992 | dprintk(1, KERN_ERR "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n", | ||
1993 | ZR_DEVNAME(zr), fb->fmt.pixelformat, | ||
1994 | (char *)&printformat); | ||
1995 | return -EINVAL; | ||
1996 | } | ||
1997 | |||
1998 | mutex_lock(&zr->resource_lock); | ||
1999 | res = setup_fbuffer(fh, fb->base, &zoran_formats[i], fb->fmt.width, | ||
2000 | fb->fmt.height, fb->fmt.bytesperline); | ||
2001 | mutex_unlock(&zr->resource_lock); | ||
2002 | |||
2003 | return res; | ||
2004 | } | ||
2005 | |||
2006 | static int zoran_overlay(struct file *file, void *__fh, unsigned int on) | ||
2007 | { | ||
2008 | struct zoran_fh *fh = __fh; | ||
2009 | struct zoran *zr = fh->zr; | ||
2010 | int res; | ||
2011 | |||
2012 | mutex_lock(&zr->resource_lock); | ||
2013 | res = setup_overlay(fh, on); | ||
2014 | mutex_unlock(&zr->resource_lock); | ||
2015 | |||
2016 | return res; | ||
2017 | } | ||
2018 | |||
2019 | static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type); | ||
2020 | |||
2021 | static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *req) | ||
2022 | { | ||
2023 | struct zoran_fh *fh = __fh; | ||
2024 | struct zoran *zr = fh->zr; | ||
2025 | int res = 0; | ||
2026 | |||
2027 | if (req->memory != V4L2_MEMORY_MMAP) { | ||
2028 | dprintk(2, | ||
2029 | KERN_ERR | ||
2030 | "%s: only MEMORY_MMAP capture is supported, not %d\n", | ||
2031 | ZR_DEVNAME(zr), req->memory); | ||
2032 | return -EINVAL; | ||
2033 | } | ||
2034 | |||
2035 | if (req->count == 0) | ||
2036 | return zoran_streamoff(file, fh, req->type); | ||
2037 | |||
2038 | mutex_lock(&zr->resource_lock); | ||
2039 | if (fh->buffers.allocated) { | ||
2040 | dprintk(2, | ||
2041 | KERN_ERR | ||
2042 | "%s: VIDIOC_REQBUFS - buffers already allocated\n", | ||
2043 | ZR_DEVNAME(zr)); | ||
2044 | res = -EBUSY; | ||
2045 | goto v4l2reqbuf_unlock_and_return; | ||
2046 | } | ||
2047 | |||
2048 | if (fh->map_mode == ZORAN_MAP_MODE_RAW && | ||
2049 | req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
2050 | /* control user input */ | ||
2051 | if (req->count < 2) | ||
2052 | req->count = 2; | ||
2053 | if (req->count > v4l_nbufs) | ||
2054 | req->count = v4l_nbufs; | ||
2055 | |||
2056 | /* The next mmap will map the V4L buffers */ | ||
2057 | map_mode_raw(fh); | ||
2058 | fh->buffers.num_buffers = req->count; | ||
2059 | |||
2060 | if (v4l_fbuffer_alloc(fh)) { | ||
2061 | res = -ENOMEM; | ||
2062 | goto v4l2reqbuf_unlock_and_return; | ||
2063 | } | ||
2064 | } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC || | ||
2065 | fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { | ||
2066 | /* we need to calculate size ourselves now */ | ||
2067 | if (req->count < 4) | ||
2068 | req->count = 4; | ||
2069 | if (req->count > jpg_nbufs) | ||
2070 | req->count = jpg_nbufs; | ||
2071 | |||
2072 | /* The next mmap will map the MJPEG buffers */ | ||
2073 | map_mode_jpg(fh, req->type == V4L2_BUF_TYPE_VIDEO_OUTPUT); | ||
2074 | fh->buffers.num_buffers = req->count; | ||
2075 | fh->buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings); | ||
2076 | |||
2077 | if (jpg_fbuffer_alloc(fh)) { | ||
2078 | res = -ENOMEM; | ||
2079 | goto v4l2reqbuf_unlock_and_return; | ||
2080 | } | ||
2081 | } else { | ||
2082 | dprintk(1, | ||
2083 | KERN_ERR | ||
2084 | "%s: VIDIOC_REQBUFS - unknown type %d\n", | ||
2085 | ZR_DEVNAME(zr), req->type); | ||
2086 | res = -EINVAL; | ||
2087 | goto v4l2reqbuf_unlock_and_return; | ||
2088 | } | ||
2089 | v4l2reqbuf_unlock_and_return: | ||
2090 | mutex_unlock(&zr->resource_lock); | ||
2091 | |||
2092 | return res; | ||
2093 | } | ||
2094 | |||
2095 | static int zoran_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf) | ||
2096 | { | ||
2097 | struct zoran_fh *fh = __fh; | ||
2098 | struct zoran *zr = fh->zr; | ||
2099 | int res; | ||
2100 | |||
2101 | mutex_lock(&zr->resource_lock); | ||
2102 | res = zoran_v4l2_buffer_status(fh, buf, buf->index); | ||
2103 | mutex_unlock(&zr->resource_lock); | ||
2104 | |||
2105 | return res; | ||
2106 | } | ||
2107 | |||
2108 | static int zoran_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) | ||
2109 | { | ||
2110 | struct zoran_fh *fh = __fh; | ||
2111 | struct zoran *zr = fh->zr; | ||
2112 | int res = 0, codec_mode, buf_type; | ||
2113 | |||
2114 | mutex_lock(&zr->resource_lock); | ||
2115 | |||
2116 | switch (fh->map_mode) { | ||
2117 | case ZORAN_MAP_MODE_RAW: | ||
2118 | if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
2119 | dprintk(1, KERN_ERR | ||
2120 | "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", | ||
2121 | ZR_DEVNAME(zr), buf->type, fh->map_mode); | ||
2122 | res = -EINVAL; | ||
2123 | goto qbuf_unlock_and_return; | ||
2124 | } | ||
2125 | |||
2126 | res = zoran_v4l_queue_frame(fh, buf->index); | ||
2127 | if (res) | ||
2128 | goto qbuf_unlock_and_return; | ||
2129 | if (!zr->v4l_memgrab_active && fh->buffers.active == ZORAN_LOCKED) | ||
2130 | zr36057_set_memgrab(zr, 1); | ||
2131 | break; | ||
2132 | |||
2133 | case ZORAN_MAP_MODE_JPG_REC: | ||
2134 | case ZORAN_MAP_MODE_JPG_PLAY: | ||
2135 | if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { | ||
2136 | buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; | ||
2137 | codec_mode = BUZ_MODE_MOTION_DECOMPRESS; | ||
2138 | } else { | ||
2139 | buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
2140 | codec_mode = BUZ_MODE_MOTION_COMPRESS; | ||
2141 | } | ||
2142 | |||
2143 | if (buf->type != buf_type) { | ||
2144 | dprintk(1, KERN_ERR | ||
2145 | "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", | ||
2146 | ZR_DEVNAME(zr), buf->type, fh->map_mode); | ||
2147 | res = -EINVAL; | ||
2148 | goto qbuf_unlock_and_return; | ||
2149 | } | ||
2150 | |||
2151 | res = zoran_jpg_queue_frame(fh, buf->index, codec_mode); | ||
2152 | if (res != 0) | ||
2153 | goto qbuf_unlock_and_return; | ||
2154 | if (zr->codec_mode == BUZ_MODE_IDLE && | ||
2155 | fh->buffers.active == ZORAN_LOCKED) | ||
2156 | zr36057_enable_jpg(zr, codec_mode); | ||
2157 | |||
2158 | break; | ||
2159 | |||
2160 | default: | ||
2161 | dprintk(1, KERN_ERR | ||
2162 | "%s: VIDIOC_QBUF - unsupported type %d\n", | ||
2163 | ZR_DEVNAME(zr), buf->type); | ||
2164 | res = -EINVAL; | ||
2165 | break; | ||
2166 | } | ||
2167 | qbuf_unlock_and_return: | ||
2168 | mutex_unlock(&zr->resource_lock); | ||
2169 | |||
2170 | return res; | ||
2171 | } | ||
2172 | |||
2173 | static int zoran_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) | ||
2174 | { | ||
2175 | struct zoran_fh *fh = __fh; | ||
2176 | struct zoran *zr = fh->zr; | ||
2177 | int res = 0, buf_type, num = -1; /* compiler borks here (?) */ | ||
2178 | |||
2179 | mutex_lock(&zr->resource_lock); | ||
2180 | |||
2181 | switch (fh->map_mode) { | ||
2182 | case ZORAN_MAP_MODE_RAW: | ||
2183 | if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
2184 | dprintk(1, KERN_ERR | ||
2185 | "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", | ||
2186 | ZR_DEVNAME(zr), buf->type, fh->map_mode); | ||
2187 | res = -EINVAL; | ||
2188 | goto dqbuf_unlock_and_return; | ||
2189 | } | ||
2190 | |||
2191 | num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME]; | ||
2192 | if (file->f_flags & O_NONBLOCK && | ||
2193 | zr->v4l_buffers.buffer[num].state != BUZ_STATE_DONE) { | ||
2194 | res = -EAGAIN; | ||
2195 | goto dqbuf_unlock_and_return; | ||
2196 | } | ||
2197 | res = v4l_sync(fh, num); | ||
2198 | if (res) | ||
2199 | goto dqbuf_unlock_and_return; | ||
2200 | zr->v4l_sync_tail++; | ||
2201 | res = zoran_v4l2_buffer_status(fh, buf, num); | ||
2202 | break; | ||
2203 | |||
2204 | case ZORAN_MAP_MODE_JPG_REC: | ||
2205 | case ZORAN_MAP_MODE_JPG_PLAY: | ||
2206 | { | ||
2207 | struct zoran_sync bs; | ||
2208 | |||
2209 | if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) | ||
2210 | buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; | ||
2211 | else | ||
2212 | buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
2213 | |||
2214 | if (buf->type != buf_type) { | ||
2215 | dprintk(1, KERN_ERR | ||
2216 | "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", | ||
2217 | ZR_DEVNAME(zr), buf->type, fh->map_mode); | ||
2218 | res = -EINVAL; | ||
2219 | goto dqbuf_unlock_and_return; | ||
2220 | } | ||
2221 | |||
2222 | num = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME]; | ||
2223 | |||
2224 | if (file->f_flags & O_NONBLOCK && | ||
2225 | zr->jpg_buffers.buffer[num].state != BUZ_STATE_DONE) { | ||
2226 | res = -EAGAIN; | ||
2227 | goto dqbuf_unlock_and_return; | ||
2228 | } | ||
2229 | bs.frame = 0; /* suppress compiler warning */ | ||
2230 | res = jpg_sync(fh, &bs); | ||
2231 | if (res) | ||
2232 | goto dqbuf_unlock_and_return; | ||
2233 | res = zoran_v4l2_buffer_status(fh, buf, bs.frame); | ||
2234 | break; | ||
2235 | } | ||
2236 | |||
2237 | default: | ||
2238 | dprintk(1, KERN_ERR | ||
2239 | "%s: VIDIOC_DQBUF - unsupported type %d\n", | ||
2240 | ZR_DEVNAME(zr), buf->type); | ||
2241 | res = -EINVAL; | ||
2242 | break; | ||
2243 | } | ||
2244 | dqbuf_unlock_and_return: | ||
2245 | mutex_unlock(&zr->resource_lock); | ||
2246 | |||
2247 | return res; | ||
2248 | } | ||
2249 | |||
2250 | static int zoran_streamon(struct file *file, void *__fh, enum v4l2_buf_type type) | ||
2251 | { | ||
2252 | struct zoran_fh *fh = __fh; | ||
2253 | struct zoran *zr = fh->zr; | ||
2254 | int res = 0; | ||
2255 | |||
2256 | mutex_lock(&zr->resource_lock); | ||
2257 | |||
2258 | switch (fh->map_mode) { | ||
2259 | case ZORAN_MAP_MODE_RAW: /* raw capture */ | ||
2260 | if (zr->v4l_buffers.active != ZORAN_ACTIVE || | ||
2261 | fh->buffers.active != ZORAN_ACTIVE) { | ||
2262 | res = -EBUSY; | ||
2263 | goto strmon_unlock_and_return; | ||
2264 | } | ||
2265 | |||
2266 | zr->v4l_buffers.active = fh->buffers.active = ZORAN_LOCKED; | ||
2267 | zr->v4l_settings = fh->v4l_settings; | ||
2268 | |||
2269 | zr->v4l_sync_tail = zr->v4l_pend_tail; | ||
2270 | if (!zr->v4l_memgrab_active && | ||
2271 | zr->v4l_pend_head != zr->v4l_pend_tail) { | ||
2272 | zr36057_set_memgrab(zr, 1); | ||
2273 | } | ||
2274 | break; | ||
2275 | |||
2276 | case ZORAN_MAP_MODE_JPG_REC: | ||
2277 | case ZORAN_MAP_MODE_JPG_PLAY: | ||
2278 | /* what is the codec mode right now? */ | ||
2279 | if (zr->jpg_buffers.active != ZORAN_ACTIVE || | ||
2280 | fh->buffers.active != ZORAN_ACTIVE) { | ||
2281 | res = -EBUSY; | ||
2282 | goto strmon_unlock_and_return; | ||
2283 | } | ||
2284 | |||
2285 | zr->jpg_buffers.active = fh->buffers.active = ZORAN_LOCKED; | ||
2286 | |||
2287 | if (zr->jpg_que_head != zr->jpg_que_tail) { | ||
2288 | /* Start the jpeg codec when the first frame is queued */ | ||
2289 | jpeg_start(zr); | ||
2290 | } | ||
2291 | break; | ||
2292 | |||
2293 | default: | ||
2294 | dprintk(1, | ||
2295 | KERN_ERR | ||
2296 | "%s: VIDIOC_STREAMON - invalid map mode %d\n", | ||
2297 | ZR_DEVNAME(zr), fh->map_mode); | ||
2298 | res = -EINVAL; | ||
2299 | break; | ||
2300 | } | ||
2301 | strmon_unlock_and_return: | ||
2302 | mutex_unlock(&zr->resource_lock); | ||
2303 | |||
2304 | return res; | ||
2305 | } | ||
2306 | |||
2307 | static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type) | ||
2308 | { | ||
2309 | struct zoran_fh *fh = __fh; | ||
2310 | struct zoran *zr = fh->zr; | ||
2311 | int i, res = 0; | ||
2312 | unsigned long flags; | ||
2313 | |||
2314 | mutex_lock(&zr->resource_lock); | ||
2315 | |||
2316 | switch (fh->map_mode) { | ||
2317 | case ZORAN_MAP_MODE_RAW: /* raw capture */ | ||
2318 | if (fh->buffers.active == ZORAN_FREE && | ||
2319 | zr->v4l_buffers.active != ZORAN_FREE) { | ||
2320 | res = -EPERM; /* stay off other's settings! */ | ||
2321 | goto strmoff_unlock_and_return; | ||
2322 | } | ||
2323 | if (zr->v4l_buffers.active == ZORAN_FREE) | ||
2324 | goto strmoff_unlock_and_return; | ||
2325 | |||
2326 | spin_lock_irqsave(&zr->spinlock, flags); | ||
2327 | /* unload capture */ | ||
2328 | if (zr->v4l_memgrab_active) { | ||
2329 | |||
2330 | zr36057_set_memgrab(zr, 0); | ||
2331 | } | ||
2332 | |||
2333 | for (i = 0; i < fh->buffers.num_buffers; i++) | ||
2334 | zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER; | ||
2335 | fh->buffers = zr->v4l_buffers; | ||
2336 | |||
2337 | zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE; | ||
2338 | |||
2339 | zr->v4l_grab_seq = 0; | ||
2340 | zr->v4l_pend_head = zr->v4l_pend_tail = 0; | ||
2341 | zr->v4l_sync_tail = 0; | ||
2342 | |||
2343 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
2344 | |||
2345 | break; | ||
2346 | |||
2347 | case ZORAN_MAP_MODE_JPG_REC: | ||
2348 | case ZORAN_MAP_MODE_JPG_PLAY: | ||
2349 | if (fh->buffers.active == ZORAN_FREE && | ||
2350 | zr->jpg_buffers.active != ZORAN_FREE) { | ||
2351 | res = -EPERM; /* stay off other's settings! */ | ||
2352 | goto strmoff_unlock_and_return; | ||
2353 | } | ||
2354 | if (zr->jpg_buffers.active == ZORAN_FREE) | ||
2355 | goto strmoff_unlock_and_return; | ||
2356 | |||
2357 | res = jpg_qbuf(fh, -1, | ||
2358 | (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ? | ||
2359 | BUZ_MODE_MOTION_COMPRESS : | ||
2360 | BUZ_MODE_MOTION_DECOMPRESS); | ||
2361 | if (res) | ||
2362 | goto strmoff_unlock_and_return; | ||
2363 | break; | ||
2364 | default: | ||
2365 | dprintk(1, KERN_ERR | ||
2366 | "%s: VIDIOC_STREAMOFF - invalid map mode %d\n", | ||
2367 | ZR_DEVNAME(zr), fh->map_mode); | ||
2368 | res = -EINVAL; | ||
2369 | break; | ||
2370 | } | ||
2371 | strmoff_unlock_and_return: | ||
2372 | mutex_unlock(&zr->resource_lock); | ||
2373 | |||
2374 | return res; | ||
2375 | } | ||
2376 | |||
2377 | static int zoran_queryctrl(struct file *file, void *__fh, | ||
2378 | struct v4l2_queryctrl *ctrl) | ||
2379 | { | ||
2380 | struct zoran_fh *fh = __fh; | ||
2381 | struct zoran *zr = fh->zr; | ||
2382 | |||
2383 | /* we only support hue/saturation/contrast/brightness */ | ||
2384 | if (ctrl->id < V4L2_CID_BRIGHTNESS || | ||
2385 | ctrl->id > V4L2_CID_HUE) | ||
2386 | return -EINVAL; | ||
2387 | |||
2388 | decoder_call(zr, core, queryctrl, ctrl); | ||
2389 | |||
2390 | return 0; | ||
2391 | } | ||
2392 | |||
2393 | static int zoran_g_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl) | ||
2394 | { | ||
2395 | struct zoran_fh *fh = __fh; | ||
2396 | struct zoran *zr = fh->zr; | ||
2397 | |||
2398 | /* we only support hue/saturation/contrast/brightness */ | ||
2399 | if (ctrl->id < V4L2_CID_BRIGHTNESS || | ||
2400 | ctrl->id > V4L2_CID_HUE) | ||
2401 | return -EINVAL; | ||
2402 | |||
2403 | mutex_lock(&zr->resource_lock); | ||
2404 | decoder_call(zr, core, g_ctrl, ctrl); | ||
2405 | mutex_unlock(&zr->resource_lock); | ||
2406 | |||
2407 | return 0; | ||
2408 | } | ||
2409 | |||
2410 | static int zoran_s_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl) | ||
2411 | { | ||
2412 | struct zoran_fh *fh = __fh; | ||
2413 | struct zoran *zr = fh->zr; | ||
2414 | |||
2415 | /* we only support hue/saturation/contrast/brightness */ | ||
2416 | if (ctrl->id < V4L2_CID_BRIGHTNESS || | ||
2417 | ctrl->id > V4L2_CID_HUE) | ||
2418 | return -EINVAL; | ||
2419 | |||
2420 | mutex_lock(&zr->resource_lock); | ||
2421 | decoder_call(zr, core, s_ctrl, ctrl); | ||
2422 | mutex_unlock(&zr->resource_lock); | ||
2423 | |||
2424 | return 0; | ||
2425 | } | ||
2426 | |||
2427 | static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std) | ||
2428 | { | ||
2429 | struct zoran_fh *fh = __fh; | ||
2430 | struct zoran *zr = fh->zr; | ||
2431 | |||
2432 | mutex_lock(&zr->resource_lock); | ||
2433 | *std = zr->norm; | ||
2434 | mutex_unlock(&zr->resource_lock); | ||
2435 | return 0; | ||
2436 | } | ||
2437 | |||
2438 | static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id *std) | ||
2439 | { | ||
2440 | struct zoran_fh *fh = __fh; | ||
2441 | struct zoran *zr = fh->zr; | ||
2442 | int res = 0; | ||
2443 | |||
2444 | mutex_lock(&zr->resource_lock); | ||
2445 | res = zoran_set_norm(zr, *std); | ||
2446 | if (res) | ||
2447 | goto sstd_unlock_and_return; | ||
2448 | |||
2449 | res = wait_grab_pending(zr); | ||
2450 | sstd_unlock_and_return: | ||
2451 | mutex_unlock(&zr->resource_lock); | ||
2452 | return res; | ||
2453 | } | ||
2454 | |||
2455 | static int zoran_enum_input(struct file *file, void *__fh, | ||
2456 | struct v4l2_input *inp) | ||
2457 | { | ||
2458 | struct zoran_fh *fh = __fh; | ||
2459 | struct zoran *zr = fh->zr; | ||
2460 | |||
2461 | if (inp->index >= zr->card.inputs) | ||
2462 | return -EINVAL; | ||
2463 | |||
2464 | strncpy(inp->name, zr->card.input[inp->index].name, | ||
2465 | sizeof(inp->name) - 1); | ||
2466 | inp->type = V4L2_INPUT_TYPE_CAMERA; | ||
2467 | inp->std = V4L2_STD_ALL; | ||
2468 | |||
2469 | /* Get status of video decoder */ | ||
2470 | mutex_lock(&zr->resource_lock); | ||
2471 | decoder_call(zr, video, g_input_status, &inp->status); | ||
2472 | mutex_unlock(&zr->resource_lock); | ||
2473 | return 0; | ||
2474 | } | ||
2475 | |||
2476 | static int zoran_g_input(struct file *file, void *__fh, unsigned int *input) | ||
2477 | { | ||
2478 | struct zoran_fh *fh = __fh; | ||
2479 | struct zoran *zr = fh->zr; | ||
2480 | |||
2481 | mutex_lock(&zr->resource_lock); | ||
2482 | *input = zr->input; | ||
2483 | mutex_unlock(&zr->resource_lock); | ||
2484 | |||
2485 | return 0; | ||
2486 | } | ||
2487 | |||
2488 | static int zoran_s_input(struct file *file, void *__fh, unsigned int input) | ||
2489 | { | ||
2490 | struct zoran_fh *fh = __fh; | ||
2491 | struct zoran *zr = fh->zr; | ||
2492 | int res; | ||
2493 | |||
2494 | mutex_lock(&zr->resource_lock); | ||
2495 | res = zoran_set_input(zr, input); | ||
2496 | if (res) | ||
2497 | goto sinput_unlock_and_return; | ||
2498 | |||
2499 | /* Make sure the changes come into effect */ | ||
2500 | res = wait_grab_pending(zr); | ||
2501 | sinput_unlock_and_return: | ||
2502 | mutex_unlock(&zr->resource_lock); | ||
2503 | return res; | ||
2504 | } | ||
2505 | |||
2506 | static int zoran_enum_output(struct file *file, void *__fh, | ||
2507 | struct v4l2_output *outp) | ||
2508 | { | ||
2509 | if (outp->index != 0) | ||
2510 | return -EINVAL; | ||
2511 | |||
2512 | outp->index = 0; | ||
2513 | outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY; | ||
2514 | strncpy(outp->name, "Autodetect", sizeof(outp->name)-1); | ||
2515 | |||
2516 | return 0; | ||
2517 | } | ||
2518 | |||
2519 | static int zoran_g_output(struct file *file, void *__fh, unsigned int *output) | ||
2520 | { | ||
2521 | *output = 0; | ||
2522 | |||
2523 | return 0; | ||
2524 | } | ||
2525 | |||
2526 | static int zoran_s_output(struct file *file, void *__fh, unsigned int output) | ||
2527 | { | ||
2528 | if (output != 0) | ||
2529 | return -EINVAL; | ||
2530 | |||
2531 | return 0; | ||
2532 | } | ||
2533 | |||
2534 | /* cropping (sub-frame capture) */ | ||
2535 | static int zoran_cropcap(struct file *file, void *__fh, | ||
2536 | struct v4l2_cropcap *cropcap) | ||
2537 | { | ||
2538 | struct zoran_fh *fh = __fh; | ||
2539 | struct zoran *zr = fh->zr; | ||
2540 | int type = cropcap->type, res = 0; | ||
2541 | |||
2542 | memset(cropcap, 0, sizeof(*cropcap)); | ||
2543 | cropcap->type = type; | ||
2544 | |||
2545 | mutex_lock(&zr->resource_lock); | ||
2546 | |||
2547 | if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && | ||
2548 | (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || | ||
2549 | fh->map_mode == ZORAN_MAP_MODE_RAW)) { | ||
2550 | dprintk(1, KERN_ERR | ||
2551 | "%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n", | ||
2552 | ZR_DEVNAME(zr)); | ||
2553 | res = -EINVAL; | ||
2554 | goto cropcap_unlock_and_return; | ||
2555 | } | ||
2556 | |||
2557 | cropcap->bounds.top = cropcap->bounds.left = 0; | ||
2558 | cropcap->bounds.width = BUZ_MAX_WIDTH; | ||
2559 | cropcap->bounds.height = BUZ_MAX_HEIGHT; | ||
2560 | cropcap->defrect.top = cropcap->defrect.left = 0; | ||
2561 | cropcap->defrect.width = BUZ_MIN_WIDTH; | ||
2562 | cropcap->defrect.height = BUZ_MIN_HEIGHT; | ||
2563 | cropcap_unlock_and_return: | ||
2564 | mutex_unlock(&zr->resource_lock); | ||
2565 | return res; | ||
2566 | } | ||
2567 | |||
2568 | static int zoran_g_crop(struct file *file, void *__fh, struct v4l2_crop *crop) | ||
2569 | { | ||
2570 | struct zoran_fh *fh = __fh; | ||
2571 | struct zoran *zr = fh->zr; | ||
2572 | int type = crop->type, res = 0; | ||
2573 | |||
2574 | memset(crop, 0, sizeof(*crop)); | ||
2575 | crop->type = type; | ||
2576 | |||
2577 | mutex_lock(&zr->resource_lock); | ||
2578 | |||
2579 | if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && | ||
2580 | (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || | ||
2581 | fh->map_mode == ZORAN_MAP_MODE_RAW)) { | ||
2582 | dprintk(1, | ||
2583 | KERN_ERR | ||
2584 | "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n", | ||
2585 | ZR_DEVNAME(zr)); | ||
2586 | res = -EINVAL; | ||
2587 | goto gcrop_unlock_and_return; | ||
2588 | } | ||
2589 | |||
2590 | crop->c.top = fh->jpg_settings.img_y; | ||
2591 | crop->c.left = fh->jpg_settings.img_x; | ||
2592 | crop->c.width = fh->jpg_settings.img_width; | ||
2593 | crop->c.height = fh->jpg_settings.img_height; | ||
2594 | |||
2595 | gcrop_unlock_and_return: | ||
2596 | mutex_unlock(&zr->resource_lock); | ||
2597 | |||
2598 | return res; | ||
2599 | } | ||
2600 | |||
2601 | static int zoran_s_crop(struct file *file, void *__fh, struct v4l2_crop *crop) | ||
2602 | { | ||
2603 | struct zoran_fh *fh = __fh; | ||
2604 | struct zoran *zr = fh->zr; | ||
2605 | int res = 0; | ||
2606 | struct zoran_jpg_settings settings; | ||
2607 | |||
2608 | settings = fh->jpg_settings; | ||
2609 | |||
2610 | mutex_lock(&zr->resource_lock); | ||
2611 | |||
2612 | if (fh->buffers.allocated) { | ||
2613 | dprintk(1, KERN_ERR | ||
2614 | "%s: VIDIOC_S_CROP - cannot change settings while active\n", | ||
2615 | ZR_DEVNAME(zr)); | ||
2616 | res = -EBUSY; | ||
2617 | goto scrop_unlock_and_return; | ||
2618 | } | ||
2619 | |||
2620 | if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && | ||
2621 | (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || | ||
2622 | fh->map_mode == ZORAN_MAP_MODE_RAW)) { | ||
2623 | dprintk(1, KERN_ERR | ||
2624 | "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n", | ||
2625 | ZR_DEVNAME(zr)); | ||
2626 | res = -EINVAL; | ||
2627 | goto scrop_unlock_and_return; | ||
2628 | } | ||
2629 | |||
2630 | /* move into a form that we understand */ | ||
2631 | settings.img_x = crop->c.left; | ||
2632 | settings.img_y = crop->c.top; | ||
2633 | settings.img_width = crop->c.width; | ||
2634 | settings.img_height = crop->c.height; | ||
2635 | |||
2636 | /* check validity */ | ||
2637 | res = zoran_check_jpg_settings(zr, &settings, 0); | ||
2638 | if (res) | ||
2639 | goto scrop_unlock_and_return; | ||
2640 | |||
2641 | /* accept */ | ||
2642 | fh->jpg_settings = settings; | ||
2643 | |||
2644 | scrop_unlock_and_return: | ||
2645 | mutex_unlock(&zr->resource_lock); | ||
2646 | return res; | ||
2647 | } | ||
2648 | |||
2649 | static int zoran_g_jpegcomp(struct file *file, void *__fh, | ||
2650 | struct v4l2_jpegcompression *params) | ||
2651 | { | ||
2652 | struct zoran_fh *fh = __fh; | ||
2653 | struct zoran *zr = fh->zr; | ||
2654 | memset(params, 0, sizeof(*params)); | ||
2655 | |||
2656 | mutex_lock(&zr->resource_lock); | ||
2657 | |||
2658 | params->quality = fh->jpg_settings.jpg_comp.quality; | ||
2659 | params->APPn = fh->jpg_settings.jpg_comp.APPn; | ||
2660 | memcpy(params->APP_data, | ||
2661 | fh->jpg_settings.jpg_comp.APP_data, | ||
2662 | fh->jpg_settings.jpg_comp.APP_len); | ||
2663 | params->APP_len = fh->jpg_settings.jpg_comp.APP_len; | ||
2664 | memcpy(params->COM_data, | ||
2665 | fh->jpg_settings.jpg_comp.COM_data, | ||
2666 | fh->jpg_settings.jpg_comp.COM_len); | ||
2667 | params->COM_len = fh->jpg_settings.jpg_comp.COM_len; | ||
2668 | params->jpeg_markers = | ||
2669 | fh->jpg_settings.jpg_comp.jpeg_markers; | ||
2670 | |||
2671 | mutex_unlock(&zr->resource_lock); | ||
2672 | |||
2673 | return 0; | ||
2674 | } | ||
2675 | |||
2676 | static int zoran_s_jpegcomp(struct file *file, void *__fh, | ||
2677 | struct v4l2_jpegcompression *params) | ||
2678 | { | ||
2679 | struct zoran_fh *fh = __fh; | ||
2680 | struct zoran *zr = fh->zr; | ||
2681 | int res = 0; | ||
2682 | struct zoran_jpg_settings settings; | ||
2683 | |||
2684 | settings = fh->jpg_settings; | ||
2685 | |||
2686 | settings.jpg_comp = *params; | ||
2687 | |||
2688 | mutex_lock(&zr->resource_lock); | ||
2689 | |||
2690 | if (fh->buffers.active != ZORAN_FREE) { | ||
2691 | dprintk(1, KERN_WARNING | ||
2692 | "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n", | ||
2693 | ZR_DEVNAME(zr)); | ||
2694 | res = -EBUSY; | ||
2695 | goto sjpegc_unlock_and_return; | ||
2696 | } | ||
2697 | |||
2698 | res = zoran_check_jpg_settings(zr, &settings, 0); | ||
2699 | if (res) | ||
2700 | goto sjpegc_unlock_and_return; | ||
2701 | if (!fh->buffers.allocated) | ||
2702 | fh->buffers.buffer_size = | ||
2703 | zoran_v4l2_calc_bufsize(&fh->jpg_settings); | ||
2704 | fh->jpg_settings.jpg_comp = *params = settings.jpg_comp; | ||
2705 | sjpegc_unlock_and_return: | ||
2706 | mutex_unlock(&zr->resource_lock); | ||
2707 | |||
2708 | return res; | ||
2709 | } | ||
2710 | |||
2711 | static unsigned int | ||
2712 | zoran_poll (struct file *file, | ||
2713 | poll_table *wait) | ||
2714 | { | ||
2715 | struct zoran_fh *fh = file->private_data; | ||
2716 | struct zoran *zr = fh->zr; | ||
2717 | int res = 0, frame; | ||
2718 | unsigned long flags; | ||
2719 | |||
2720 | /* we should check whether buffers are ready to be synced on | ||
2721 | * (w/o waits - O_NONBLOCK) here | ||
2722 | * if ready for read (sync), return POLLIN|POLLRDNORM, | ||
2723 | * if ready for write (sync), return POLLOUT|POLLWRNORM, | ||
2724 | * if error, return POLLERR, | ||
2725 | * if no buffers queued or so, return POLLNVAL | ||
2726 | */ | ||
2727 | |||
2728 | mutex_lock(&zr->resource_lock); | ||
2729 | |||
2730 | switch (fh->map_mode) { | ||
2731 | case ZORAN_MAP_MODE_RAW: | ||
2732 | poll_wait(file, &zr->v4l_capq, wait); | ||
2733 | frame = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME]; | ||
2734 | |||
2735 | spin_lock_irqsave(&zr->spinlock, flags); | ||
2736 | dprintk(3, | ||
2737 | KERN_DEBUG | ||
2738 | "%s: %s() raw - active=%c, sync_tail=%lu/%c, pend_tail=%lu, pend_head=%lu\n", | ||
2739 | ZR_DEVNAME(zr), __func__, | ||
2740 | "FAL"[fh->buffers.active], zr->v4l_sync_tail, | ||
2741 | "UPMD"[zr->v4l_buffers.buffer[frame].state], | ||
2742 | zr->v4l_pend_tail, zr->v4l_pend_head); | ||
2743 | /* Process is the one capturing? */ | ||
2744 | if (fh->buffers.active != ZORAN_FREE && | ||
2745 | /* Buffer ready to DQBUF? */ | ||
2746 | zr->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE) | ||
2747 | res = POLLIN | POLLRDNORM; | ||
2748 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
2749 | |||
2750 | break; | ||
2751 | |||
2752 | case ZORAN_MAP_MODE_JPG_REC: | ||
2753 | case ZORAN_MAP_MODE_JPG_PLAY: | ||
2754 | poll_wait(file, &zr->jpg_capq, wait); | ||
2755 | frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME]; | ||
2756 | |||
2757 | spin_lock_irqsave(&zr->spinlock, flags); | ||
2758 | dprintk(3, | ||
2759 | KERN_DEBUG | ||
2760 | "%s: %s() jpg - active=%c, que_tail=%lu/%c, que_head=%lu, dma=%lu/%lu\n", | ||
2761 | ZR_DEVNAME(zr), __func__, | ||
2762 | "FAL"[fh->buffers.active], zr->jpg_que_tail, | ||
2763 | "UPMD"[zr->jpg_buffers.buffer[frame].state], | ||
2764 | zr->jpg_que_head, zr->jpg_dma_tail, zr->jpg_dma_head); | ||
2765 | if (fh->buffers.active != ZORAN_FREE && | ||
2766 | zr->jpg_buffers.buffer[frame].state == BUZ_STATE_DONE) { | ||
2767 | if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) | ||
2768 | res = POLLIN | POLLRDNORM; | ||
2769 | else | ||
2770 | res = POLLOUT | POLLWRNORM; | ||
2771 | } | ||
2772 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
2773 | |||
2774 | break; | ||
2775 | |||
2776 | default: | ||
2777 | dprintk(1, | ||
2778 | KERN_ERR | ||
2779 | "%s: %s - internal error, unknown map_mode=%d\n", | ||
2780 | ZR_DEVNAME(zr), __func__, fh->map_mode); | ||
2781 | res = POLLNVAL; | ||
2782 | } | ||
2783 | |||
2784 | mutex_unlock(&zr->resource_lock); | ||
2785 | |||
2786 | return res; | ||
2787 | } | ||
2788 | |||
2789 | |||
2790 | /* | ||
2791 | * This maps the buffers to user space. | ||
2792 | * | ||
2793 | * Depending on the state of fh->map_mode | ||
2794 | * the V4L or the MJPEG buffers are mapped | ||
2795 | * per buffer or all together | ||
2796 | * | ||
2797 | * Note that we need to connect to some | ||
2798 | * unmap signal event to unmap the de-allocate | ||
2799 | * the buffer accordingly (zoran_vm_close()) | ||
2800 | */ | ||
2801 | |||
2802 | static void | ||
2803 | zoran_vm_open (struct vm_area_struct *vma) | ||
2804 | { | ||
2805 | struct zoran_mapping *map = vma->vm_private_data; | ||
2806 | |||
2807 | map->count++; | ||
2808 | } | ||
2809 | |||
2810 | static void | ||
2811 | zoran_vm_close (struct vm_area_struct *vma) | ||
2812 | { | ||
2813 | struct zoran_mapping *map = vma->vm_private_data; | ||
2814 | struct zoran_fh *fh = map->fh; | ||
2815 | struct zoran *zr = fh->zr; | ||
2816 | int i; | ||
2817 | |||
2818 | if (--map->count > 0) | ||
2819 | return; | ||
2820 | |||
2821 | dprintk(3, KERN_INFO "%s: %s - munmap(%s)\n", ZR_DEVNAME(zr), | ||
2822 | __func__, mode_name(fh->map_mode)); | ||
2823 | |||
2824 | for (i = 0; i < fh->buffers.num_buffers; i++) { | ||
2825 | if (fh->buffers.buffer[i].map == map) | ||
2826 | fh->buffers.buffer[i].map = NULL; | ||
2827 | } | ||
2828 | kfree(map); | ||
2829 | |||
2830 | /* Any buffers still mapped? */ | ||
2831 | for (i = 0; i < fh->buffers.num_buffers; i++) | ||
2832 | if (fh->buffers.buffer[i].map) | ||
2833 | return; | ||
2834 | |||
2835 | dprintk(3, KERN_INFO "%s: %s - free %s buffers\n", ZR_DEVNAME(zr), | ||
2836 | __func__, mode_name(fh->map_mode)); | ||
2837 | |||
2838 | mutex_lock(&zr->resource_lock); | ||
2839 | |||
2840 | if (fh->map_mode == ZORAN_MAP_MODE_RAW) { | ||
2841 | if (fh->buffers.active != ZORAN_FREE) { | ||
2842 | unsigned long flags; | ||
2843 | |||
2844 | spin_lock_irqsave(&zr->spinlock, flags); | ||
2845 | zr36057_set_memgrab(zr, 0); | ||
2846 | zr->v4l_buffers.allocated = 0; | ||
2847 | zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE; | ||
2848 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
2849 | } | ||
2850 | v4l_fbuffer_free(fh); | ||
2851 | } else { | ||
2852 | if (fh->buffers.active != ZORAN_FREE) { | ||
2853 | jpg_qbuf(fh, -1, zr->codec_mode); | ||
2854 | zr->jpg_buffers.allocated = 0; | ||
2855 | zr->jpg_buffers.active = fh->buffers.active = ZORAN_FREE; | ||
2856 | } | ||
2857 | jpg_fbuffer_free(fh); | ||
2858 | } | ||
2859 | |||
2860 | mutex_unlock(&zr->resource_lock); | ||
2861 | } | ||
2862 | |||
2863 | static const struct vm_operations_struct zoran_vm_ops = { | ||
2864 | .open = zoran_vm_open, | ||
2865 | .close = zoran_vm_close, | ||
2866 | }; | ||
2867 | |||
2868 | static int | ||
2869 | zoran_mmap (struct file *file, | ||
2870 | struct vm_area_struct *vma) | ||
2871 | { | ||
2872 | struct zoran_fh *fh = file->private_data; | ||
2873 | struct zoran *zr = fh->zr; | ||
2874 | unsigned long size = (vma->vm_end - vma->vm_start); | ||
2875 | unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; | ||
2876 | int i, j; | ||
2877 | unsigned long page, start = vma->vm_start, todo, pos, fraglen; | ||
2878 | int first, last; | ||
2879 | struct zoran_mapping *map; | ||
2880 | int res = 0; | ||
2881 | |||
2882 | dprintk(3, | ||
2883 | KERN_INFO "%s: %s(%s) of 0x%08lx-0x%08lx (size=%lu)\n", | ||
2884 | ZR_DEVNAME(zr), __func__, | ||
2885 | mode_name(fh->map_mode), vma->vm_start, vma->vm_end, size); | ||
2886 | |||
2887 | if (!(vma->vm_flags & VM_SHARED) || !(vma->vm_flags & VM_READ) || | ||
2888 | !(vma->vm_flags & VM_WRITE)) { | ||
2889 | dprintk(1, | ||
2890 | KERN_ERR | ||
2891 | "%s: %s - no MAP_SHARED/PROT_{READ,WRITE} given\n", | ||
2892 | ZR_DEVNAME(zr), __func__); | ||
2893 | return -EINVAL; | ||
2894 | } | ||
2895 | |||
2896 | mutex_lock(&zr->resource_lock); | ||
2897 | |||
2898 | if (!fh->buffers.allocated) { | ||
2899 | dprintk(1, | ||
2900 | KERN_ERR | ||
2901 | "%s: %s(%s) - buffers not yet allocated\n", | ||
2902 | ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode)); | ||
2903 | res = -ENOMEM; | ||
2904 | goto mmap_unlock_and_return; | ||
2905 | } | ||
2906 | |||
2907 | first = offset / fh->buffers.buffer_size; | ||
2908 | last = first - 1 + size / fh->buffers.buffer_size; | ||
2909 | if (offset % fh->buffers.buffer_size != 0 || | ||
2910 | size % fh->buffers.buffer_size != 0 || first < 0 || | ||
2911 | last < 0 || first >= fh->buffers.num_buffers || | ||
2912 | last >= fh->buffers.buffer_size) { | ||
2913 | dprintk(1, | ||
2914 | KERN_ERR | ||
2915 | "%s: %s(%s) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n", | ||
2916 | ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode), offset, size, | ||
2917 | fh->buffers.buffer_size, | ||
2918 | fh->buffers.num_buffers); | ||
2919 | res = -EINVAL; | ||
2920 | goto mmap_unlock_and_return; | ||
2921 | } | ||
2922 | |||
2923 | /* Check if any buffers are already mapped */ | ||
2924 | for (i = first; i <= last; i++) { | ||
2925 | if (fh->buffers.buffer[i].map) { | ||
2926 | dprintk(1, | ||
2927 | KERN_ERR | ||
2928 | "%s: %s(%s) - buffer %d already mapped\n", | ||
2929 | ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode), i); | ||
2930 | res = -EBUSY; | ||
2931 | goto mmap_unlock_and_return; | ||
2932 | } | ||
2933 | } | ||
2934 | |||
2935 | /* map these buffers */ | ||
2936 | map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL); | ||
2937 | if (!map) { | ||
2938 | res = -ENOMEM; | ||
2939 | goto mmap_unlock_and_return; | ||
2940 | } | ||
2941 | map->fh = fh; | ||
2942 | map->count = 1; | ||
2943 | |||
2944 | vma->vm_ops = &zoran_vm_ops; | ||
2945 | vma->vm_flags |= VM_DONTEXPAND; | ||
2946 | vma->vm_private_data = map; | ||
2947 | |||
2948 | if (fh->map_mode == ZORAN_MAP_MODE_RAW) { | ||
2949 | for (i = first; i <= last; i++) { | ||
2950 | todo = size; | ||
2951 | if (todo > fh->buffers.buffer_size) | ||
2952 | todo = fh->buffers.buffer_size; | ||
2953 | page = fh->buffers.buffer[i].v4l.fbuffer_phys; | ||
2954 | if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, | ||
2955 | todo, PAGE_SHARED)) { | ||
2956 | dprintk(1, | ||
2957 | KERN_ERR | ||
2958 | "%s: %s(V4L) - remap_pfn_range failed\n", | ||
2959 | ZR_DEVNAME(zr), __func__); | ||
2960 | res = -EAGAIN; | ||
2961 | goto mmap_unlock_and_return; | ||
2962 | } | ||
2963 | size -= todo; | ||
2964 | start += todo; | ||
2965 | fh->buffers.buffer[i].map = map; | ||
2966 | if (size == 0) | ||
2967 | break; | ||
2968 | } | ||
2969 | } else { | ||
2970 | for (i = first; i <= last; i++) { | ||
2971 | for (j = 0; | ||
2972 | j < fh->buffers.buffer_size / PAGE_SIZE; | ||
2973 | j++) { | ||
2974 | fraglen = | ||
2975 | (le32_to_cpu(fh->buffers.buffer[i].jpg. | ||
2976 | frag_tab[2 * j + 1]) & ~1) << 1; | ||
2977 | todo = size; | ||
2978 | if (todo > fraglen) | ||
2979 | todo = fraglen; | ||
2980 | pos = | ||
2981 | le32_to_cpu(fh->buffers. | ||
2982 | buffer[i].jpg.frag_tab[2 * j]); | ||
2983 | /* should just be pos on i386 */ | ||
2984 | page = virt_to_phys(bus_to_virt(pos)) | ||
2985 | >> PAGE_SHIFT; | ||
2986 | if (remap_pfn_range(vma, start, page, | ||
2987 | todo, PAGE_SHARED)) { | ||
2988 | dprintk(1, | ||
2989 | KERN_ERR | ||
2990 | "%s: %s(V4L) - remap_pfn_range failed\n", | ||
2991 | ZR_DEVNAME(zr), __func__); | ||
2992 | res = -EAGAIN; | ||
2993 | goto mmap_unlock_and_return; | ||
2994 | } | ||
2995 | size -= todo; | ||
2996 | start += todo; | ||
2997 | if (size == 0) | ||
2998 | break; | ||
2999 | if (le32_to_cpu(fh->buffers.buffer[i].jpg. | ||
3000 | frag_tab[2 * j + 1]) & 1) | ||
3001 | break; /* was last fragment */ | ||
3002 | } | ||
3003 | fh->buffers.buffer[i].map = map; | ||
3004 | if (size == 0) | ||
3005 | break; | ||
3006 | |||
3007 | } | ||
3008 | } | ||
3009 | |||
3010 | mmap_unlock_and_return: | ||
3011 | mutex_unlock(&zr->resource_lock); | ||
3012 | |||
3013 | return res; | ||
3014 | } | ||
3015 | |||
3016 | static const struct v4l2_ioctl_ops zoran_ioctl_ops = { | ||
3017 | .vidioc_querycap = zoran_querycap, | ||
3018 | .vidioc_cropcap = zoran_cropcap, | ||
3019 | .vidioc_s_crop = zoran_s_crop, | ||
3020 | .vidioc_g_crop = zoran_g_crop, | ||
3021 | .vidioc_enum_input = zoran_enum_input, | ||
3022 | .vidioc_g_input = zoran_g_input, | ||
3023 | .vidioc_s_input = zoran_s_input, | ||
3024 | .vidioc_enum_output = zoran_enum_output, | ||
3025 | .vidioc_g_output = zoran_g_output, | ||
3026 | .vidioc_s_output = zoran_s_output, | ||
3027 | .vidioc_g_fbuf = zoran_g_fbuf, | ||
3028 | .vidioc_s_fbuf = zoran_s_fbuf, | ||
3029 | .vidioc_g_std = zoran_g_std, | ||
3030 | .vidioc_s_std = zoran_s_std, | ||
3031 | .vidioc_g_jpegcomp = zoran_g_jpegcomp, | ||
3032 | .vidioc_s_jpegcomp = zoran_s_jpegcomp, | ||
3033 | .vidioc_overlay = zoran_overlay, | ||
3034 | .vidioc_reqbufs = zoran_reqbufs, | ||
3035 | .vidioc_querybuf = zoran_querybuf, | ||
3036 | .vidioc_qbuf = zoran_qbuf, | ||
3037 | .vidioc_dqbuf = zoran_dqbuf, | ||
3038 | .vidioc_streamon = zoran_streamon, | ||
3039 | .vidioc_streamoff = zoran_streamoff, | ||
3040 | .vidioc_enum_fmt_vid_cap = zoran_enum_fmt_vid_cap, | ||
3041 | .vidioc_enum_fmt_vid_out = zoran_enum_fmt_vid_out, | ||
3042 | .vidioc_enum_fmt_vid_overlay = zoran_enum_fmt_vid_overlay, | ||
3043 | .vidioc_g_fmt_vid_cap = zoran_g_fmt_vid_cap, | ||
3044 | .vidioc_g_fmt_vid_out = zoran_g_fmt_vid_out, | ||
3045 | .vidioc_g_fmt_vid_overlay = zoran_g_fmt_vid_overlay, | ||
3046 | .vidioc_s_fmt_vid_cap = zoran_s_fmt_vid_cap, | ||
3047 | .vidioc_s_fmt_vid_out = zoran_s_fmt_vid_out, | ||
3048 | .vidioc_s_fmt_vid_overlay = zoran_s_fmt_vid_overlay, | ||
3049 | .vidioc_try_fmt_vid_cap = zoran_try_fmt_vid_cap, | ||
3050 | .vidioc_try_fmt_vid_out = zoran_try_fmt_vid_out, | ||
3051 | .vidioc_try_fmt_vid_overlay = zoran_try_fmt_vid_overlay, | ||
3052 | .vidioc_queryctrl = zoran_queryctrl, | ||
3053 | .vidioc_s_ctrl = zoran_s_ctrl, | ||
3054 | .vidioc_g_ctrl = zoran_g_ctrl, | ||
3055 | }; | ||
3056 | |||
3057 | /* please use zr->resource_lock consistently and kill this wrapper */ | ||
3058 | static long zoran_ioctl(struct file *file, unsigned int cmd, | ||
3059 | unsigned long arg) | ||
3060 | { | ||
3061 | struct zoran_fh *fh = file->private_data; | ||
3062 | struct zoran *zr = fh->zr; | ||
3063 | int ret; | ||
3064 | |||
3065 | mutex_lock(&zr->other_lock); | ||
3066 | ret = video_ioctl2(file, cmd, arg); | ||
3067 | mutex_unlock(&zr->other_lock); | ||
3068 | |||
3069 | return ret; | ||
3070 | } | ||
3071 | |||
3072 | static const struct v4l2_file_operations zoran_fops = { | ||
3073 | .owner = THIS_MODULE, | ||
3074 | .open = zoran_open, | ||
3075 | .release = zoran_close, | ||
3076 | .unlocked_ioctl = zoran_ioctl, | ||
3077 | .read = zoran_read, | ||
3078 | .write = zoran_write, | ||
3079 | .mmap = zoran_mmap, | ||
3080 | .poll = zoran_poll, | ||
3081 | }; | ||
3082 | |||
3083 | struct video_device zoran_template __devinitdata = { | ||
3084 | .name = ZORAN_NAME, | ||
3085 | .fops = &zoran_fops, | ||
3086 | .ioctl_ops = &zoran_ioctl_ops, | ||
3087 | .release = &zoran_vdev_release, | ||
3088 | .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, | ||
3089 | }; | ||
3090 | |||
diff --git a/drivers/media/video/zoran/zoran_procfs.c b/drivers/media/video/zoran/zoran_procfs.c deleted file mode 100644 index f1423b777db1..000000000000 --- a/drivers/media/video/zoran/zoran_procfs.c +++ /dev/null | |||
@@ -1,225 +0,0 @@ | |||
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 the procFS entries (/proc/ZORAN[%d]) | ||
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/types.h> | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/vmalloc.h> | ||
34 | |||
35 | #include <linux/proc_fs.h> | ||
36 | #include <linux/pci.h> | ||
37 | #include <linux/i2c.h> | ||
38 | #include <linux/i2c-algo-bit.h> | ||
39 | #include <linux/videodev2.h> | ||
40 | #include <linux/spinlock.h> | ||
41 | #include <linux/sem.h> | ||
42 | #include <linux/seq_file.h> | ||
43 | |||
44 | #include <linux/ctype.h> | ||
45 | #include <linux/poll.h> | ||
46 | #include <asm/io.h> | ||
47 | |||
48 | #include "videocodec.h" | ||
49 | #include "zoran.h" | ||
50 | #include "zoran_procfs.h" | ||
51 | #include "zoran_card.h" | ||
52 | |||
53 | #ifdef CONFIG_PROC_FS | ||
54 | struct procfs_params_zr36067 { | ||
55 | char *name; | ||
56 | short reg; | ||
57 | u32 mask; | ||
58 | short bit; | ||
59 | }; | ||
60 | |||
61 | static const struct procfs_params_zr36067 zr67[] = { | ||
62 | {"HSPol", 0x000, 1, 30}, | ||
63 | {"HStart", 0x000, 0x3ff, 10}, | ||
64 | {"HEnd", 0x000, 0x3ff, 0}, | ||
65 | |||
66 | {"VSPol", 0x004, 1, 30}, | ||
67 | {"VStart", 0x004, 0x3ff, 10}, | ||
68 | {"VEnd", 0x004, 0x3ff, 0}, | ||
69 | |||
70 | {"ExtFl", 0x008, 1, 26}, | ||
71 | {"TopField", 0x008, 1, 25}, | ||
72 | {"VCLKPol", 0x008, 1, 24}, | ||
73 | {"DupFld", 0x008, 1, 20}, | ||
74 | {"LittleEndian", 0x008, 1, 0}, | ||
75 | |||
76 | {"HsyncStart", 0x10c, 0xffff, 16}, | ||
77 | {"LineTot", 0x10c, 0xffff, 0}, | ||
78 | |||
79 | {"NAX", 0x110, 0xffff, 16}, | ||
80 | {"PAX", 0x110, 0xffff, 0}, | ||
81 | |||
82 | {"NAY", 0x114, 0xffff, 16}, | ||
83 | {"PAY", 0x114, 0xffff, 0}, | ||
84 | |||
85 | /* {"",,,}, */ | ||
86 | |||
87 | {NULL, 0, 0, 0}, | ||
88 | }; | ||
89 | |||
90 | static void | ||
91 | setparam (struct zoran *zr, | ||
92 | char *name, | ||
93 | char *sval) | ||
94 | { | ||
95 | int i = 0, reg0, reg, val; | ||
96 | |||
97 | while (zr67[i].name != NULL) { | ||
98 | if (!strncmp(name, zr67[i].name, strlen(zr67[i].name))) { | ||
99 | reg = reg0 = btread(zr67[i].reg); | ||
100 | reg &= ~(zr67[i].mask << zr67[i].bit); | ||
101 | if (!isdigit(sval[0])) | ||
102 | break; | ||
103 | val = simple_strtoul(sval, NULL, 0); | ||
104 | if ((val & ~zr67[i].mask)) | ||
105 | break; | ||
106 | reg |= (val & zr67[i].mask) << zr67[i].bit; | ||
107 | dprintk(4, | ||
108 | KERN_INFO | ||
109 | "%s: setparam: setting ZR36067 register 0x%03x: 0x%08x=>0x%08x %s=%d\n", | ||
110 | ZR_DEVNAME(zr), zr67[i].reg, reg0, reg, | ||
111 | zr67[i].name, val); | ||
112 | btwrite(reg, zr67[i].reg); | ||
113 | break; | ||
114 | } | ||
115 | i++; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | static int zoran_show(struct seq_file *p, void *v) | ||
120 | { | ||
121 | struct zoran *zr = p->private; | ||
122 | int i; | ||
123 | |||
124 | seq_printf(p, "ZR36067 registers:\n"); | ||
125 | for (i = 0; i < 0x130; i += 16) | ||
126 | seq_printf(p, "%03X %08X %08X %08X %08X \n", i, | ||
127 | btread(i), btread(i+4), btread(i+8), btread(i+12)); | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static int zoran_open(struct inode *inode, struct file *file) | ||
132 | { | ||
133 | struct zoran *data = PDE(inode)->data; | ||
134 | return single_open(file, zoran_show, data); | ||
135 | } | ||
136 | |||
137 | static ssize_t zoran_write(struct file *file, const char __user *buffer, | ||
138 | size_t count, loff_t *ppos) | ||
139 | { | ||
140 | struct zoran *zr = PDE(file->f_path.dentry->d_inode)->data; | ||
141 | char *string, *sp; | ||
142 | char *line, *ldelim, *varname, *svar, *tdelim; | ||
143 | |||
144 | if (count > 32768) /* Stupidity filter */ | ||
145 | return -EINVAL; | ||
146 | |||
147 | string = sp = vmalloc(count + 1); | ||
148 | if (!string) { | ||
149 | dprintk(1, | ||
150 | KERN_ERR | ||
151 | "%s: write_proc: can not allocate memory\n", | ||
152 | ZR_DEVNAME(zr)); | ||
153 | return -ENOMEM; | ||
154 | } | ||
155 | if (copy_from_user(string, buffer, count)) { | ||
156 | vfree (string); | ||
157 | return -EFAULT; | ||
158 | } | ||
159 | string[count] = 0; | ||
160 | dprintk(4, KERN_INFO "%s: write_proc: name=%s count=%zu zr=%p\n", | ||
161 | ZR_DEVNAME(zr), file->f_path.dentry->d_name.name, count, zr); | ||
162 | ldelim = " \t\n"; | ||
163 | tdelim = "="; | ||
164 | line = strpbrk(sp, ldelim); | ||
165 | while (line) { | ||
166 | *line = 0; | ||
167 | svar = strpbrk(sp, tdelim); | ||
168 | if (svar) { | ||
169 | *svar = 0; | ||
170 | varname = sp; | ||
171 | svar++; | ||
172 | setparam(zr, varname, svar); | ||
173 | } | ||
174 | sp = line + 1; | ||
175 | line = strpbrk(sp, ldelim); | ||
176 | } | ||
177 | vfree(string); | ||
178 | |||
179 | return count; | ||
180 | } | ||
181 | |||
182 | static const struct file_operations zoran_operations = { | ||
183 | .owner = THIS_MODULE, | ||
184 | .open = zoran_open, | ||
185 | .read = seq_read, | ||
186 | .write = zoran_write, | ||
187 | .llseek = seq_lseek, | ||
188 | .release = single_release, | ||
189 | }; | ||
190 | #endif | ||
191 | |||
192 | int | ||
193 | zoran_proc_init (struct zoran *zr) | ||
194 | { | ||
195 | #ifdef CONFIG_PROC_FS | ||
196 | char name[8]; | ||
197 | |||
198 | snprintf(name, 7, "zoran%d", zr->id); | ||
199 | zr->zoran_proc = proc_create_data(name, 0, NULL, &zoran_operations, zr); | ||
200 | if (zr->zoran_proc != NULL) { | ||
201 | dprintk(2, | ||
202 | KERN_INFO | ||
203 | "%s: procfs entry /proc/%s allocated. data=%p\n", | ||
204 | ZR_DEVNAME(zr), name, zr->zoran_proc->data); | ||
205 | } else { | ||
206 | dprintk(1, KERN_ERR "%s: Unable to initialise /proc/%s\n", | ||
207 | ZR_DEVNAME(zr), name); | ||
208 | return 1; | ||
209 | } | ||
210 | #endif | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | void | ||
215 | zoran_proc_cleanup (struct zoran *zr) | ||
216 | { | ||
217 | #ifdef CONFIG_PROC_FS | ||
218 | char name[8]; | ||
219 | |||
220 | snprintf(name, 7, "zoran%d", zr->id); | ||
221 | if (zr->zoran_proc) | ||
222 | remove_proc_entry(name, NULL); | ||
223 | zr->zoran_proc = NULL; | ||
224 | #endif | ||
225 | } | ||
diff --git a/drivers/media/video/zoran/zoran_procfs.h b/drivers/media/video/zoran/zoran_procfs.h deleted file mode 100644 index f2d5b1ba448f..000000000000 --- a/drivers/media/video/zoran/zoran_procfs.h +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
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 card-specific data and detection | ||
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 | #ifndef __ZORAN_PROCFS_H__ | ||
31 | #define __ZORAN_PROCFS_H__ | ||
32 | |||
33 | extern int zoran_proc_init(struct zoran *zr); | ||
34 | extern void zoran_proc_cleanup(struct zoran *zr); | ||
35 | |||
36 | #endif /* __ZORAN_PROCFS_H__ */ | ||
diff --git a/drivers/media/video/zoran/zr36016.c b/drivers/media/video/zoran/zr36016.c deleted file mode 100644 index b87ddba8608f..000000000000 --- a/drivers/media/video/zoran/zr36016.c +++ /dev/null | |||
@@ -1,524 +0,0 @@ | |||
1 | /* | ||
2 | * Zoran ZR36016 basic configuration functions | ||
3 | * | ||
4 | * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at> | ||
5 | * | ||
6 | * $Id: zr36016.c,v 1.1.2.14 2003/08/20 19:46:55 rbultje Exp $ | ||
7 | * | ||
8 | * ------------------------------------------------------------------------ | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | * | ||
24 | * ------------------------------------------------------------------------ | ||
25 | */ | ||
26 | |||
27 | #define ZR016_VERSION "v0.7" | ||
28 | |||
29 | #include <linux/module.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/slab.h> | ||
32 | #include <linux/delay.h> | ||
33 | |||
34 | #include <linux/types.h> | ||
35 | #include <linux/wait.h> | ||
36 | |||
37 | /* I/O commands, error codes */ | ||
38 | #include <asm/io.h> | ||
39 | |||
40 | /* v4l API */ | ||
41 | |||
42 | /* headerfile of this module */ | ||
43 | #include "zr36016.h" | ||
44 | |||
45 | /* codec io API */ | ||
46 | #include "videocodec.h" | ||
47 | |||
48 | /* it doesn't make sense to have more than 20 or so, | ||
49 | just to prevent some unwanted loops */ | ||
50 | #define MAX_CODECS 20 | ||
51 | |||
52 | /* amount of chips attached via this driver */ | ||
53 | static int zr36016_codecs; | ||
54 | |||
55 | /* debugging is available via module parameter */ | ||
56 | static int debug; | ||
57 | module_param(debug, int, 0); | ||
58 | MODULE_PARM_DESC(debug, "Debug level (0-4)"); | ||
59 | |||
60 | #define dprintk(num, format, args...) \ | ||
61 | do { \ | ||
62 | if (debug >= num) \ | ||
63 | printk(format, ##args); \ | ||
64 | } while (0) | ||
65 | |||
66 | /* ========================================================================= | ||
67 | Local hardware I/O functions: | ||
68 | |||
69 | read/write via codec layer (registers are located in the master device) | ||
70 | ========================================================================= */ | ||
71 | |||
72 | /* read and write functions */ | ||
73 | static u8 | ||
74 | zr36016_read (struct zr36016 *ptr, | ||
75 | u16 reg) | ||
76 | { | ||
77 | u8 value = 0; | ||
78 | |||
79 | // just in case something is wrong... | ||
80 | if (ptr->codec->master_data->readreg) | ||
81 | value = | ||
82 | (ptr->codec->master_data-> | ||
83 | readreg(ptr->codec, reg)) & 0xFF; | ||
84 | else | ||
85 | dprintk(1, | ||
86 | KERN_ERR "%s: invalid I/O setup, nothing read!\n", | ||
87 | ptr->name); | ||
88 | |||
89 | dprintk(4, "%s: reading from 0x%04x: %02x\n", ptr->name, reg, | ||
90 | value); | ||
91 | |||
92 | return value; | ||
93 | } | ||
94 | |||
95 | static void | ||
96 | zr36016_write (struct zr36016 *ptr, | ||
97 | u16 reg, | ||
98 | u8 value) | ||
99 | { | ||
100 | dprintk(4, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value, | ||
101 | reg); | ||
102 | |||
103 | // just in case something is wrong... | ||
104 | if (ptr->codec->master_data->writereg) { | ||
105 | ptr->codec->master_data->writereg(ptr->codec, reg, value); | ||
106 | } else | ||
107 | dprintk(1, | ||
108 | KERN_ERR | ||
109 | "%s: invalid I/O setup, nothing written!\n", | ||
110 | ptr->name); | ||
111 | } | ||
112 | |||
113 | /* indirect read and write functions */ | ||
114 | /* the 016 supports auto-addr-increment, but | ||
115 | * writing it all time cost not much and is safer... */ | ||
116 | static u8 | ||
117 | zr36016_readi (struct zr36016 *ptr, | ||
118 | u16 reg) | ||
119 | { | ||
120 | u8 value = 0; | ||
121 | |||
122 | // just in case something is wrong... | ||
123 | if ((ptr->codec->master_data->writereg) && | ||
124 | (ptr->codec->master_data->readreg)) { | ||
125 | ptr->codec->master_data->writereg(ptr->codec, ZR016_IADDR, reg & 0x0F); // ADDR | ||
126 | value = (ptr->codec->master_data->readreg(ptr->codec, ZR016_IDATA)) & 0xFF; // DATA | ||
127 | } else | ||
128 | dprintk(1, | ||
129 | KERN_ERR | ||
130 | "%s: invalid I/O setup, nothing read (i)!\n", | ||
131 | ptr->name); | ||
132 | |||
133 | dprintk(4, "%s: reading indirect from 0x%04x: %02x\n", ptr->name, | ||
134 | reg, value); | ||
135 | return value; | ||
136 | } | ||
137 | |||
138 | static void | ||
139 | zr36016_writei (struct zr36016 *ptr, | ||
140 | u16 reg, | ||
141 | u8 value) | ||
142 | { | ||
143 | dprintk(4, "%s: writing indirect 0x%02x to 0x%04x\n", ptr->name, | ||
144 | value, reg); | ||
145 | |||
146 | // just in case something is wrong... | ||
147 | if (ptr->codec->master_data->writereg) { | ||
148 | ptr->codec->master_data->writereg(ptr->codec, ZR016_IADDR, reg & 0x0F); // ADDR | ||
149 | ptr->codec->master_data->writereg(ptr->codec, ZR016_IDATA, value & 0x0FF); // DATA | ||
150 | } else | ||
151 | dprintk(1, | ||
152 | KERN_ERR | ||
153 | "%s: invalid I/O setup, nothing written (i)!\n", | ||
154 | ptr->name); | ||
155 | } | ||
156 | |||
157 | /* ========================================================================= | ||
158 | Local helper function: | ||
159 | |||
160 | version read | ||
161 | ========================================================================= */ | ||
162 | |||
163 | /* version kept in datastructure */ | ||
164 | static u8 | ||
165 | zr36016_read_version (struct zr36016 *ptr) | ||
166 | { | ||
167 | ptr->version = zr36016_read(ptr, 0) >> 4; | ||
168 | return ptr->version; | ||
169 | } | ||
170 | |||
171 | /* ========================================================================= | ||
172 | Local helper function: | ||
173 | |||
174 | basic test of "connectivity", writes/reads to/from PAX-Lo register | ||
175 | ========================================================================= */ | ||
176 | |||
177 | static int | ||
178 | zr36016_basic_test (struct zr36016 *ptr) | ||
179 | { | ||
180 | if (debug) { | ||
181 | int i; | ||
182 | zr36016_writei(ptr, ZR016I_PAX_LO, 0x55); | ||
183 | dprintk(1, KERN_INFO "%s: registers: ", ptr->name); | ||
184 | for (i = 0; i <= 0x0b; i++) | ||
185 | dprintk(1, "%02x ", zr36016_readi(ptr, i)); | ||
186 | dprintk(1, "\n"); | ||
187 | } | ||
188 | // for testing just write 0, then the default value to a register and read | ||
189 | // it back in both cases | ||
190 | zr36016_writei(ptr, ZR016I_PAX_LO, 0x00); | ||
191 | if (zr36016_readi(ptr, ZR016I_PAX_LO) != 0x0) { | ||
192 | dprintk(1, | ||
193 | KERN_ERR | ||
194 | "%s: attach failed, can't connect to vfe processor!\n", | ||
195 | ptr->name); | ||
196 | return -ENXIO; | ||
197 | } | ||
198 | zr36016_writei(ptr, ZR016I_PAX_LO, 0x0d0); | ||
199 | if (zr36016_readi(ptr, ZR016I_PAX_LO) != 0x0d0) { | ||
200 | dprintk(1, | ||
201 | KERN_ERR | ||
202 | "%s: attach failed, can't connect to vfe processor!\n", | ||
203 | ptr->name); | ||
204 | return -ENXIO; | ||
205 | } | ||
206 | // we allow version numbers from 0-3, should be enough, though | ||
207 | zr36016_read_version(ptr); | ||
208 | if (ptr->version & 0x0c) { | ||
209 | dprintk(1, | ||
210 | KERN_ERR | ||
211 | "%s: attach failed, suspicious version %d found...\n", | ||
212 | ptr->name, ptr->version); | ||
213 | return -ENXIO; | ||
214 | } | ||
215 | |||
216 | return 0; /* looks good! */ | ||
217 | } | ||
218 | |||
219 | /* ========================================================================= | ||
220 | Local helper function: | ||
221 | |||
222 | simple loop for pushing the init datasets - NO USE -- | ||
223 | ========================================================================= */ | ||
224 | |||
225 | #if 0 | ||
226 | static int zr36016_pushit (struct zr36016 *ptr, | ||
227 | u16 startreg, | ||
228 | u16 len, | ||
229 | const char *data) | ||
230 | { | ||
231 | int i=0; | ||
232 | |||
233 | dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", | ||
234 | ptr->name, startreg,len); | ||
235 | while (i<len) { | ||
236 | zr36016_writei(ptr, startreg++, data[i++]); | ||
237 | } | ||
238 | |||
239 | return i; | ||
240 | } | ||
241 | #endif | ||
242 | |||
243 | /* ========================================================================= | ||
244 | Basic datasets & init: | ||
245 | |||
246 | //TODO// | ||
247 | ========================================================================= */ | ||
248 | |||
249 | // needed offset values PAL NTSC SECAM | ||
250 | static const int zr016_xoff[] = { 20, 20, 20 }; | ||
251 | static const int zr016_yoff[] = { 8, 9, 7 }; | ||
252 | |||
253 | static void | ||
254 | zr36016_init (struct zr36016 *ptr) | ||
255 | { | ||
256 | // stop any processing | ||
257 | zr36016_write(ptr, ZR016_GOSTOP, 0); | ||
258 | |||
259 | // mode setup (yuv422 in and out, compression/expansuon due to mode) | ||
260 | zr36016_write(ptr, ZR016_MODE, | ||
261 | ZR016_YUV422 | ZR016_YUV422_YUV422 | | ||
262 | (ptr->mode == CODEC_DO_COMPRESSION ? | ||
263 | ZR016_COMPRESSION : ZR016_EXPANSION)); | ||
264 | |||
265 | // misc setup | ||
266 | zr36016_writei(ptr, ZR016I_SETUP1, | ||
267 | (ptr->xdec ? (ZR016_HRFL | ZR016_HORZ) : 0) | | ||
268 | (ptr->ydec ? ZR016_VERT : 0) | ZR016_CNTI); | ||
269 | zr36016_writei(ptr, ZR016I_SETUP2, ZR016_CCIR); | ||
270 | |||
271 | // Window setup | ||
272 | // (no extra offset for now, norm defines offset, default width height) | ||
273 | zr36016_writei(ptr, ZR016I_PAX_HI, ptr->width >> 8); | ||
274 | zr36016_writei(ptr, ZR016I_PAX_LO, ptr->width & 0xFF); | ||
275 | zr36016_writei(ptr, ZR016I_PAY_HI, ptr->height >> 8); | ||
276 | zr36016_writei(ptr, ZR016I_PAY_LO, ptr->height & 0xFF); | ||
277 | zr36016_writei(ptr, ZR016I_NAX_HI, ptr->xoff >> 8); | ||
278 | zr36016_writei(ptr, ZR016I_NAX_LO, ptr->xoff & 0xFF); | ||
279 | zr36016_writei(ptr, ZR016I_NAY_HI, ptr->yoff >> 8); | ||
280 | zr36016_writei(ptr, ZR016I_NAY_LO, ptr->yoff & 0xFF); | ||
281 | |||
282 | /* shall we continue now, please? */ | ||
283 | zr36016_write(ptr, ZR016_GOSTOP, 1); | ||
284 | } | ||
285 | |||
286 | /* ========================================================================= | ||
287 | CODEC API FUNCTIONS | ||
288 | |||
289 | this functions are accessed by the master via the API structure | ||
290 | ========================================================================= */ | ||
291 | |||
292 | /* set compression/expansion mode and launches codec - | ||
293 | this should be the last call from the master before starting processing */ | ||
294 | static int | ||
295 | zr36016_set_mode (struct videocodec *codec, | ||
296 | int mode) | ||
297 | { | ||
298 | struct zr36016 *ptr = (struct zr36016 *) codec->data; | ||
299 | |||
300 | dprintk(2, "%s: set_mode %d call\n", ptr->name, mode); | ||
301 | |||
302 | if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION)) | ||
303 | return -EINVAL; | ||
304 | |||
305 | ptr->mode = mode; | ||
306 | zr36016_init(ptr); | ||
307 | |||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | /* set picture size */ | ||
312 | static int | ||
313 | zr36016_set_video (struct videocodec *codec, | ||
314 | struct tvnorm *norm, | ||
315 | struct vfe_settings *cap, | ||
316 | struct vfe_polarity *pol) | ||
317 | { | ||
318 | struct zr36016 *ptr = (struct zr36016 *) codec->data; | ||
319 | |||
320 | dprintk(2, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) call\n", | ||
321 | ptr->name, norm->HStart, norm->VStart, | ||
322 | cap->x, cap->y, cap->width, cap->height, | ||
323 | cap->decimation); | ||
324 | |||
325 | /* if () return -EINVAL; | ||
326 | * trust the master driver that it knows what it does - so | ||
327 | * we allow invalid startx/y for now ... */ | ||
328 | ptr->width = cap->width; | ||
329 | ptr->height = cap->height; | ||
330 | /* (Ronald) This is ugly. zoran_device.c, line 387 | ||
331 | * already mentions what happens if HStart is even | ||
332 | * (blue faces, etc., cr/cb inversed). There's probably | ||
333 | * some good reason why HStart is 0 instead of 1, so I'm | ||
334 | * leaving it to this for now, but really... This can be | ||
335 | * done a lot simpler */ | ||
336 | ptr->xoff = (norm->HStart ? norm->HStart : 1) + cap->x; | ||
337 | /* Something to note here (I don't understand it), setting | ||
338 | * VStart too high will cause the codec to 'not work'. I | ||
339 | * really don't get it. values of 16 (VStart) already break | ||
340 | * it here. Just '0' seems to work. More testing needed! */ | ||
341 | ptr->yoff = norm->VStart + cap->y; | ||
342 | /* (Ronald) dzjeeh, can't this thing do hor_decimation = 4? */ | ||
343 | ptr->xdec = ((cap->decimation & 0xff) == 1) ? 0 : 1; | ||
344 | ptr->ydec = (((cap->decimation >> 8) & 0xff) == 1) ? 0 : 1; | ||
345 | |||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | /* additional control functions */ | ||
350 | static int | ||
351 | zr36016_control (struct videocodec *codec, | ||
352 | int type, | ||
353 | int size, | ||
354 | void *data) | ||
355 | { | ||
356 | struct zr36016 *ptr = (struct zr36016 *) codec->data; | ||
357 | int *ival = (int *) data; | ||
358 | |||
359 | dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type, | ||
360 | size); | ||
361 | |||
362 | switch (type) { | ||
363 | case CODEC_G_STATUS: /* get last status - we don't know it ... */ | ||
364 | if (size != sizeof(int)) | ||
365 | return -EFAULT; | ||
366 | *ival = 0; | ||
367 | break; | ||
368 | |||
369 | case CODEC_G_CODEC_MODE: | ||
370 | if (size != sizeof(int)) | ||
371 | return -EFAULT; | ||
372 | *ival = 0; | ||
373 | break; | ||
374 | |||
375 | case CODEC_S_CODEC_MODE: | ||
376 | if (size != sizeof(int)) | ||
377 | return -EFAULT; | ||
378 | if (*ival != 0) | ||
379 | return -EINVAL; | ||
380 | /* not needed, do nothing */ | ||
381 | return 0; | ||
382 | |||
383 | case CODEC_G_VFE: | ||
384 | case CODEC_S_VFE: | ||
385 | return 0; | ||
386 | |||
387 | case CODEC_S_MMAP: | ||
388 | /* not available, give an error */ | ||
389 | return -ENXIO; | ||
390 | |||
391 | default: | ||
392 | return -EINVAL; | ||
393 | } | ||
394 | |||
395 | return size; | ||
396 | } | ||
397 | |||
398 | /* ========================================================================= | ||
399 | Exit and unregister function: | ||
400 | |||
401 | Deinitializes Zoran's JPEG processor | ||
402 | ========================================================================= */ | ||
403 | |||
404 | static int | ||
405 | zr36016_unset (struct videocodec *codec) | ||
406 | { | ||
407 | struct zr36016 *ptr = codec->data; | ||
408 | |||
409 | if (ptr) { | ||
410 | /* do wee need some codec deinit here, too ???? */ | ||
411 | |||
412 | dprintk(1, "%s: finished codec #%d\n", ptr->name, | ||
413 | ptr->num); | ||
414 | kfree(ptr); | ||
415 | codec->data = NULL; | ||
416 | |||
417 | zr36016_codecs--; | ||
418 | return 0; | ||
419 | } | ||
420 | |||
421 | return -EFAULT; | ||
422 | } | ||
423 | |||
424 | /* ========================================================================= | ||
425 | Setup and registry function: | ||
426 | |||
427 | Initializes Zoran's JPEG processor | ||
428 | |||
429 | Also sets pixel size, average code size, mode (compr./decompr.) | ||
430 | (the given size is determined by the processor with the video interface) | ||
431 | ========================================================================= */ | ||
432 | |||
433 | static int | ||
434 | zr36016_setup (struct videocodec *codec) | ||
435 | { | ||
436 | struct zr36016 *ptr; | ||
437 | int res; | ||
438 | |||
439 | dprintk(2, "zr36016: initializing VFE subsystem #%d.\n", | ||
440 | zr36016_codecs); | ||
441 | |||
442 | if (zr36016_codecs == MAX_CODECS) { | ||
443 | dprintk(1, | ||
444 | KERN_ERR "zr36016: Can't attach more codecs!\n"); | ||
445 | return -ENOSPC; | ||
446 | } | ||
447 | //mem structure init | ||
448 | codec->data = ptr = kzalloc(sizeof(struct zr36016), GFP_KERNEL); | ||
449 | if (NULL == ptr) { | ||
450 | dprintk(1, KERN_ERR "zr36016: Can't get enough memory!\n"); | ||
451 | return -ENOMEM; | ||
452 | } | ||
453 | |||
454 | snprintf(ptr->name, sizeof(ptr->name), "zr36016[%d]", | ||
455 | zr36016_codecs); | ||
456 | ptr->num = zr36016_codecs++; | ||
457 | ptr->codec = codec; | ||
458 | |||
459 | //testing | ||
460 | res = zr36016_basic_test(ptr); | ||
461 | if (res < 0) { | ||
462 | zr36016_unset(codec); | ||
463 | return res; | ||
464 | } | ||
465 | //final setup | ||
466 | ptr->mode = CODEC_DO_COMPRESSION; | ||
467 | ptr->width = 768; | ||
468 | ptr->height = 288; | ||
469 | ptr->xdec = 1; | ||
470 | ptr->ydec = 0; | ||
471 | zr36016_init(ptr); | ||
472 | |||
473 | dprintk(1, KERN_INFO "%s: codec v%d attached and running\n", | ||
474 | ptr->name, ptr->version); | ||
475 | |||
476 | return 0; | ||
477 | } | ||
478 | |||
479 | static const struct videocodec zr36016_codec = { | ||
480 | .owner = THIS_MODULE, | ||
481 | .name = "zr36016", | ||
482 | .magic = 0L, // magic not used | ||
483 | .flags = | ||
484 | CODEC_FLAG_HARDWARE | CODEC_FLAG_VFE | CODEC_FLAG_ENCODER | | ||
485 | CODEC_FLAG_DECODER, | ||
486 | .type = CODEC_TYPE_ZR36016, | ||
487 | .setup = zr36016_setup, // functionality | ||
488 | .unset = zr36016_unset, | ||
489 | .set_mode = zr36016_set_mode, | ||
490 | .set_video = zr36016_set_video, | ||
491 | .control = zr36016_control, | ||
492 | // others are not used | ||
493 | }; | ||
494 | |||
495 | /* ========================================================================= | ||
496 | HOOK IN DRIVER AS KERNEL MODULE | ||
497 | ========================================================================= */ | ||
498 | |||
499 | static int __init | ||
500 | zr36016_init_module (void) | ||
501 | { | ||
502 | //dprintk(1, "ZR36016 driver %s\n",ZR016_VERSION); | ||
503 | zr36016_codecs = 0; | ||
504 | return videocodec_register(&zr36016_codec); | ||
505 | } | ||
506 | |||
507 | static void __exit | ||
508 | zr36016_cleanup_module (void) | ||
509 | { | ||
510 | if (zr36016_codecs) { | ||
511 | dprintk(1, | ||
512 | "zr36016: something's wrong - %d codecs left somehow.\n", | ||
513 | zr36016_codecs); | ||
514 | } | ||
515 | videocodec_unregister(&zr36016_codec); | ||
516 | } | ||
517 | |||
518 | module_init(zr36016_init_module); | ||
519 | module_exit(zr36016_cleanup_module); | ||
520 | |||
521 | MODULE_AUTHOR("Wolfgang Scherr <scherr@net4you.at>"); | ||
522 | MODULE_DESCRIPTION("Driver module for ZR36016 video frontends " | ||
523 | ZR016_VERSION); | ||
524 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/zoran/zr36016.h b/drivers/media/video/zoran/zr36016.h deleted file mode 100644 index 8c79229f69d1..000000000000 --- a/drivers/media/video/zoran/zr36016.h +++ /dev/null | |||
@@ -1,111 +0,0 @@ | |||
1 | /* | ||
2 | * Zoran ZR36016 basic configuration functions - header file | ||
3 | * | ||
4 | * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at> | ||
5 | * | ||
6 | * $Id: zr36016.h,v 1.1.2.3 2003/01/14 21:18:07 rbultje Exp $ | ||
7 | * | ||
8 | * ------------------------------------------------------------------------ | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | * | ||
24 | * ------------------------------------------------------------------------ | ||
25 | */ | ||
26 | |||
27 | #ifndef ZR36016_H | ||
28 | #define ZR36016_H | ||
29 | |||
30 | /* data stored for each zoran jpeg codec chip */ | ||
31 | struct zr36016 { | ||
32 | char name[32]; | ||
33 | int num; | ||
34 | /* io datastructure */ | ||
35 | struct videocodec *codec; | ||
36 | // coder status | ||
37 | __u8 version; | ||
38 | // actual coder setup | ||
39 | int mode; | ||
40 | |||
41 | __u16 xoff; | ||
42 | __u16 yoff; | ||
43 | __u16 width; | ||
44 | __u16 height; | ||
45 | __u16 xdec; | ||
46 | __u16 ydec; | ||
47 | }; | ||
48 | |||
49 | /* direct register addresses */ | ||
50 | #define ZR016_GOSTOP 0x00 | ||
51 | #define ZR016_MODE 0x01 | ||
52 | #define ZR016_IADDR 0x02 | ||
53 | #define ZR016_IDATA 0x03 | ||
54 | |||
55 | /* indirect register addresses */ | ||
56 | #define ZR016I_SETUP1 0x00 | ||
57 | #define ZR016I_SETUP2 0x01 | ||
58 | #define ZR016I_NAX_LO 0x02 | ||
59 | #define ZR016I_NAX_HI 0x03 | ||
60 | #define ZR016I_PAX_LO 0x04 | ||
61 | #define ZR016I_PAX_HI 0x05 | ||
62 | #define ZR016I_NAY_LO 0x06 | ||
63 | #define ZR016I_NAY_HI 0x07 | ||
64 | #define ZR016I_PAY_LO 0x08 | ||
65 | #define ZR016I_PAY_HI 0x09 | ||
66 | #define ZR016I_NOL_LO 0x0a | ||
67 | #define ZR016I_NOL_HI 0x0b | ||
68 | |||
69 | /* possible values for mode register */ | ||
70 | #define ZR016_RGB444_YUV444 0x00 | ||
71 | #define ZR016_RGB444_YUV422 0x01 | ||
72 | #define ZR016_RGB444_YUV411 0x02 | ||
73 | #define ZR016_RGB444_Y400 0x03 | ||
74 | #define ZR016_RGB444_RGB444 0x04 | ||
75 | #define ZR016_YUV444_YUV444 0x08 | ||
76 | #define ZR016_YUV444_YUV422 0x09 | ||
77 | #define ZR016_YUV444_YUV411 0x0a | ||
78 | #define ZR016_YUV444_Y400 0x0b | ||
79 | #define ZR016_YUV444_RGB444 0x0c | ||
80 | #define ZR016_YUV422_YUV422 0x11 | ||
81 | #define ZR016_YUV422_YUV411 0x12 | ||
82 | #define ZR016_YUV422_Y400 0x13 | ||
83 | #define ZR016_YUV411_YUV411 0x16 | ||
84 | #define ZR016_YUV411_Y400 0x17 | ||
85 | #define ZR016_4444_4444 0x19 | ||
86 | #define ZR016_100_100 0x1b | ||
87 | |||
88 | #define ZR016_RGB444 0x00 | ||
89 | #define ZR016_YUV444 0x20 | ||
90 | #define ZR016_YUV422 0x40 | ||
91 | |||
92 | #define ZR016_COMPRESSION 0x80 | ||
93 | #define ZR016_EXPANSION 0x80 | ||
94 | |||
95 | /* possible values for setup 1 register */ | ||
96 | #define ZR016_CKRT 0x80 | ||
97 | #define ZR016_VERT 0x40 | ||
98 | #define ZR016_HORZ 0x20 | ||
99 | #define ZR016_HRFL 0x10 | ||
100 | #define ZR016_DSFL 0x08 | ||
101 | #define ZR016_SBFL 0x04 | ||
102 | #define ZR016_RSTR 0x02 | ||
103 | #define ZR016_CNTI 0x01 | ||
104 | |||
105 | /* possible values for setup 2 register */ | ||
106 | #define ZR016_SYEN 0x40 | ||
107 | #define ZR016_CCIR 0x04 | ||
108 | #define ZR016_SIGN 0x02 | ||
109 | #define ZR016_YMCS 0x01 | ||
110 | |||
111 | #endif /*fndef ZR36016_H */ | ||
diff --git a/drivers/media/video/zoran/zr36050.c b/drivers/media/video/zoran/zr36050.c deleted file mode 100644 index e1985609af4b..000000000000 --- a/drivers/media/video/zoran/zr36050.c +++ /dev/null | |||
@@ -1,900 +0,0 @@ | |||
1 | /* | ||
2 | * Zoran ZR36050 basic configuration functions | ||
3 | * | ||
4 | * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at> | ||
5 | * | ||
6 | * $Id: zr36050.c,v 1.1.2.11 2003/08/03 14:54:53 rbultje Exp $ | ||
7 | * | ||
8 | * ------------------------------------------------------------------------ | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | * | ||
24 | * ------------------------------------------------------------------------ | ||
25 | */ | ||
26 | |||
27 | #define ZR050_VERSION "v0.7.1" | ||
28 | |||
29 | #include <linux/module.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/slab.h> | ||
32 | #include <linux/delay.h> | ||
33 | |||
34 | #include <linux/types.h> | ||
35 | #include <linux/wait.h> | ||
36 | |||
37 | /* I/O commands, error codes */ | ||
38 | #include <asm/io.h> | ||
39 | |||
40 | /* headerfile of this module */ | ||
41 | #include "zr36050.h" | ||
42 | |||
43 | /* codec io API */ | ||
44 | #include "videocodec.h" | ||
45 | |||
46 | /* it doesn't make sense to have more than 20 or so, | ||
47 | just to prevent some unwanted loops */ | ||
48 | #define MAX_CODECS 20 | ||
49 | |||
50 | /* amount of chips attached via this driver */ | ||
51 | static int zr36050_codecs; | ||
52 | |||
53 | /* debugging is available via module parameter */ | ||
54 | static int debug; | ||
55 | module_param(debug, int, 0); | ||
56 | MODULE_PARM_DESC(debug, "Debug level (0-4)"); | ||
57 | |||
58 | #define dprintk(num, format, args...) \ | ||
59 | do { \ | ||
60 | if (debug >= num) \ | ||
61 | printk(format, ##args); \ | ||
62 | } while (0) | ||
63 | |||
64 | /* ========================================================================= | ||
65 | Local hardware I/O functions: | ||
66 | |||
67 | read/write via codec layer (registers are located in the master device) | ||
68 | ========================================================================= */ | ||
69 | |||
70 | /* read and write functions */ | ||
71 | static u8 | ||
72 | zr36050_read (struct zr36050 *ptr, | ||
73 | u16 reg) | ||
74 | { | ||
75 | u8 value = 0; | ||
76 | |||
77 | // just in case something is wrong... | ||
78 | if (ptr->codec->master_data->readreg) | ||
79 | value = (ptr->codec->master_data->readreg(ptr->codec, | ||
80 | reg)) & 0xFF; | ||
81 | else | ||
82 | dprintk(1, | ||
83 | KERN_ERR "%s: invalid I/O setup, nothing read!\n", | ||
84 | ptr->name); | ||
85 | |||
86 | dprintk(4, "%s: reading from 0x%04x: %02x\n", ptr->name, reg, | ||
87 | value); | ||
88 | |||
89 | return value; | ||
90 | } | ||
91 | |||
92 | static void | ||
93 | zr36050_write (struct zr36050 *ptr, | ||
94 | u16 reg, | ||
95 | u8 value) | ||
96 | { | ||
97 | dprintk(4, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value, | ||
98 | reg); | ||
99 | |||
100 | // just in case something is wrong... | ||
101 | if (ptr->codec->master_data->writereg) | ||
102 | ptr->codec->master_data->writereg(ptr->codec, reg, value); | ||
103 | else | ||
104 | dprintk(1, | ||
105 | KERN_ERR | ||
106 | "%s: invalid I/O setup, nothing written!\n", | ||
107 | ptr->name); | ||
108 | } | ||
109 | |||
110 | /* ========================================================================= | ||
111 | Local helper function: | ||
112 | |||
113 | status read | ||
114 | ========================================================================= */ | ||
115 | |||
116 | /* status is kept in datastructure */ | ||
117 | static u8 | ||
118 | zr36050_read_status1 (struct zr36050 *ptr) | ||
119 | { | ||
120 | ptr->status1 = zr36050_read(ptr, ZR050_STATUS_1); | ||
121 | |||
122 | zr36050_read(ptr, 0); | ||
123 | return ptr->status1; | ||
124 | } | ||
125 | |||
126 | /* ========================================================================= | ||
127 | Local helper function: | ||
128 | |||
129 | scale factor read | ||
130 | ========================================================================= */ | ||
131 | |||
132 | /* scale factor is kept in datastructure */ | ||
133 | static u16 | ||
134 | zr36050_read_scalefactor (struct zr36050 *ptr) | ||
135 | { | ||
136 | ptr->scalefact = (zr36050_read(ptr, ZR050_SF_HI) << 8) | | ||
137 | (zr36050_read(ptr, ZR050_SF_LO) & 0xFF); | ||
138 | |||
139 | /* leave 0 selected for an eventually GO from master */ | ||
140 | zr36050_read(ptr, 0); | ||
141 | return ptr->scalefact; | ||
142 | } | ||
143 | |||
144 | /* ========================================================================= | ||
145 | Local helper function: | ||
146 | |||
147 | wait if codec is ready to proceed (end of processing) or time is over | ||
148 | ========================================================================= */ | ||
149 | |||
150 | static void | ||
151 | zr36050_wait_end (struct zr36050 *ptr) | ||
152 | { | ||
153 | int i = 0; | ||
154 | |||
155 | while (!(zr36050_read_status1(ptr) & 0x4)) { | ||
156 | udelay(1); | ||
157 | if (i++ > 200000) { // 200ms, there is for sure something wrong!!! | ||
158 | dprintk(1, | ||
159 | "%s: timeout at wait_end (last status: 0x%02x)\n", | ||
160 | ptr->name, ptr->status1); | ||
161 | break; | ||
162 | } | ||
163 | } | ||
164 | } | ||
165 | |||
166 | /* ========================================================================= | ||
167 | Local helper function: | ||
168 | |||
169 | basic test of "connectivity", writes/reads to/from memory the SOF marker | ||
170 | ========================================================================= */ | ||
171 | |||
172 | static int | ||
173 | zr36050_basic_test (struct zr36050 *ptr) | ||
174 | { | ||
175 | zr36050_write(ptr, ZR050_SOF_IDX, 0x00); | ||
176 | zr36050_write(ptr, ZR050_SOF_IDX + 1, 0x00); | ||
177 | if ((zr36050_read(ptr, ZR050_SOF_IDX) | | ||
178 | zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0x0000) { | ||
179 | dprintk(1, | ||
180 | KERN_ERR | ||
181 | "%s: attach failed, can't connect to jpeg processor!\n", | ||
182 | ptr->name); | ||
183 | return -ENXIO; | ||
184 | } | ||
185 | zr36050_write(ptr, ZR050_SOF_IDX, 0xff); | ||
186 | zr36050_write(ptr, ZR050_SOF_IDX + 1, 0xc0); | ||
187 | if (((zr36050_read(ptr, ZR050_SOF_IDX) << 8) | | ||
188 | zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0xffc0) { | ||
189 | dprintk(1, | ||
190 | KERN_ERR | ||
191 | "%s: attach failed, can't connect to jpeg processor!\n", | ||
192 | ptr->name); | ||
193 | return -ENXIO; | ||
194 | } | ||
195 | |||
196 | zr36050_wait_end(ptr); | ||
197 | if ((ptr->status1 & 0x4) == 0) { | ||
198 | dprintk(1, | ||
199 | KERN_ERR | ||
200 | "%s: attach failed, jpeg processor failed (end flag)!\n", | ||
201 | ptr->name); | ||
202 | return -EBUSY; | ||
203 | } | ||
204 | |||
205 | return 0; /* looks good! */ | ||
206 | } | ||
207 | |||
208 | /* ========================================================================= | ||
209 | Local helper function: | ||
210 | |||
211 | simple loop for pushing the init datasets | ||
212 | ========================================================================= */ | ||
213 | |||
214 | static int | ||
215 | zr36050_pushit (struct zr36050 *ptr, | ||
216 | u16 startreg, | ||
217 | u16 len, | ||
218 | const char *data) | ||
219 | { | ||
220 | int i = 0; | ||
221 | |||
222 | dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name, | ||
223 | startreg, len); | ||
224 | while (i < len) { | ||
225 | zr36050_write(ptr, startreg++, data[i++]); | ||
226 | } | ||
227 | |||
228 | return i; | ||
229 | } | ||
230 | |||
231 | /* ========================================================================= | ||
232 | Basic datasets: | ||
233 | |||
234 | jpeg baseline setup data (you find it on lots places in internet, or just | ||
235 | extract it from any regular .jpg image...) | ||
236 | |||
237 | Could be variable, but until it's not needed it they are just fixed to save | ||
238 | memory. Otherwise expand zr36050 structure with arrays, push the values to | ||
239 | it and initialize from there, as e.g. the linux zr36057/60 driver does it. | ||
240 | ========================================================================= */ | ||
241 | |||
242 | static const char zr36050_dqt[0x86] = { | ||
243 | 0xff, 0xdb, //Marker: DQT | ||
244 | 0x00, 0x84, //Length: 2*65+2 | ||
245 | 0x00, //Pq,Tq first table | ||
246 | 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, | ||
247 | 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, | ||
248 | 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, | ||
249 | 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, | ||
250 | 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44, | ||
251 | 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57, | ||
252 | 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, | ||
253 | 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63, | ||
254 | 0x01, //Pq,Tq second table | ||
255 | 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, | ||
256 | 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, | ||
257 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
258 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
259 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
260 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
261 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
262 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 | ||
263 | }; | ||
264 | |||
265 | static const char zr36050_dht[0x1a4] = { | ||
266 | 0xff, 0xc4, //Marker: DHT | ||
267 | 0x01, 0xa2, //Length: 2*AC, 2*DC | ||
268 | 0x00, //DC first table | ||
269 | 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, | ||
270 | 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | ||
271 | 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, | ||
272 | 0x01, //DC second table | ||
273 | 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, | ||
274 | 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | ||
275 | 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, | ||
276 | 0x10, //AC first table | ||
277 | 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, | ||
278 | 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, | ||
279 | 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, | ||
280 | 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, | ||
281 | 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, | ||
282 | 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, | ||
283 | 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, | ||
284 | 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, | ||
285 | 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, | ||
286 | 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, | ||
287 | 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, | ||
288 | 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, | ||
289 | 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, | ||
290 | 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, | ||
291 | 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, | ||
292 | 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, | ||
293 | 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, | ||
294 | 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, | ||
295 | 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, | ||
296 | 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, | ||
297 | 0xF8, 0xF9, 0xFA, | ||
298 | 0x11, //AC second table | ||
299 | 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, | ||
300 | 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, | ||
301 | 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, | ||
302 | 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, | ||
303 | 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, | ||
304 | 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, | ||
305 | 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, | ||
306 | 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, | ||
307 | 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, | ||
308 | 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, | ||
309 | 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, | ||
310 | 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, | ||
311 | 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, | ||
312 | 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, | ||
313 | 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, | ||
314 | 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, | ||
315 | 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, | ||
316 | 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, | ||
317 | 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, | ||
318 | 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, | ||
319 | 0xF9, 0xFA | ||
320 | }; | ||
321 | |||
322 | /* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */ | ||
323 | #define NO_OF_COMPONENTS 0x3 //Y,U,V | ||
324 | #define BASELINE_PRECISION 0x8 //MCU size (?) | ||
325 | static const char zr36050_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's QT | ||
326 | static const char zr36050_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's DC | ||
327 | static const char zr36050_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's AC | ||
328 | |||
329 | /* horizontal 422 decimation setup (maybe we support 411 or so later, too) */ | ||
330 | static const char zr36050_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 }; | ||
331 | static const char zr36050_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 }; | ||
332 | |||
333 | /* ========================================================================= | ||
334 | Local helper functions: | ||
335 | |||
336 | calculation and setup of parameter-dependent JPEG baseline segments | ||
337 | (needed for compression only) | ||
338 | ========================================================================= */ | ||
339 | |||
340 | /* ------------------------------------------------------------------------- */ | ||
341 | |||
342 | /* SOF (start of frame) segment depends on width, height and sampling ratio | ||
343 | of each color component */ | ||
344 | |||
345 | static int | ||
346 | zr36050_set_sof (struct zr36050 *ptr) | ||
347 | { | ||
348 | char sof_data[34]; // max. size of register set | ||
349 | int i; | ||
350 | |||
351 | dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name, | ||
352 | ptr->width, ptr->height, NO_OF_COMPONENTS); | ||
353 | sof_data[0] = 0xff; | ||
354 | sof_data[1] = 0xc0; | ||
355 | sof_data[2] = 0x00; | ||
356 | sof_data[3] = (3 * NO_OF_COMPONENTS) + 8; | ||
357 | sof_data[4] = BASELINE_PRECISION; // only '8' possible with zr36050 | ||
358 | sof_data[5] = (ptr->height) >> 8; | ||
359 | sof_data[6] = (ptr->height) & 0xff; | ||
360 | sof_data[7] = (ptr->width) >> 8; | ||
361 | sof_data[8] = (ptr->width) & 0xff; | ||
362 | sof_data[9] = NO_OF_COMPONENTS; | ||
363 | for (i = 0; i < NO_OF_COMPONENTS; i++) { | ||
364 | sof_data[10 + (i * 3)] = i; // index identifier | ||
365 | sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) | (ptr->v_samp_ratio[i]); // sampling ratios | ||
366 | sof_data[12 + (i * 3)] = zr36050_tq[i]; // Q table selection | ||
367 | } | ||
368 | return zr36050_pushit(ptr, ZR050_SOF_IDX, | ||
369 | (3 * NO_OF_COMPONENTS) + 10, sof_data); | ||
370 | } | ||
371 | |||
372 | /* ------------------------------------------------------------------------- */ | ||
373 | |||
374 | /* SOS (start of scan) segment depends on the used scan components | ||
375 | of each color component */ | ||
376 | |||
377 | static int | ||
378 | zr36050_set_sos (struct zr36050 *ptr) | ||
379 | { | ||
380 | char sos_data[16]; // max. size of register set | ||
381 | int i; | ||
382 | |||
383 | dprintk(3, "%s: write SOS\n", ptr->name); | ||
384 | sos_data[0] = 0xff; | ||
385 | sos_data[1] = 0xda; | ||
386 | sos_data[2] = 0x00; | ||
387 | sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3; | ||
388 | sos_data[4] = NO_OF_COMPONENTS; | ||
389 | for (i = 0; i < NO_OF_COMPONENTS; i++) { | ||
390 | sos_data[5 + (i * 2)] = i; // index | ||
391 | sos_data[6 + (i * 2)] = (zr36050_td[i] << 4) | zr36050_ta[i]; // AC/DC tbl.sel. | ||
392 | } | ||
393 | sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00; // scan start | ||
394 | sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3F; | ||
395 | sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00; | ||
396 | return zr36050_pushit(ptr, ZR050_SOS1_IDX, | ||
397 | 4 + 1 + (2 * NO_OF_COMPONENTS) + 3, | ||
398 | sos_data); | ||
399 | } | ||
400 | |||
401 | /* ------------------------------------------------------------------------- */ | ||
402 | |||
403 | /* DRI (define restart interval) */ | ||
404 | |||
405 | static int | ||
406 | zr36050_set_dri (struct zr36050 *ptr) | ||
407 | { | ||
408 | char dri_data[6]; // max. size of register set | ||
409 | |||
410 | dprintk(3, "%s: write DRI\n", ptr->name); | ||
411 | dri_data[0] = 0xff; | ||
412 | dri_data[1] = 0xdd; | ||
413 | dri_data[2] = 0x00; | ||
414 | dri_data[3] = 0x04; | ||
415 | dri_data[4] = ptr->dri >> 8; | ||
416 | dri_data[5] = ptr->dri & 0xff; | ||
417 | return zr36050_pushit(ptr, ZR050_DRI_IDX, 6, dri_data); | ||
418 | } | ||
419 | |||
420 | /* ========================================================================= | ||
421 | Setup function: | ||
422 | |||
423 | Setup compression/decompression of Zoran's JPEG processor | ||
424 | ( see also zoran 36050 manual ) | ||
425 | |||
426 | ... sorry for the spaghetti code ... | ||
427 | ========================================================================= */ | ||
428 | static void | ||
429 | zr36050_init (struct zr36050 *ptr) | ||
430 | { | ||
431 | int sum = 0; | ||
432 | long bitcnt, tmp; | ||
433 | |||
434 | if (ptr->mode == CODEC_DO_COMPRESSION) { | ||
435 | dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name); | ||
436 | |||
437 | /* 050 communicates with 057 in master mode */ | ||
438 | zr36050_write(ptr, ZR050_HARDWARE, ZR050_HW_MSTR); | ||
439 | |||
440 | /* encoding table preload for compression */ | ||
441 | zr36050_write(ptr, ZR050_MODE, | ||
442 | ZR050_MO_COMP | ZR050_MO_TLM); | ||
443 | zr36050_write(ptr, ZR050_OPTIONS, 0); | ||
444 | |||
445 | /* disable all IRQs */ | ||
446 | zr36050_write(ptr, ZR050_INT_REQ_0, 0); | ||
447 | zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1 | ||
448 | |||
449 | /* volume control settings */ | ||
450 | /*zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol);*/ | ||
451 | zr36050_write(ptr, ZR050_SF_HI, ptr->scalefact >> 8); | ||
452 | zr36050_write(ptr, ZR050_SF_LO, ptr->scalefact & 0xff); | ||
453 | |||
454 | zr36050_write(ptr, ZR050_AF_HI, 0xff); | ||
455 | zr36050_write(ptr, ZR050_AF_M, 0xff); | ||
456 | zr36050_write(ptr, ZR050_AF_LO, 0xff); | ||
457 | |||
458 | /* setup the variable jpeg tables */ | ||
459 | sum += zr36050_set_sof(ptr); | ||
460 | sum += zr36050_set_sos(ptr); | ||
461 | sum += zr36050_set_dri(ptr); | ||
462 | |||
463 | /* setup the fixed jpeg tables - maybe variable, though - | ||
464 | * (see table init section above) */ | ||
465 | dprintk(3, "%s: write DQT, DHT, APP\n", ptr->name); | ||
466 | sum += zr36050_pushit(ptr, ZR050_DQT_IDX, | ||
467 | sizeof(zr36050_dqt), zr36050_dqt); | ||
468 | sum += zr36050_pushit(ptr, ZR050_DHT_IDX, | ||
469 | sizeof(zr36050_dht), zr36050_dht); | ||
470 | zr36050_write(ptr, ZR050_APP_IDX, 0xff); | ||
471 | zr36050_write(ptr, ZR050_APP_IDX + 1, 0xe0 + ptr->app.appn); | ||
472 | zr36050_write(ptr, ZR050_APP_IDX + 2, 0x00); | ||
473 | zr36050_write(ptr, ZR050_APP_IDX + 3, ptr->app.len + 2); | ||
474 | sum += zr36050_pushit(ptr, ZR050_APP_IDX + 4, 60, | ||
475 | ptr->app.data) + 4; | ||
476 | zr36050_write(ptr, ZR050_COM_IDX, 0xff); | ||
477 | zr36050_write(ptr, ZR050_COM_IDX + 1, 0xfe); | ||
478 | zr36050_write(ptr, ZR050_COM_IDX + 2, 0x00); | ||
479 | zr36050_write(ptr, ZR050_COM_IDX + 3, ptr->com.len + 2); | ||
480 | sum += zr36050_pushit(ptr, ZR050_COM_IDX + 4, 60, | ||
481 | ptr->com.data) + 4; | ||
482 | |||
483 | /* do the internal huffman table preload */ | ||
484 | zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI); | ||
485 | |||
486 | zr36050_write(ptr, ZR050_GO, 1); // launch codec | ||
487 | zr36050_wait_end(ptr); | ||
488 | dprintk(2, "%s: Status after table preload: 0x%02x\n", | ||
489 | ptr->name, ptr->status1); | ||
490 | |||
491 | if ((ptr->status1 & 0x4) == 0) { | ||
492 | dprintk(1, KERN_ERR "%s: init aborted!\n", | ||
493 | ptr->name); | ||
494 | return; // something is wrong, its timed out!!!! | ||
495 | } | ||
496 | |||
497 | /* setup misc. data for compression (target code sizes) */ | ||
498 | |||
499 | /* size of compressed code to reach without header data */ | ||
500 | sum = ptr->real_code_vol - sum; | ||
501 | bitcnt = sum << 3; /* need the size in bits */ | ||
502 | |||
503 | tmp = bitcnt >> 16; | ||
504 | dprintk(3, | ||
505 | "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n", | ||
506 | ptr->name, sum, ptr->real_code_vol, bitcnt, tmp); | ||
507 | zr36050_write(ptr, ZR050_TCV_NET_HI, tmp >> 8); | ||
508 | zr36050_write(ptr, ZR050_TCV_NET_MH, tmp & 0xff); | ||
509 | tmp = bitcnt & 0xffff; | ||
510 | zr36050_write(ptr, ZR050_TCV_NET_ML, tmp >> 8); | ||
511 | zr36050_write(ptr, ZR050_TCV_NET_LO, tmp & 0xff); | ||
512 | |||
513 | bitcnt -= bitcnt >> 7; // bits without stuffing | ||
514 | bitcnt -= ((bitcnt * 5) >> 6); // bits without eob | ||
515 | |||
516 | tmp = bitcnt >> 16; | ||
517 | dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n", | ||
518 | ptr->name, bitcnt, tmp); | ||
519 | zr36050_write(ptr, ZR050_TCV_DATA_HI, tmp >> 8); | ||
520 | zr36050_write(ptr, ZR050_TCV_DATA_MH, tmp & 0xff); | ||
521 | tmp = bitcnt & 0xffff; | ||
522 | zr36050_write(ptr, ZR050_TCV_DATA_ML, tmp >> 8); | ||
523 | zr36050_write(ptr, ZR050_TCV_DATA_LO, tmp & 0xff); | ||
524 | |||
525 | /* compression setup with or without bitrate control */ | ||
526 | zr36050_write(ptr, ZR050_MODE, | ||
527 | ZR050_MO_COMP | ZR050_MO_PASS2 | | ||
528 | (ptr->bitrate_ctrl ? ZR050_MO_BRC : 0)); | ||
529 | |||
530 | /* this headers seem to deliver "valid AVI" jpeg frames */ | ||
531 | zr36050_write(ptr, ZR050_MARKERS_EN, | ||
532 | ZR050_ME_DQT | ZR050_ME_DHT | | ||
533 | ((ptr->app.len > 0) ? ZR050_ME_APP : 0) | | ||
534 | ((ptr->com.len > 0) ? ZR050_ME_COM : 0)); | ||
535 | } else { | ||
536 | dprintk(2, "%s: EXPANSION SETUP\n", ptr->name); | ||
537 | |||
538 | /* 050 communicates with 055 in master mode */ | ||
539 | zr36050_write(ptr, ZR050_HARDWARE, | ||
540 | ZR050_HW_MSTR | ZR050_HW_CFIS_2_CLK); | ||
541 | |||
542 | /* encoding table preload */ | ||
543 | zr36050_write(ptr, ZR050_MODE, ZR050_MO_TLM); | ||
544 | |||
545 | /* disable all IRQs */ | ||
546 | zr36050_write(ptr, ZR050_INT_REQ_0, 0); | ||
547 | zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1 | ||
548 | |||
549 | dprintk(3, "%s: write DHT\n", ptr->name); | ||
550 | zr36050_pushit(ptr, ZR050_DHT_IDX, sizeof(zr36050_dht), | ||
551 | zr36050_dht); | ||
552 | |||
553 | /* do the internal huffman table preload */ | ||
554 | zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI); | ||
555 | |||
556 | zr36050_write(ptr, ZR050_GO, 1); // launch codec | ||
557 | zr36050_wait_end(ptr); | ||
558 | dprintk(2, "%s: Status after table preload: 0x%02x\n", | ||
559 | ptr->name, ptr->status1); | ||
560 | |||
561 | if ((ptr->status1 & 0x4) == 0) { | ||
562 | dprintk(1, KERN_ERR "%s: init aborted!\n", | ||
563 | ptr->name); | ||
564 | return; // something is wrong, its timed out!!!! | ||
565 | } | ||
566 | |||
567 | /* setup misc. data for expansion */ | ||
568 | zr36050_write(ptr, ZR050_MODE, 0); | ||
569 | zr36050_write(ptr, ZR050_MARKERS_EN, 0); | ||
570 | } | ||
571 | |||
572 | /* adr on selected, to allow GO from master */ | ||
573 | zr36050_read(ptr, 0); | ||
574 | } | ||
575 | |||
576 | /* ========================================================================= | ||
577 | CODEC API FUNCTIONS | ||
578 | |||
579 | this functions are accessed by the master via the API structure | ||
580 | ========================================================================= */ | ||
581 | |||
582 | /* set compression/expansion mode and launches codec - | ||
583 | this should be the last call from the master before starting processing */ | ||
584 | static int | ||
585 | zr36050_set_mode (struct videocodec *codec, | ||
586 | int mode) | ||
587 | { | ||
588 | struct zr36050 *ptr = (struct zr36050 *) codec->data; | ||
589 | |||
590 | dprintk(2, "%s: set_mode %d call\n", ptr->name, mode); | ||
591 | |||
592 | if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION)) | ||
593 | return -EINVAL; | ||
594 | |||
595 | ptr->mode = mode; | ||
596 | zr36050_init(ptr); | ||
597 | |||
598 | return 0; | ||
599 | } | ||
600 | |||
601 | /* set picture size (norm is ignored as the codec doesn't know about it) */ | ||
602 | static int | ||
603 | zr36050_set_video (struct videocodec *codec, | ||
604 | struct tvnorm *norm, | ||
605 | struct vfe_settings *cap, | ||
606 | struct vfe_polarity *pol) | ||
607 | { | ||
608 | struct zr36050 *ptr = (struct zr36050 *) codec->data; | ||
609 | int size; | ||
610 | |||
611 | dprintk(2, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) q%d call\n", | ||
612 | ptr->name, norm->HStart, norm->VStart, | ||
613 | cap->x, cap->y, cap->width, cap->height, | ||
614 | cap->decimation, cap->quality); | ||
615 | /* if () return -EINVAL; | ||
616 | * trust the master driver that it knows what it does - so | ||
617 | * we allow invalid startx/y and norm for now ... */ | ||
618 | ptr->width = cap->width / (cap->decimation & 0xff); | ||
619 | ptr->height = cap->height / ((cap->decimation >> 8) & 0xff); | ||
620 | |||
621 | /* (KM) JPEG quality */ | ||
622 | size = ptr->width * ptr->height; | ||
623 | size *= 16; /* size in bits */ | ||
624 | /* apply quality setting */ | ||
625 | size = size * cap->quality / 200; | ||
626 | |||
627 | /* Minimum: 1kb */ | ||
628 | if (size < 8192) | ||
629 | size = 8192; | ||
630 | /* Maximum: 7/8 of code buffer */ | ||
631 | if (size > ptr->total_code_vol * 7) | ||
632 | size = ptr->total_code_vol * 7; | ||
633 | |||
634 | ptr->real_code_vol = size >> 3; /* in bytes */ | ||
635 | |||
636 | /* Set max_block_vol here (previously in zr36050_init, moved | ||
637 | * here for consistency with zr36060 code */ | ||
638 | zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol); | ||
639 | |||
640 | return 0; | ||
641 | } | ||
642 | |||
643 | /* additional control functions */ | ||
644 | static int | ||
645 | zr36050_control (struct videocodec *codec, | ||
646 | int type, | ||
647 | int size, | ||
648 | void *data) | ||
649 | { | ||
650 | struct zr36050 *ptr = (struct zr36050 *) codec->data; | ||
651 | int *ival = (int *) data; | ||
652 | |||
653 | dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type, | ||
654 | size); | ||
655 | |||
656 | switch (type) { | ||
657 | case CODEC_G_STATUS: /* get last status */ | ||
658 | if (size != sizeof(int)) | ||
659 | return -EFAULT; | ||
660 | zr36050_read_status1(ptr); | ||
661 | *ival = ptr->status1; | ||
662 | break; | ||
663 | |||
664 | case CODEC_G_CODEC_MODE: | ||
665 | if (size != sizeof(int)) | ||
666 | return -EFAULT; | ||
667 | *ival = CODEC_MODE_BJPG; | ||
668 | break; | ||
669 | |||
670 | case CODEC_S_CODEC_MODE: | ||
671 | if (size != sizeof(int)) | ||
672 | return -EFAULT; | ||
673 | if (*ival != CODEC_MODE_BJPG) | ||
674 | return -EINVAL; | ||
675 | /* not needed, do nothing */ | ||
676 | return 0; | ||
677 | |||
678 | case CODEC_G_VFE: | ||
679 | case CODEC_S_VFE: | ||
680 | /* not needed, do nothing */ | ||
681 | return 0; | ||
682 | |||
683 | case CODEC_S_MMAP: | ||
684 | /* not available, give an error */ | ||
685 | return -ENXIO; | ||
686 | |||
687 | case CODEC_G_JPEG_TDS_BYTE: /* get target volume in byte */ | ||
688 | if (size != sizeof(int)) | ||
689 | return -EFAULT; | ||
690 | *ival = ptr->total_code_vol; | ||
691 | break; | ||
692 | |||
693 | case CODEC_S_JPEG_TDS_BYTE: /* get target volume in byte */ | ||
694 | if (size != sizeof(int)) | ||
695 | return -EFAULT; | ||
696 | ptr->total_code_vol = *ival; | ||
697 | /* (Kieran Morrissey) | ||
698 | * code copied from zr36060.c to ensure proper bitrate */ | ||
699 | ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3; | ||
700 | break; | ||
701 | |||
702 | case CODEC_G_JPEG_SCALE: /* get scaling factor */ | ||
703 | if (size != sizeof(int)) | ||
704 | return -EFAULT; | ||
705 | *ival = zr36050_read_scalefactor(ptr); | ||
706 | break; | ||
707 | |||
708 | case CODEC_S_JPEG_SCALE: /* set scaling factor */ | ||
709 | if (size != sizeof(int)) | ||
710 | return -EFAULT; | ||
711 | ptr->scalefact = *ival; | ||
712 | break; | ||
713 | |||
714 | case CODEC_G_JPEG_APP_DATA: { /* get appn marker data */ | ||
715 | struct jpeg_app_marker *app = data; | ||
716 | |||
717 | if (size != sizeof(struct jpeg_app_marker)) | ||
718 | return -EFAULT; | ||
719 | |||
720 | *app = ptr->app; | ||
721 | break; | ||
722 | } | ||
723 | |||
724 | case CODEC_S_JPEG_APP_DATA: { /* set appn marker data */ | ||
725 | struct jpeg_app_marker *app = data; | ||
726 | |||
727 | if (size != sizeof(struct jpeg_app_marker)) | ||
728 | return -EFAULT; | ||
729 | |||
730 | ptr->app = *app; | ||
731 | break; | ||
732 | } | ||
733 | |||
734 | case CODEC_G_JPEG_COM_DATA: { /* get comment marker data */ | ||
735 | struct jpeg_com_marker *com = data; | ||
736 | |||
737 | if (size != sizeof(struct jpeg_com_marker)) | ||
738 | return -EFAULT; | ||
739 | |||
740 | *com = ptr->com; | ||
741 | break; | ||
742 | } | ||
743 | |||
744 | case CODEC_S_JPEG_COM_DATA: { /* set comment marker data */ | ||
745 | struct jpeg_com_marker *com = data; | ||
746 | |||
747 | if (size != sizeof(struct jpeg_com_marker)) | ||
748 | return -EFAULT; | ||
749 | |||
750 | ptr->com = *com; | ||
751 | break; | ||
752 | } | ||
753 | |||
754 | default: | ||
755 | return -EINVAL; | ||
756 | } | ||
757 | |||
758 | return size; | ||
759 | } | ||
760 | |||
761 | /* ========================================================================= | ||
762 | Exit and unregister function: | ||
763 | |||
764 | Deinitializes Zoran's JPEG processor | ||
765 | ========================================================================= */ | ||
766 | |||
767 | static int | ||
768 | zr36050_unset (struct videocodec *codec) | ||
769 | { | ||
770 | struct zr36050 *ptr = codec->data; | ||
771 | |||
772 | if (ptr) { | ||
773 | /* do wee need some codec deinit here, too ???? */ | ||
774 | |||
775 | dprintk(1, "%s: finished codec #%d\n", ptr->name, | ||
776 | ptr->num); | ||
777 | kfree(ptr); | ||
778 | codec->data = NULL; | ||
779 | |||
780 | zr36050_codecs--; | ||
781 | return 0; | ||
782 | } | ||
783 | |||
784 | return -EFAULT; | ||
785 | } | ||
786 | |||
787 | /* ========================================================================= | ||
788 | Setup and registry function: | ||
789 | |||
790 | Initializes Zoran's JPEG processor | ||
791 | |||
792 | Also sets pixel size, average code size, mode (compr./decompr.) | ||
793 | (the given size is determined by the processor with the video interface) | ||
794 | ========================================================================= */ | ||
795 | |||
796 | static int | ||
797 | zr36050_setup (struct videocodec *codec) | ||
798 | { | ||
799 | struct zr36050 *ptr; | ||
800 | int res; | ||
801 | |||
802 | dprintk(2, "zr36050: initializing MJPEG subsystem #%d.\n", | ||
803 | zr36050_codecs); | ||
804 | |||
805 | if (zr36050_codecs == MAX_CODECS) { | ||
806 | dprintk(1, | ||
807 | KERN_ERR "zr36050: Can't attach more codecs!\n"); | ||
808 | return -ENOSPC; | ||
809 | } | ||
810 | //mem structure init | ||
811 | codec->data = ptr = kzalloc(sizeof(struct zr36050), GFP_KERNEL); | ||
812 | if (NULL == ptr) { | ||
813 | dprintk(1, KERN_ERR "zr36050: Can't get enough memory!\n"); | ||
814 | return -ENOMEM; | ||
815 | } | ||
816 | |||
817 | snprintf(ptr->name, sizeof(ptr->name), "zr36050[%d]", | ||
818 | zr36050_codecs); | ||
819 | ptr->num = zr36050_codecs++; | ||
820 | ptr->codec = codec; | ||
821 | |||
822 | //testing | ||
823 | res = zr36050_basic_test(ptr); | ||
824 | if (res < 0) { | ||
825 | zr36050_unset(codec); | ||
826 | return res; | ||
827 | } | ||
828 | //final setup | ||
829 | memcpy(ptr->h_samp_ratio, zr36050_decimation_h, 8); | ||
830 | memcpy(ptr->v_samp_ratio, zr36050_decimation_v, 8); | ||
831 | |||
832 | ptr->bitrate_ctrl = 0; /* 0 or 1 - fixed file size flag | ||
833 | * (what is the difference?) */ | ||
834 | ptr->mode = CODEC_DO_COMPRESSION; | ||
835 | ptr->width = 384; | ||
836 | ptr->height = 288; | ||
837 | ptr->total_code_vol = 16000; | ||
838 | ptr->max_block_vol = 240; | ||
839 | ptr->scalefact = 0x100; | ||
840 | ptr->dri = 1; | ||
841 | |||
842 | /* no app/com marker by default */ | ||
843 | ptr->app.appn = 0; | ||
844 | ptr->app.len = 0; | ||
845 | ptr->com.len = 0; | ||
846 | |||
847 | zr36050_init(ptr); | ||
848 | |||
849 | dprintk(1, KERN_INFO "%s: codec attached and running\n", | ||
850 | ptr->name); | ||
851 | |||
852 | return 0; | ||
853 | } | ||
854 | |||
855 | static const struct videocodec zr36050_codec = { | ||
856 | .owner = THIS_MODULE, | ||
857 | .name = "zr36050", | ||
858 | .magic = 0L, // magic not used | ||
859 | .flags = | ||
860 | CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER | | ||
861 | CODEC_FLAG_DECODER, | ||
862 | .type = CODEC_TYPE_ZR36050, | ||
863 | .setup = zr36050_setup, // functionality | ||
864 | .unset = zr36050_unset, | ||
865 | .set_mode = zr36050_set_mode, | ||
866 | .set_video = zr36050_set_video, | ||
867 | .control = zr36050_control, | ||
868 | // others are not used | ||
869 | }; | ||
870 | |||
871 | /* ========================================================================= | ||
872 | HOOK IN DRIVER AS KERNEL MODULE | ||
873 | ========================================================================= */ | ||
874 | |||
875 | static int __init | ||
876 | zr36050_init_module (void) | ||
877 | { | ||
878 | //dprintk(1, "ZR36050 driver %s\n",ZR050_VERSION); | ||
879 | zr36050_codecs = 0; | ||
880 | return videocodec_register(&zr36050_codec); | ||
881 | } | ||
882 | |||
883 | static void __exit | ||
884 | zr36050_cleanup_module (void) | ||
885 | { | ||
886 | if (zr36050_codecs) { | ||
887 | dprintk(1, | ||
888 | "zr36050: something's wrong - %d codecs left somehow.\n", | ||
889 | zr36050_codecs); | ||
890 | } | ||
891 | videocodec_unregister(&zr36050_codec); | ||
892 | } | ||
893 | |||
894 | module_init(zr36050_init_module); | ||
895 | module_exit(zr36050_cleanup_module); | ||
896 | |||
897 | MODULE_AUTHOR("Wolfgang Scherr <scherr@net4you.at>"); | ||
898 | MODULE_DESCRIPTION("Driver module for ZR36050 jpeg processors " | ||
899 | ZR050_VERSION); | ||
900 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/zoran/zr36050.h b/drivers/media/video/zoran/zr36050.h deleted file mode 100644 index 9f52f0cdde50..000000000000 --- a/drivers/media/video/zoran/zr36050.h +++ /dev/null | |||
@@ -1,184 +0,0 @@ | |||
1 | /* | ||
2 | * Zoran ZR36050 basic configuration functions - header file | ||
3 | * | ||
4 | * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at> | ||
5 | * | ||
6 | * $Id: zr36050.h,v 1.1.2.2 2003/01/14 21:18:22 rbultje Exp $ | ||
7 | * | ||
8 | * ------------------------------------------------------------------------ | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | * | ||
24 | * ------------------------------------------------------------------------ | ||
25 | */ | ||
26 | |||
27 | #ifndef ZR36050_H | ||
28 | #define ZR36050_H | ||
29 | |||
30 | #include "videocodec.h" | ||
31 | |||
32 | /* data stored for each zoran jpeg codec chip */ | ||
33 | struct zr36050 { | ||
34 | char name[32]; | ||
35 | int num; | ||
36 | /* io datastructure */ | ||
37 | struct videocodec *codec; | ||
38 | // last coder status | ||
39 | __u8 status1; | ||
40 | // actual coder setup | ||
41 | int mode; | ||
42 | |||
43 | __u16 width; | ||
44 | __u16 height; | ||
45 | |||
46 | __u16 bitrate_ctrl; | ||
47 | |||
48 | __u32 total_code_vol; | ||
49 | __u32 real_code_vol; | ||
50 | __u16 max_block_vol; | ||
51 | |||
52 | __u8 h_samp_ratio[8]; | ||
53 | __u8 v_samp_ratio[8]; | ||
54 | __u16 scalefact; | ||
55 | __u16 dri; | ||
56 | |||
57 | /* com/app marker */ | ||
58 | struct jpeg_com_marker com; | ||
59 | struct jpeg_app_marker app; | ||
60 | }; | ||
61 | |||
62 | /* zr36050 register addresses */ | ||
63 | #define ZR050_GO 0x000 | ||
64 | #define ZR050_HARDWARE 0x002 | ||
65 | #define ZR050_MODE 0x003 | ||
66 | #define ZR050_OPTIONS 0x004 | ||
67 | #define ZR050_MBCV 0x005 | ||
68 | #define ZR050_MARKERS_EN 0x006 | ||
69 | #define ZR050_INT_REQ_0 0x007 | ||
70 | #define ZR050_INT_REQ_1 0x008 | ||
71 | #define ZR050_TCV_NET_HI 0x009 | ||
72 | #define ZR050_TCV_NET_MH 0x00a | ||
73 | #define ZR050_TCV_NET_ML 0x00b | ||
74 | #define ZR050_TCV_NET_LO 0x00c | ||
75 | #define ZR050_TCV_DATA_HI 0x00d | ||
76 | #define ZR050_TCV_DATA_MH 0x00e | ||
77 | #define ZR050_TCV_DATA_ML 0x00f | ||
78 | #define ZR050_TCV_DATA_LO 0x010 | ||
79 | #define ZR050_SF_HI 0x011 | ||
80 | #define ZR050_SF_LO 0x012 | ||
81 | #define ZR050_AF_HI 0x013 | ||
82 | #define ZR050_AF_M 0x014 | ||
83 | #define ZR050_AF_LO 0x015 | ||
84 | #define ZR050_ACV_HI 0x016 | ||
85 | #define ZR050_ACV_MH 0x017 | ||
86 | #define ZR050_ACV_ML 0x018 | ||
87 | #define ZR050_ACV_LO 0x019 | ||
88 | #define ZR050_ACT_HI 0x01a | ||
89 | #define ZR050_ACT_MH 0x01b | ||
90 | #define ZR050_ACT_ML 0x01c | ||
91 | #define ZR050_ACT_LO 0x01d | ||
92 | #define ZR050_ACV_TRUN_HI 0x01e | ||
93 | #define ZR050_ACV_TRUN_MH 0x01f | ||
94 | #define ZR050_ACV_TRUN_ML 0x020 | ||
95 | #define ZR050_ACV_TRUN_LO 0x021 | ||
96 | #define ZR050_STATUS_0 0x02e | ||
97 | #define ZR050_STATUS_1 0x02f | ||
98 | |||
99 | #define ZR050_SOF_IDX 0x040 | ||
100 | #define ZR050_SOS1_IDX 0x07a | ||
101 | #define ZR050_SOS2_IDX 0x08a | ||
102 | #define ZR050_SOS3_IDX 0x09a | ||
103 | #define ZR050_SOS4_IDX 0x0aa | ||
104 | #define ZR050_DRI_IDX 0x0c0 | ||
105 | #define ZR050_DNL_IDX 0x0c6 | ||
106 | #define ZR050_DQT_IDX 0x0cc | ||
107 | #define ZR050_DHT_IDX 0x1d4 | ||
108 | #define ZR050_APP_IDX 0x380 | ||
109 | #define ZR050_COM_IDX 0x3c0 | ||
110 | |||
111 | /* zr36050 hardware register bits */ | ||
112 | |||
113 | #define ZR050_HW_BSWD 0x80 | ||
114 | #define ZR050_HW_MSTR 0x40 | ||
115 | #define ZR050_HW_DMA 0x20 | ||
116 | #define ZR050_HW_CFIS_1_CLK 0x00 | ||
117 | #define ZR050_HW_CFIS_2_CLK 0x04 | ||
118 | #define ZR050_HW_CFIS_3_CLK 0x08 | ||
119 | #define ZR050_HW_CFIS_4_CLK 0x0C | ||
120 | #define ZR050_HW_CFIS_5_CLK 0x10 | ||
121 | #define ZR050_HW_CFIS_6_CLK 0x14 | ||
122 | #define ZR050_HW_CFIS_7_CLK 0x18 | ||
123 | #define ZR050_HW_CFIS_8_CLK 0x1C | ||
124 | #define ZR050_HW_BELE 0x01 | ||
125 | |||
126 | /* zr36050 mode register bits */ | ||
127 | |||
128 | #define ZR050_MO_COMP 0x80 | ||
129 | #define ZR050_MO_COMP 0x80 | ||
130 | #define ZR050_MO_ATP 0x40 | ||
131 | #define ZR050_MO_PASS2 0x20 | ||
132 | #define ZR050_MO_TLM 0x10 | ||
133 | #define ZR050_MO_DCONLY 0x08 | ||
134 | #define ZR050_MO_BRC 0x04 | ||
135 | |||
136 | #define ZR050_MO_ATP 0x40 | ||
137 | #define ZR050_MO_PASS2 0x20 | ||
138 | #define ZR050_MO_TLM 0x10 | ||
139 | #define ZR050_MO_DCONLY 0x08 | ||
140 | |||
141 | /* zr36050 option register bits */ | ||
142 | |||
143 | #define ZR050_OP_NSCN_1 0x00 | ||
144 | #define ZR050_OP_NSCN_2 0x20 | ||
145 | #define ZR050_OP_NSCN_3 0x40 | ||
146 | #define ZR050_OP_NSCN_4 0x60 | ||
147 | #define ZR050_OP_NSCN_5 0x80 | ||
148 | #define ZR050_OP_NSCN_6 0xA0 | ||
149 | #define ZR050_OP_NSCN_7 0xC0 | ||
150 | #define ZR050_OP_NSCN_8 0xE0 | ||
151 | #define ZR050_OP_OVF 0x10 | ||
152 | |||
153 | |||
154 | /* zr36050 markers-enable register bits */ | ||
155 | |||
156 | #define ZR050_ME_APP 0x80 | ||
157 | #define ZR050_ME_COM 0x40 | ||
158 | #define ZR050_ME_DRI 0x20 | ||
159 | #define ZR050_ME_DQT 0x10 | ||
160 | #define ZR050_ME_DHT 0x08 | ||
161 | #define ZR050_ME_DNL 0x04 | ||
162 | #define ZR050_ME_DQTI 0x02 | ||
163 | #define ZR050_ME_DHTI 0x01 | ||
164 | |||
165 | /* zr36050 status0/1 register bit masks */ | ||
166 | |||
167 | #define ZR050_ST_RST_MASK 0x20 | ||
168 | #define ZR050_ST_SOF_MASK 0x02 | ||
169 | #define ZR050_ST_SOS_MASK 0x02 | ||
170 | #define ZR050_ST_DATRDY_MASK 0x80 | ||
171 | #define ZR050_ST_MRKDET_MASK 0x40 | ||
172 | #define ZR050_ST_RFM_MASK 0x10 | ||
173 | #define ZR050_ST_RFD_MASK 0x08 | ||
174 | #define ZR050_ST_END_MASK 0x04 | ||
175 | #define ZR050_ST_TCVOVF_MASK 0x02 | ||
176 | #define ZR050_ST_DATOVF_MASK 0x01 | ||
177 | |||
178 | /* pixel component idx */ | ||
179 | |||
180 | #define ZR050_Y_COMPONENT 0 | ||
181 | #define ZR050_U_COMPONENT 1 | ||
182 | #define ZR050_V_COMPONENT 2 | ||
183 | |||
184 | #endif /*fndef ZR36050_H */ | ||
diff --git a/drivers/media/video/zoran/zr36057.h b/drivers/media/video/zoran/zr36057.h deleted file mode 100644 index 54c9362aa980..000000000000 --- a/drivers/media/video/zoran/zr36057.h +++ /dev/null | |||
@@ -1,168 +0,0 @@ | |||
1 | /* | ||
2 | * zr36057.h - zr36057 register offsets | ||
3 | * | ||
4 | * Copyright (C) 1998 Dave Perks <dperks@ibm.net> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef _ZR36057_H_ | ||
22 | #define _ZR36057_H_ | ||
23 | |||
24 | |||
25 | /* Zoran ZR36057 registers */ | ||
26 | |||
27 | #define ZR36057_VFEHCR 0x000 /* Video Front End, Horizontal Configuration Register */ | ||
28 | #define ZR36057_VFEHCR_HSPol (1<<30) | ||
29 | #define ZR36057_VFEHCR_HStart 10 | ||
30 | #define ZR36057_VFEHCR_HEnd 0 | ||
31 | #define ZR36057_VFEHCR_Hmask 0x3ff | ||
32 | |||
33 | #define ZR36057_VFEVCR 0x004 /* Video Front End, Vertical Configuration Register */ | ||
34 | #define ZR36057_VFEVCR_VSPol (1<<30) | ||
35 | #define ZR36057_VFEVCR_VStart 10 | ||
36 | #define ZR36057_VFEVCR_VEnd 0 | ||
37 | #define ZR36057_VFEVCR_Vmask 0x3ff | ||
38 | |||
39 | #define ZR36057_VFESPFR 0x008 /* Video Front End, Scaler and Pixel Format Register */ | ||
40 | #define ZR36057_VFESPFR_ExtFl (1<<26) | ||
41 | #define ZR36057_VFESPFR_TopField (1<<25) | ||
42 | #define ZR36057_VFESPFR_VCLKPol (1<<24) | ||
43 | #define ZR36057_VFESPFR_HFilter 21 | ||
44 | #define ZR36057_VFESPFR_HorDcm 14 | ||
45 | #define ZR36057_VFESPFR_VerDcm 8 | ||
46 | #define ZR36057_VFESPFR_DispMode 6 | ||
47 | #define ZR36057_VFESPFR_YUV422 (0<<3) | ||
48 | #define ZR36057_VFESPFR_RGB888 (1<<3) | ||
49 | #define ZR36057_VFESPFR_RGB565 (2<<3) | ||
50 | #define ZR36057_VFESPFR_RGB555 (3<<3) | ||
51 | #define ZR36057_VFESPFR_ErrDif (1<<2) | ||
52 | #define ZR36057_VFESPFR_Pack24 (1<<1) | ||
53 | #define ZR36057_VFESPFR_LittleEndian (1<<0) | ||
54 | |||
55 | #define ZR36057_VDTR 0x00c /* Video Display "Top" Register */ | ||
56 | |||
57 | #define ZR36057_VDBR 0x010 /* Video Display "Bottom" Register */ | ||
58 | |||
59 | #define ZR36057_VSSFGR 0x014 /* Video Stride, Status, and Frame Grab Register */ | ||
60 | #define ZR36057_VSSFGR_DispStride 16 | ||
61 | #define ZR36057_VSSFGR_VidOvf (1<<8) | ||
62 | #define ZR36057_VSSFGR_SnapShot (1<<1) | ||
63 | #define ZR36057_VSSFGR_FrameGrab (1<<0) | ||
64 | |||
65 | #define ZR36057_VDCR 0x018 /* Video Display Configuration Register */ | ||
66 | #define ZR36057_VDCR_VidEn (1<<31) | ||
67 | #define ZR36057_VDCR_MinPix 24 | ||
68 | #define ZR36057_VDCR_Triton (1<<24) | ||
69 | #define ZR36057_VDCR_VidWinHt 12 | ||
70 | #define ZR36057_VDCR_VidWinWid 0 | ||
71 | |||
72 | #define ZR36057_MMTR 0x01c /* Masking Map "Top" Register */ | ||
73 | |||
74 | #define ZR36057_MMBR 0x020 /* Masking Map "Bottom" Register */ | ||
75 | |||
76 | #define ZR36057_OCR 0x024 /* Overlay Control Register */ | ||
77 | #define ZR36057_OCR_OvlEnable (1 << 15) | ||
78 | #define ZR36057_OCR_MaskStride 0 | ||
79 | |||
80 | #define ZR36057_SPGPPCR 0x028 /* System, PCI, and General Purpose Pins Control Register */ | ||
81 | #define ZR36057_SPGPPCR_SoftReset (1<<24) | ||
82 | |||
83 | #define ZR36057_GPPGCR1 0x02c /* General Purpose Pins and GuestBus Control Register (1) */ | ||
84 | |||
85 | #define ZR36057_MCSAR 0x030 /* MPEG Code Source Address Register */ | ||
86 | |||
87 | #define ZR36057_MCTCR 0x034 /* MPEG Code Transfer Control Register */ | ||
88 | #define ZR36057_MCTCR_CodTime (1 << 30) | ||
89 | #define ZR36057_MCTCR_CEmpty (1 << 29) | ||
90 | #define ZR36057_MCTCR_CFlush (1 << 28) | ||
91 | #define ZR36057_MCTCR_CodGuestID 20 | ||
92 | #define ZR36057_MCTCR_CodGuestReg 16 | ||
93 | |||
94 | #define ZR36057_MCMPR 0x038 /* MPEG Code Memory Pointer Register */ | ||
95 | |||
96 | #define ZR36057_ISR 0x03c /* Interrupt Status Register */ | ||
97 | #define ZR36057_ISR_GIRQ1 (1<<30) | ||
98 | #define ZR36057_ISR_GIRQ0 (1<<29) | ||
99 | #define ZR36057_ISR_CodRepIRQ (1<<28) | ||
100 | #define ZR36057_ISR_JPEGRepIRQ (1<<27) | ||
101 | |||
102 | #define ZR36057_ICR 0x040 /* Interrupt Control Register */ | ||
103 | #define ZR36057_ICR_GIRQ1 (1<<30) | ||
104 | #define ZR36057_ICR_GIRQ0 (1<<29) | ||
105 | #define ZR36057_ICR_CodRepIRQ (1<<28) | ||
106 | #define ZR36057_ICR_JPEGRepIRQ (1<<27) | ||
107 | #define ZR36057_ICR_IntPinEn (1<<24) | ||
108 | |||
109 | #define ZR36057_I2CBR 0x044 /* I2C Bus Register */ | ||
110 | #define ZR36057_I2CBR_SDA (1<<1) | ||
111 | #define ZR36057_I2CBR_SCL (1<<0) | ||
112 | |||
113 | #define ZR36057_JMC 0x100 /* JPEG Mode and Control */ | ||
114 | #define ZR36057_JMC_JPG (1 << 31) | ||
115 | #define ZR36057_JMC_JPGExpMode (0 << 29) | ||
116 | #define ZR36057_JMC_JPGCmpMode (1 << 29) | ||
117 | #define ZR36057_JMC_MJPGExpMode (2 << 29) | ||
118 | #define ZR36057_JMC_MJPGCmpMode (3 << 29) | ||
119 | #define ZR36057_JMC_RTBUSY_FB (1 << 6) | ||
120 | #define ZR36057_JMC_Go_en (1 << 5) | ||
121 | #define ZR36057_JMC_SyncMstr (1 << 4) | ||
122 | #define ZR36057_JMC_Fld_per_buff (1 << 3) | ||
123 | #define ZR36057_JMC_VFIFO_FB (1 << 2) | ||
124 | #define ZR36057_JMC_CFIFO_FB (1 << 1) | ||
125 | #define ZR36057_JMC_Stll_LitEndian (1 << 0) | ||
126 | |||
127 | #define ZR36057_JPC 0x104 /* JPEG Process Control */ | ||
128 | #define ZR36057_JPC_P_Reset (1 << 7) | ||
129 | #define ZR36057_JPC_CodTrnsEn (1 << 5) | ||
130 | #define ZR36057_JPC_Active (1 << 0) | ||
131 | |||
132 | #define ZR36057_VSP 0x108 /* Vertical Sync Parameters */ | ||
133 | #define ZR36057_VSP_VsyncSize 16 | ||
134 | #define ZR36057_VSP_FrmTot 0 | ||
135 | |||
136 | #define ZR36057_HSP 0x10c /* Horizontal Sync Parameters */ | ||
137 | #define ZR36057_HSP_HsyncStart 16 | ||
138 | #define ZR36057_HSP_LineTot 0 | ||
139 | |||
140 | #define ZR36057_FHAP 0x110 /* Field Horizontal Active Portion */ | ||
141 | #define ZR36057_FHAP_NAX 16 | ||
142 | #define ZR36057_FHAP_PAX 0 | ||
143 | |||
144 | #define ZR36057_FVAP 0x114 /* Field Vertical Active Portion */ | ||
145 | #define ZR36057_FVAP_NAY 16 | ||
146 | #define ZR36057_FVAP_PAY 0 | ||
147 | |||
148 | #define ZR36057_FPP 0x118 /* Field Process Parameters */ | ||
149 | #define ZR36057_FPP_Odd_Even (1 << 0) | ||
150 | |||
151 | #define ZR36057_JCBA 0x11c /* JPEG Code Base Address */ | ||
152 | |||
153 | #define ZR36057_JCFT 0x120 /* JPEG Code FIFO Threshold */ | ||
154 | |||
155 | #define ZR36057_JCGI 0x124 /* JPEG Codec Guest ID */ | ||
156 | #define ZR36057_JCGI_JPEGuestID 4 | ||
157 | #define ZR36057_JCGI_JPEGuestReg 0 | ||
158 | |||
159 | #define ZR36057_GCR2 0x12c /* GuestBus Control Register (2) */ | ||
160 | |||
161 | #define ZR36057_POR 0x200 /* Post Office Register */ | ||
162 | #define ZR36057_POR_POPen (1<<25) | ||
163 | #define ZR36057_POR_POTime (1<<24) | ||
164 | #define ZR36057_POR_PODir (1<<23) | ||
165 | |||
166 | #define ZR36057_STR 0x300 /* "Still" Transfer Register */ | ||
167 | |||
168 | #endif | ||
diff --git a/drivers/media/video/zoran/zr36060.c b/drivers/media/video/zoran/zr36060.c deleted file mode 100644 index f08546fe2234..000000000000 --- a/drivers/media/video/zoran/zr36060.c +++ /dev/null | |||
@@ -1,1010 +0,0 @@ | |||
1 | /* | ||
2 | * Zoran ZR36060 basic configuration functions | ||
3 | * | ||
4 | * Copyright (C) 2002 Laurent Pinchart <laurent.pinchart@skynet.be> | ||
5 | * | ||
6 | * $Id: zr36060.c,v 1.1.2.22 2003/05/06 09:35:36 rbultje Exp $ | ||
7 | * | ||
8 | * ------------------------------------------------------------------------ | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | * | ||
24 | * ------------------------------------------------------------------------ | ||
25 | */ | ||
26 | |||
27 | #define ZR060_VERSION "v0.7" | ||
28 | |||
29 | #include <linux/module.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/slab.h> | ||
32 | #include <linux/delay.h> | ||
33 | |||
34 | #include <linux/types.h> | ||
35 | #include <linux/wait.h> | ||
36 | |||
37 | /* I/O commands, error codes */ | ||
38 | #include <asm/io.h> | ||
39 | |||
40 | /* headerfile of this module */ | ||
41 | #include "zr36060.h" | ||
42 | |||
43 | /* codec io API */ | ||
44 | #include "videocodec.h" | ||
45 | |||
46 | /* it doesn't make sense to have more than 20 or so, | ||
47 | just to prevent some unwanted loops */ | ||
48 | #define MAX_CODECS 20 | ||
49 | |||
50 | /* amount of chips attached via this driver */ | ||
51 | static int zr36060_codecs; | ||
52 | |||
53 | static bool low_bitrate; | ||
54 | module_param(low_bitrate, bool, 0); | ||
55 | MODULE_PARM_DESC(low_bitrate, "Buz compatibility option, halves bitrate"); | ||
56 | |||
57 | /* debugging is available via module parameter */ | ||
58 | static int debug; | ||
59 | module_param(debug, int, 0); | ||
60 | MODULE_PARM_DESC(debug, "Debug level (0-4)"); | ||
61 | |||
62 | #define dprintk(num, format, args...) \ | ||
63 | do { \ | ||
64 | if (debug >= num) \ | ||
65 | printk(format, ##args); \ | ||
66 | } while (0) | ||
67 | |||
68 | /* ========================================================================= | ||
69 | Local hardware I/O functions: | ||
70 | |||
71 | read/write via codec layer (registers are located in the master device) | ||
72 | ========================================================================= */ | ||
73 | |||
74 | /* read and write functions */ | ||
75 | static u8 | ||
76 | zr36060_read (struct zr36060 *ptr, | ||
77 | u16 reg) | ||
78 | { | ||
79 | u8 value = 0; | ||
80 | |||
81 | // just in case something is wrong... | ||
82 | if (ptr->codec->master_data->readreg) | ||
83 | value = (ptr->codec->master_data->readreg(ptr->codec, | ||
84 | reg)) & 0xff; | ||
85 | else | ||
86 | dprintk(1, | ||
87 | KERN_ERR "%s: invalid I/O setup, nothing read!\n", | ||
88 | ptr->name); | ||
89 | |||
90 | //dprintk(4, "%s: reading from 0x%04x: %02x\n",ptr->name,reg,value); | ||
91 | |||
92 | return value; | ||
93 | } | ||
94 | |||
95 | static void | ||
96 | zr36060_write(struct zr36060 *ptr, | ||
97 | u16 reg, | ||
98 | u8 value) | ||
99 | { | ||
100 | //dprintk(4, "%s: writing 0x%02x to 0x%04x\n",ptr->name,value,reg); | ||
101 | dprintk(4, "0x%02x @0x%04x\n", value, reg); | ||
102 | |||
103 | // just in case something is wrong... | ||
104 | if (ptr->codec->master_data->writereg) | ||
105 | ptr->codec->master_data->writereg(ptr->codec, reg, value); | ||
106 | else | ||
107 | dprintk(1, | ||
108 | KERN_ERR | ||
109 | "%s: invalid I/O setup, nothing written!\n", | ||
110 | ptr->name); | ||
111 | } | ||
112 | |||
113 | /* ========================================================================= | ||
114 | Local helper function: | ||
115 | |||
116 | status read | ||
117 | ========================================================================= */ | ||
118 | |||
119 | /* status is kept in datastructure */ | ||
120 | static u8 | ||
121 | zr36060_read_status (struct zr36060 *ptr) | ||
122 | { | ||
123 | ptr->status = zr36060_read(ptr, ZR060_CFSR); | ||
124 | |||
125 | zr36060_read(ptr, 0); | ||
126 | return ptr->status; | ||
127 | } | ||
128 | |||
129 | /* ========================================================================= | ||
130 | Local helper function: | ||
131 | |||
132 | scale factor read | ||
133 | ========================================================================= */ | ||
134 | |||
135 | /* scale factor is kept in datastructure */ | ||
136 | static u16 | ||
137 | zr36060_read_scalefactor (struct zr36060 *ptr) | ||
138 | { | ||
139 | ptr->scalefact = (zr36060_read(ptr, ZR060_SF_HI) << 8) | | ||
140 | (zr36060_read(ptr, ZR060_SF_LO) & 0xFF); | ||
141 | |||
142 | /* leave 0 selected for an eventually GO from master */ | ||
143 | zr36060_read(ptr, 0); | ||
144 | return ptr->scalefact; | ||
145 | } | ||
146 | |||
147 | /* ========================================================================= | ||
148 | Local helper function: | ||
149 | |||
150 | wait if codec is ready to proceed (end of processing) or time is over | ||
151 | ========================================================================= */ | ||
152 | |||
153 | static void | ||
154 | zr36060_wait_end (struct zr36060 *ptr) | ||
155 | { | ||
156 | int i = 0; | ||
157 | |||
158 | while (zr36060_read_status(ptr) & ZR060_CFSR_Busy) { | ||
159 | udelay(1); | ||
160 | if (i++ > 200000) { // 200ms, there is for sure something wrong!!! | ||
161 | dprintk(1, | ||
162 | "%s: timeout at wait_end (last status: 0x%02x)\n", | ||
163 | ptr->name, ptr->status); | ||
164 | break; | ||
165 | } | ||
166 | } | ||
167 | } | ||
168 | |||
169 | /* ========================================================================= | ||
170 | Local helper function: | ||
171 | |||
172 | basic test of "connectivity", writes/reads to/from memory the SOF marker | ||
173 | ========================================================================= */ | ||
174 | |||
175 | static int | ||
176 | zr36060_basic_test (struct zr36060 *ptr) | ||
177 | { | ||
178 | if ((zr36060_read(ptr, ZR060_IDR_DEV) != 0x33) && | ||
179 | (zr36060_read(ptr, ZR060_IDR_REV) != 0x01)) { | ||
180 | dprintk(1, | ||
181 | KERN_ERR | ||
182 | "%s: attach failed, can't connect to jpeg processor!\n", | ||
183 | ptr->name); | ||
184 | return -ENXIO; | ||
185 | } | ||
186 | |||
187 | zr36060_wait_end(ptr); | ||
188 | if (ptr->status & ZR060_CFSR_Busy) { | ||
189 | dprintk(1, | ||
190 | KERN_ERR | ||
191 | "%s: attach failed, jpeg processor failed (end flag)!\n", | ||
192 | ptr->name); | ||
193 | return -EBUSY; | ||
194 | } | ||
195 | |||
196 | return 0; /* looks good! */ | ||
197 | } | ||
198 | |||
199 | /* ========================================================================= | ||
200 | Local helper function: | ||
201 | |||
202 | simple loop for pushing the init datasets | ||
203 | ========================================================================= */ | ||
204 | |||
205 | static int | ||
206 | zr36060_pushit (struct zr36060 *ptr, | ||
207 | u16 startreg, | ||
208 | u16 len, | ||
209 | const char *data) | ||
210 | { | ||
211 | int i = 0; | ||
212 | |||
213 | dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name, | ||
214 | startreg, len); | ||
215 | while (i < len) { | ||
216 | zr36060_write(ptr, startreg++, data[i++]); | ||
217 | } | ||
218 | |||
219 | return i; | ||
220 | } | ||
221 | |||
222 | /* ========================================================================= | ||
223 | Basic datasets: | ||
224 | |||
225 | jpeg baseline setup data (you find it on lots places in internet, or just | ||
226 | extract it from any regular .jpg image...) | ||
227 | |||
228 | Could be variable, but until it's not needed it they are just fixed to save | ||
229 | memory. Otherwise expand zr36060 structure with arrays, push the values to | ||
230 | it and initialize from there, as e.g. the linux zr36057/60 driver does it. | ||
231 | ========================================================================= */ | ||
232 | |||
233 | static const char zr36060_dqt[0x86] = { | ||
234 | 0xff, 0xdb, //Marker: DQT | ||
235 | 0x00, 0x84, //Length: 2*65+2 | ||
236 | 0x00, //Pq,Tq first table | ||
237 | 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, | ||
238 | 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, | ||
239 | 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, | ||
240 | 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, | ||
241 | 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44, | ||
242 | 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57, | ||
243 | 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, | ||
244 | 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63, | ||
245 | 0x01, //Pq,Tq second table | ||
246 | 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, | ||
247 | 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, | ||
248 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
249 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
250 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
251 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
252 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
253 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 | ||
254 | }; | ||
255 | |||
256 | static const char zr36060_dht[0x1a4] = { | ||
257 | 0xff, 0xc4, //Marker: DHT | ||
258 | 0x01, 0xa2, //Length: 2*AC, 2*DC | ||
259 | 0x00, //DC first table | ||
260 | 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, | ||
261 | 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | ||
262 | 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, | ||
263 | 0x01, //DC second table | ||
264 | 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, | ||
265 | 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | ||
266 | 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, | ||
267 | 0x10, //AC first table | ||
268 | 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, | ||
269 | 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, | ||
270 | 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, | ||
271 | 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, | ||
272 | 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, | ||
273 | 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, | ||
274 | 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, | ||
275 | 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, | ||
276 | 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, | ||
277 | 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, | ||
278 | 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, | ||
279 | 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, | ||
280 | 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, | ||
281 | 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, | ||
282 | 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, | ||
283 | 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, | ||
284 | 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, | ||
285 | 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, | ||
286 | 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, | ||
287 | 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, | ||
288 | 0xF8, 0xF9, 0xFA, | ||
289 | 0x11, //AC second table | ||
290 | 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, | ||
291 | 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, | ||
292 | 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, | ||
293 | 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, | ||
294 | 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, | ||
295 | 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, | ||
296 | 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, | ||
297 | 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, | ||
298 | 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, | ||
299 | 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, | ||
300 | 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, | ||
301 | 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, | ||
302 | 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, | ||
303 | 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, | ||
304 | 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, | ||
305 | 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, | ||
306 | 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, | ||
307 | 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, | ||
308 | 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, | ||
309 | 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, | ||
310 | 0xF9, 0xFA | ||
311 | }; | ||
312 | |||
313 | /* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */ | ||
314 | #define NO_OF_COMPONENTS 0x3 //Y,U,V | ||
315 | #define BASELINE_PRECISION 0x8 //MCU size (?) | ||
316 | static const char zr36060_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's QT | ||
317 | static const char zr36060_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's DC | ||
318 | static const char zr36060_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's AC | ||
319 | |||
320 | /* horizontal 422 decimation setup (maybe we support 411 or so later, too) */ | ||
321 | static const char zr36060_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 }; | ||
322 | static const char zr36060_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 }; | ||
323 | |||
324 | /* ========================================================================= | ||
325 | Local helper functions: | ||
326 | |||
327 | calculation and setup of parameter-dependent JPEG baseline segments | ||
328 | (needed for compression only) | ||
329 | ========================================================================= */ | ||
330 | |||
331 | /* ------------------------------------------------------------------------- */ | ||
332 | |||
333 | /* SOF (start of frame) segment depends on width, height and sampling ratio | ||
334 | of each color component */ | ||
335 | |||
336 | static int | ||
337 | zr36060_set_sof (struct zr36060 *ptr) | ||
338 | { | ||
339 | char sof_data[34]; // max. size of register set | ||
340 | int i; | ||
341 | |||
342 | dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name, | ||
343 | ptr->width, ptr->height, NO_OF_COMPONENTS); | ||
344 | sof_data[0] = 0xff; | ||
345 | sof_data[1] = 0xc0; | ||
346 | sof_data[2] = 0x00; | ||
347 | sof_data[3] = (3 * NO_OF_COMPONENTS) + 8; | ||
348 | sof_data[4] = BASELINE_PRECISION; // only '8' possible with zr36060 | ||
349 | sof_data[5] = (ptr->height) >> 8; | ||
350 | sof_data[6] = (ptr->height) & 0xff; | ||
351 | sof_data[7] = (ptr->width) >> 8; | ||
352 | sof_data[8] = (ptr->width) & 0xff; | ||
353 | sof_data[9] = NO_OF_COMPONENTS; | ||
354 | for (i = 0; i < NO_OF_COMPONENTS; i++) { | ||
355 | sof_data[10 + (i * 3)] = i; // index identifier | ||
356 | sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) | | ||
357 | (ptr->v_samp_ratio[i]); // sampling ratios | ||
358 | sof_data[12 + (i * 3)] = zr36060_tq[i]; // Q table selection | ||
359 | } | ||
360 | return zr36060_pushit(ptr, ZR060_SOF_IDX, | ||
361 | (3 * NO_OF_COMPONENTS) + 10, sof_data); | ||
362 | } | ||
363 | |||
364 | /* ------------------------------------------------------------------------- */ | ||
365 | |||
366 | /* SOS (start of scan) segment depends on the used scan components | ||
367 | of each color component */ | ||
368 | |||
369 | static int | ||
370 | zr36060_set_sos (struct zr36060 *ptr) | ||
371 | { | ||
372 | char sos_data[16]; // max. size of register set | ||
373 | int i; | ||
374 | |||
375 | dprintk(3, "%s: write SOS\n", ptr->name); | ||
376 | sos_data[0] = 0xff; | ||
377 | sos_data[1] = 0xda; | ||
378 | sos_data[2] = 0x00; | ||
379 | sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3; | ||
380 | sos_data[4] = NO_OF_COMPONENTS; | ||
381 | for (i = 0; i < NO_OF_COMPONENTS; i++) { | ||
382 | sos_data[5 + (i * 2)] = i; // index | ||
383 | sos_data[6 + (i * 2)] = (zr36060_td[i] << 4) | | ||
384 | zr36060_ta[i]; // AC/DC tbl.sel. | ||
385 | } | ||
386 | sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00; // scan start | ||
387 | sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3f; | ||
388 | sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00; | ||
389 | return zr36060_pushit(ptr, ZR060_SOS_IDX, | ||
390 | 4 + 1 + (2 * NO_OF_COMPONENTS) + 3, | ||
391 | sos_data); | ||
392 | } | ||
393 | |||
394 | /* ------------------------------------------------------------------------- */ | ||
395 | |||
396 | /* DRI (define restart interval) */ | ||
397 | |||
398 | static int | ||
399 | zr36060_set_dri (struct zr36060 *ptr) | ||
400 | { | ||
401 | char dri_data[6]; // max. size of register set | ||
402 | |||
403 | dprintk(3, "%s: write DRI\n", ptr->name); | ||
404 | dri_data[0] = 0xff; | ||
405 | dri_data[1] = 0xdd; | ||
406 | dri_data[2] = 0x00; | ||
407 | dri_data[3] = 0x04; | ||
408 | dri_data[4] = (ptr->dri) >> 8; | ||
409 | dri_data[5] = (ptr->dri) & 0xff; | ||
410 | return zr36060_pushit(ptr, ZR060_DRI_IDX, 6, dri_data); | ||
411 | } | ||
412 | |||
413 | /* ========================================================================= | ||
414 | Setup function: | ||
415 | |||
416 | Setup compression/decompression of Zoran's JPEG processor | ||
417 | ( see also zoran 36060 manual ) | ||
418 | |||
419 | ... sorry for the spaghetti code ... | ||
420 | ========================================================================= */ | ||
421 | static void | ||
422 | zr36060_init (struct zr36060 *ptr) | ||
423 | { | ||
424 | int sum = 0; | ||
425 | long bitcnt, tmp; | ||
426 | |||
427 | if (ptr->mode == CODEC_DO_COMPRESSION) { | ||
428 | dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name); | ||
429 | |||
430 | zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst); | ||
431 | |||
432 | /* 060 communicates with 067 in master mode */ | ||
433 | zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CodeMstr); | ||
434 | |||
435 | /* Compression with or without variable scale factor */ | ||
436 | /*FIXME: What about ptr->bitrate_ctrl? */ | ||
437 | zr36060_write(ptr, ZR060_CMR, | ||
438 | ZR060_CMR_Comp | ZR060_CMR_Pass2 | | ||
439 | ZR060_CMR_BRB); | ||
440 | |||
441 | /* Must be zero */ | ||
442 | zr36060_write(ptr, ZR060_MBZ, 0x00); | ||
443 | zr36060_write(ptr, ZR060_TCR_HI, 0x00); | ||
444 | zr36060_write(ptr, ZR060_TCR_LO, 0x00); | ||
445 | |||
446 | /* Disable all IRQs - no DataErr means autoreset */ | ||
447 | zr36060_write(ptr, ZR060_IMR, 0); | ||
448 | |||
449 | /* volume control settings */ | ||
450 | zr36060_write(ptr, ZR060_SF_HI, ptr->scalefact >> 8); | ||
451 | zr36060_write(ptr, ZR060_SF_LO, ptr->scalefact & 0xff); | ||
452 | |||
453 | zr36060_write(ptr, ZR060_AF_HI, 0xff); | ||
454 | zr36060_write(ptr, ZR060_AF_M, 0xff); | ||
455 | zr36060_write(ptr, ZR060_AF_LO, 0xff); | ||
456 | |||
457 | /* setup the variable jpeg tables */ | ||
458 | sum += zr36060_set_sof(ptr); | ||
459 | sum += zr36060_set_sos(ptr); | ||
460 | sum += zr36060_set_dri(ptr); | ||
461 | |||
462 | /* setup the fixed jpeg tables - maybe variable, though - | ||
463 | * (see table init section above) */ | ||
464 | sum += | ||
465 | zr36060_pushit(ptr, ZR060_DQT_IDX, sizeof(zr36060_dqt), | ||
466 | zr36060_dqt); | ||
467 | sum += | ||
468 | zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht), | ||
469 | zr36060_dht); | ||
470 | zr36060_write(ptr, ZR060_APP_IDX, 0xff); | ||
471 | zr36060_write(ptr, ZR060_APP_IDX + 1, 0xe0 + ptr->app.appn); | ||
472 | zr36060_write(ptr, ZR060_APP_IDX + 2, 0x00); | ||
473 | zr36060_write(ptr, ZR060_APP_IDX + 3, ptr->app.len + 2); | ||
474 | sum += zr36060_pushit(ptr, ZR060_APP_IDX + 4, 60, | ||
475 | ptr->app.data) + 4; | ||
476 | zr36060_write(ptr, ZR060_COM_IDX, 0xff); | ||
477 | zr36060_write(ptr, ZR060_COM_IDX + 1, 0xfe); | ||
478 | zr36060_write(ptr, ZR060_COM_IDX + 2, 0x00); | ||
479 | zr36060_write(ptr, ZR060_COM_IDX + 3, ptr->com.len + 2); | ||
480 | sum += zr36060_pushit(ptr, ZR060_COM_IDX + 4, 60, | ||
481 | ptr->com.data) + 4; | ||
482 | |||
483 | /* setup misc. data for compression (target code sizes) */ | ||
484 | |||
485 | /* size of compressed code to reach without header data */ | ||
486 | sum = ptr->real_code_vol - sum; | ||
487 | bitcnt = sum << 3; /* need the size in bits */ | ||
488 | |||
489 | tmp = bitcnt >> 16; | ||
490 | dprintk(3, | ||
491 | "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n", | ||
492 | ptr->name, sum, ptr->real_code_vol, bitcnt, tmp); | ||
493 | zr36060_write(ptr, ZR060_TCV_NET_HI, tmp >> 8); | ||
494 | zr36060_write(ptr, ZR060_TCV_NET_MH, tmp & 0xff); | ||
495 | tmp = bitcnt & 0xffff; | ||
496 | zr36060_write(ptr, ZR060_TCV_NET_ML, tmp >> 8); | ||
497 | zr36060_write(ptr, ZR060_TCV_NET_LO, tmp & 0xff); | ||
498 | |||
499 | bitcnt -= bitcnt >> 7; // bits without stuffing | ||
500 | bitcnt -= ((bitcnt * 5) >> 6); // bits without eob | ||
501 | |||
502 | tmp = bitcnt >> 16; | ||
503 | dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n", | ||
504 | ptr->name, bitcnt, tmp); | ||
505 | zr36060_write(ptr, ZR060_TCV_DATA_HI, tmp >> 8); | ||
506 | zr36060_write(ptr, ZR060_TCV_DATA_MH, tmp & 0xff); | ||
507 | tmp = bitcnt & 0xffff; | ||
508 | zr36060_write(ptr, ZR060_TCV_DATA_ML, tmp >> 8); | ||
509 | zr36060_write(ptr, ZR060_TCV_DATA_LO, tmp & 0xff); | ||
510 | |||
511 | /* JPEG markers to be included in the compressed stream */ | ||
512 | zr36060_write(ptr, ZR060_MER, | ||
513 | ZR060_MER_DQT | ZR060_MER_DHT | | ||
514 | ((ptr->com.len > 0) ? ZR060_MER_Com : 0) | | ||
515 | ((ptr->app.len > 0) ? ZR060_MER_App : 0)); | ||
516 | |||
517 | /* Setup the Video Frontend */ | ||
518 | /* Limit pixel range to 16..235 as per CCIR-601 */ | ||
519 | zr36060_write(ptr, ZR060_VCR, ZR060_VCR_Range); | ||
520 | |||
521 | } else { | ||
522 | dprintk(2, "%s: EXPANSION SETUP\n", ptr->name); | ||
523 | |||
524 | zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst); | ||
525 | |||
526 | /* 060 communicates with 067 in master mode */ | ||
527 | zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CodeMstr); | ||
528 | |||
529 | /* Decompression */ | ||
530 | zr36060_write(ptr, ZR060_CMR, 0); | ||
531 | |||
532 | /* Must be zero */ | ||
533 | zr36060_write(ptr, ZR060_MBZ, 0x00); | ||
534 | zr36060_write(ptr, ZR060_TCR_HI, 0x00); | ||
535 | zr36060_write(ptr, ZR060_TCR_LO, 0x00); | ||
536 | |||
537 | /* Disable all IRQs - no DataErr means autoreset */ | ||
538 | zr36060_write(ptr, ZR060_IMR, 0); | ||
539 | |||
540 | /* setup misc. data for expansion */ | ||
541 | zr36060_write(ptr, ZR060_MER, 0); | ||
542 | |||
543 | /* setup the fixed jpeg tables - maybe variable, though - | ||
544 | * (see table init section above) */ | ||
545 | zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht), | ||
546 | zr36060_dht); | ||
547 | |||
548 | /* Setup the Video Frontend */ | ||
549 | //zr36060_write(ptr, ZR060_VCR, ZR060_VCR_FIExt); | ||
550 | //this doesn't seem right and doesn't work... | ||
551 | zr36060_write(ptr, ZR060_VCR, ZR060_VCR_Range); | ||
552 | } | ||
553 | |||
554 | /* Load the tables */ | ||
555 | zr36060_write(ptr, ZR060_LOAD, | ||
556 | ZR060_LOAD_SyncRst | ZR060_LOAD_Load); | ||
557 | zr36060_wait_end(ptr); | ||
558 | dprintk(2, "%s: Status after table preload: 0x%02x\n", ptr->name, | ||
559 | ptr->status); | ||
560 | |||
561 | if (ptr->status & ZR060_CFSR_Busy) { | ||
562 | dprintk(1, KERN_ERR "%s: init aborted!\n", ptr->name); | ||
563 | return; // something is wrong, its timed out!!!! | ||
564 | } | ||
565 | } | ||
566 | |||
567 | /* ========================================================================= | ||
568 | CODEC API FUNCTIONS | ||
569 | |||
570 | this functions are accessed by the master via the API structure | ||
571 | ========================================================================= */ | ||
572 | |||
573 | /* set compression/expansion mode and launches codec - | ||
574 | this should be the last call from the master before starting processing */ | ||
575 | static int | ||
576 | zr36060_set_mode (struct videocodec *codec, | ||
577 | int mode) | ||
578 | { | ||
579 | struct zr36060 *ptr = (struct zr36060 *) codec->data; | ||
580 | |||
581 | dprintk(2, "%s: set_mode %d call\n", ptr->name, mode); | ||
582 | |||
583 | if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION)) | ||
584 | return -EINVAL; | ||
585 | |||
586 | ptr->mode = mode; | ||
587 | zr36060_init(ptr); | ||
588 | |||
589 | return 0; | ||
590 | } | ||
591 | |||
592 | /* set picture size (norm is ignored as the codec doesn't know about it) */ | ||
593 | static int | ||
594 | zr36060_set_video (struct videocodec *codec, | ||
595 | struct tvnorm *norm, | ||
596 | struct vfe_settings *cap, | ||
597 | struct vfe_polarity *pol) | ||
598 | { | ||
599 | struct zr36060 *ptr = (struct zr36060 *) codec->data; | ||
600 | u32 reg; | ||
601 | int size; | ||
602 | |||
603 | dprintk(2, "%s: set_video %d/%d-%dx%d (%%%d) call\n", ptr->name, | ||
604 | cap->x, cap->y, cap->width, cap->height, cap->decimation); | ||
605 | |||
606 | /* if () return -EINVAL; | ||
607 | * trust the master driver that it knows what it does - so | ||
608 | * we allow invalid startx/y and norm for now ... */ | ||
609 | ptr->width = cap->width / (cap->decimation & 0xff); | ||
610 | ptr->height = cap->height / (cap->decimation >> 8); | ||
611 | |||
612 | zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst); | ||
613 | |||
614 | /* Note that VSPol/HSPol bits in zr36060 have the opposite | ||
615 | * meaning of their zr360x7 counterparts with the same names | ||
616 | * N.b. for VSPol this is only true if FIVEdge = 0 (default, | ||
617 | * left unchanged here - in accordance with datasheet). | ||
618 | */ | ||
619 | reg = (!pol->vsync_pol ? ZR060_VPR_VSPol : 0) | ||
620 | | (!pol->hsync_pol ? ZR060_VPR_HSPol : 0) | ||
621 | | (pol->field_pol ? ZR060_VPR_FIPol : 0) | ||
622 | | (pol->blank_pol ? ZR060_VPR_BLPol : 0) | ||
623 | | (pol->subimg_pol ? ZR060_VPR_SImgPol : 0) | ||
624 | | (pol->poe_pol ? ZR060_VPR_PoePol : 0) | ||
625 | | (pol->pvalid_pol ? ZR060_VPR_PValPol : 0) | ||
626 | | (pol->vclk_pol ? ZR060_VPR_VCLKPol : 0); | ||
627 | zr36060_write(ptr, ZR060_VPR, reg); | ||
628 | |||
629 | reg = 0; | ||
630 | switch (cap->decimation & 0xff) { | ||
631 | default: | ||
632 | case 1: | ||
633 | break; | ||
634 | |||
635 | case 2: | ||
636 | reg |= ZR060_SR_HScale2; | ||
637 | break; | ||
638 | |||
639 | case 4: | ||
640 | reg |= ZR060_SR_HScale4; | ||
641 | break; | ||
642 | } | ||
643 | |||
644 | switch (cap->decimation >> 8) { | ||
645 | default: | ||
646 | case 1: | ||
647 | break; | ||
648 | |||
649 | case 2: | ||
650 | reg |= ZR060_SR_VScale; | ||
651 | break; | ||
652 | } | ||
653 | zr36060_write(ptr, ZR060_SR, reg); | ||
654 | |||
655 | zr36060_write(ptr, ZR060_BCR_Y, 0x00); | ||
656 | zr36060_write(ptr, ZR060_BCR_U, 0x80); | ||
657 | zr36060_write(ptr, ZR060_BCR_V, 0x80); | ||
658 | |||
659 | /* sync generator */ | ||
660 | |||
661 | reg = norm->Ht - 1; /* Vtotal */ | ||
662 | zr36060_write(ptr, ZR060_SGR_VTOTAL_HI, (reg >> 8) & 0xff); | ||
663 | zr36060_write(ptr, ZR060_SGR_VTOTAL_LO, (reg >> 0) & 0xff); | ||
664 | |||
665 | reg = norm->Wt - 1; /* Htotal */ | ||
666 | zr36060_write(ptr, ZR060_SGR_HTOTAL_HI, (reg >> 8) & 0xff); | ||
667 | zr36060_write(ptr, ZR060_SGR_HTOTAL_LO, (reg >> 0) & 0xff); | ||
668 | |||
669 | reg = 6 - 1; /* VsyncSize */ | ||
670 | zr36060_write(ptr, ZR060_SGR_VSYNC, reg); | ||
671 | |||
672 | //reg = 30 - 1; /* HsyncSize */ | ||
673 | ///*CP*/ reg = (zr->params.norm == 1 ? 57 : 68); | ||
674 | reg = 68; | ||
675 | zr36060_write(ptr, ZR060_SGR_HSYNC, reg); | ||
676 | |||
677 | reg = norm->VStart - 1; /* BVstart */ | ||
678 | zr36060_write(ptr, ZR060_SGR_BVSTART, reg); | ||
679 | |||
680 | reg += norm->Ha / 2; /* BVend */ | ||
681 | zr36060_write(ptr, ZR060_SGR_BVEND_HI, (reg >> 8) & 0xff); | ||
682 | zr36060_write(ptr, ZR060_SGR_BVEND_LO, (reg >> 0) & 0xff); | ||
683 | |||
684 | reg = norm->HStart - 1; /* BHstart */ | ||
685 | zr36060_write(ptr, ZR060_SGR_BHSTART, reg); | ||
686 | |||
687 | reg += norm->Wa; /* BHend */ | ||
688 | zr36060_write(ptr, ZR060_SGR_BHEND_HI, (reg >> 8) & 0xff); | ||
689 | zr36060_write(ptr, ZR060_SGR_BHEND_LO, (reg >> 0) & 0xff); | ||
690 | |||
691 | /* active area */ | ||
692 | reg = cap->y + norm->VStart; /* Vstart */ | ||
693 | zr36060_write(ptr, ZR060_AAR_VSTART_HI, (reg >> 8) & 0xff); | ||
694 | zr36060_write(ptr, ZR060_AAR_VSTART_LO, (reg >> 0) & 0xff); | ||
695 | |||
696 | reg += cap->height; /* Vend */ | ||
697 | zr36060_write(ptr, ZR060_AAR_VEND_HI, (reg >> 8) & 0xff); | ||
698 | zr36060_write(ptr, ZR060_AAR_VEND_LO, (reg >> 0) & 0xff); | ||
699 | |||
700 | reg = cap->x + norm->HStart; /* Hstart */ | ||
701 | zr36060_write(ptr, ZR060_AAR_HSTART_HI, (reg >> 8) & 0xff); | ||
702 | zr36060_write(ptr, ZR060_AAR_HSTART_LO, (reg >> 0) & 0xff); | ||
703 | |||
704 | reg += cap->width; /* Hend */ | ||
705 | zr36060_write(ptr, ZR060_AAR_HEND_HI, (reg >> 8) & 0xff); | ||
706 | zr36060_write(ptr, ZR060_AAR_HEND_LO, (reg >> 0) & 0xff); | ||
707 | |||
708 | /* subimage area */ | ||
709 | reg = norm->VStart - 4; /* SVstart */ | ||
710 | zr36060_write(ptr, ZR060_SWR_VSTART_HI, (reg >> 8) & 0xff); | ||
711 | zr36060_write(ptr, ZR060_SWR_VSTART_LO, (reg >> 0) & 0xff); | ||
712 | |||
713 | reg += norm->Ha / 2 + 8; /* SVend */ | ||
714 | zr36060_write(ptr, ZR060_SWR_VEND_HI, (reg >> 8) & 0xff); | ||
715 | zr36060_write(ptr, ZR060_SWR_VEND_LO, (reg >> 0) & 0xff); | ||
716 | |||
717 | reg = norm->HStart /*+ 64 */ - 4; /* SHstart */ | ||
718 | zr36060_write(ptr, ZR060_SWR_HSTART_HI, (reg >> 8) & 0xff); | ||
719 | zr36060_write(ptr, ZR060_SWR_HSTART_LO, (reg >> 0) & 0xff); | ||
720 | |||
721 | reg += norm->Wa + 8; /* SHend */ | ||
722 | zr36060_write(ptr, ZR060_SWR_HEND_HI, (reg >> 8) & 0xff); | ||
723 | zr36060_write(ptr, ZR060_SWR_HEND_LO, (reg >> 0) & 0xff); | ||
724 | |||
725 | size = ptr->width * ptr->height; | ||
726 | /* Target compressed field size in bits: */ | ||
727 | size = size * 16; /* uncompressed size in bits */ | ||
728 | /* (Ronald) by default, quality = 100 is a compression | ||
729 | * ratio 1:2. Setting low_bitrate (insmod option) sets | ||
730 | * it to 1:4 (instead of 1:2, zr36060 max) as limit because the | ||
731 | * buz can't handle more at decimation=1... Use low_bitrate if | ||
732 | * you have a Buz, unless you know what you're doing */ | ||
733 | size = size * cap->quality / (low_bitrate ? 400 : 200); | ||
734 | /* Lower limit (arbitrary, 1 KB) */ | ||
735 | if (size < 8192) | ||
736 | size = 8192; | ||
737 | /* Upper limit: 7/8 of the code buffers */ | ||
738 | if (size > ptr->total_code_vol * 7) | ||
739 | size = ptr->total_code_vol * 7; | ||
740 | |||
741 | ptr->real_code_vol = size >> 3; /* in bytes */ | ||
742 | |||
743 | /* the MBCVR is the *maximum* block volume, according to the | ||
744 | * JPEG ISO specs, this shouldn't be used, since that allows | ||
745 | * for the best encoding quality. So set it to it's max value */ | ||
746 | reg = ptr->max_block_vol; | ||
747 | zr36060_write(ptr, ZR060_MBCVR, reg); | ||
748 | |||
749 | return 0; | ||
750 | } | ||
751 | |||
752 | /* additional control functions */ | ||
753 | static int | ||
754 | zr36060_control (struct videocodec *codec, | ||
755 | int type, | ||
756 | int size, | ||
757 | void *data) | ||
758 | { | ||
759 | struct zr36060 *ptr = (struct zr36060 *) codec->data; | ||
760 | int *ival = (int *) data; | ||
761 | |||
762 | dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type, | ||
763 | size); | ||
764 | |||
765 | switch (type) { | ||
766 | case CODEC_G_STATUS: /* get last status */ | ||
767 | if (size != sizeof(int)) | ||
768 | return -EFAULT; | ||
769 | zr36060_read_status(ptr); | ||
770 | *ival = ptr->status; | ||
771 | break; | ||
772 | |||
773 | case CODEC_G_CODEC_MODE: | ||
774 | if (size != sizeof(int)) | ||
775 | return -EFAULT; | ||
776 | *ival = CODEC_MODE_BJPG; | ||
777 | break; | ||
778 | |||
779 | case CODEC_S_CODEC_MODE: | ||
780 | if (size != sizeof(int)) | ||
781 | return -EFAULT; | ||
782 | if (*ival != CODEC_MODE_BJPG) | ||
783 | return -EINVAL; | ||
784 | /* not needed, do nothing */ | ||
785 | return 0; | ||
786 | |||
787 | case CODEC_G_VFE: | ||
788 | case CODEC_S_VFE: | ||
789 | /* not needed, do nothing */ | ||
790 | return 0; | ||
791 | |||
792 | case CODEC_S_MMAP: | ||
793 | /* not available, give an error */ | ||
794 | return -ENXIO; | ||
795 | |||
796 | case CODEC_G_JPEG_TDS_BYTE: /* get target volume in byte */ | ||
797 | if (size != sizeof(int)) | ||
798 | return -EFAULT; | ||
799 | *ival = ptr->total_code_vol; | ||
800 | break; | ||
801 | |||
802 | case CODEC_S_JPEG_TDS_BYTE: /* get target volume in byte */ | ||
803 | if (size != sizeof(int)) | ||
804 | return -EFAULT; | ||
805 | ptr->total_code_vol = *ival; | ||
806 | ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3; | ||
807 | break; | ||
808 | |||
809 | case CODEC_G_JPEG_SCALE: /* get scaling factor */ | ||
810 | if (size != sizeof(int)) | ||
811 | return -EFAULT; | ||
812 | *ival = zr36060_read_scalefactor(ptr); | ||
813 | break; | ||
814 | |||
815 | case CODEC_S_JPEG_SCALE: /* set scaling factor */ | ||
816 | if (size != sizeof(int)) | ||
817 | return -EFAULT; | ||
818 | ptr->scalefact = *ival; | ||
819 | break; | ||
820 | |||
821 | case CODEC_G_JPEG_APP_DATA: { /* get appn marker data */ | ||
822 | struct jpeg_app_marker *app = data; | ||
823 | |||
824 | if (size != sizeof(struct jpeg_app_marker)) | ||
825 | return -EFAULT; | ||
826 | |||
827 | *app = ptr->app; | ||
828 | break; | ||
829 | } | ||
830 | |||
831 | case CODEC_S_JPEG_APP_DATA: { /* set appn marker data */ | ||
832 | struct jpeg_app_marker *app = data; | ||
833 | |||
834 | if (size != sizeof(struct jpeg_app_marker)) | ||
835 | return -EFAULT; | ||
836 | |||
837 | ptr->app = *app; | ||
838 | break; | ||
839 | } | ||
840 | |||
841 | case CODEC_G_JPEG_COM_DATA: { /* get comment marker data */ | ||
842 | struct jpeg_com_marker *com = data; | ||
843 | |||
844 | if (size != sizeof(struct jpeg_com_marker)) | ||
845 | return -EFAULT; | ||
846 | |||
847 | *com = ptr->com; | ||
848 | break; | ||
849 | } | ||
850 | |||
851 | case CODEC_S_JPEG_COM_DATA: { /* set comment marker data */ | ||
852 | struct jpeg_com_marker *com = data; | ||
853 | |||
854 | if (size != sizeof(struct jpeg_com_marker)) | ||
855 | return -EFAULT; | ||
856 | |||
857 | ptr->com = *com; | ||
858 | break; | ||
859 | } | ||
860 | |||
861 | default: | ||
862 | return -EINVAL; | ||
863 | } | ||
864 | |||
865 | return size; | ||
866 | } | ||
867 | |||
868 | /* ========================================================================= | ||
869 | Exit and unregister function: | ||
870 | |||
871 | Deinitializes Zoran's JPEG processor | ||
872 | ========================================================================= */ | ||
873 | |||
874 | static int | ||
875 | zr36060_unset (struct videocodec *codec) | ||
876 | { | ||
877 | struct zr36060 *ptr = codec->data; | ||
878 | |||
879 | if (ptr) { | ||
880 | /* do wee need some codec deinit here, too ???? */ | ||
881 | |||
882 | dprintk(1, "%s: finished codec #%d\n", ptr->name, | ||
883 | ptr->num); | ||
884 | kfree(ptr); | ||
885 | codec->data = NULL; | ||
886 | |||
887 | zr36060_codecs--; | ||
888 | return 0; | ||
889 | } | ||
890 | |||
891 | return -EFAULT; | ||
892 | } | ||
893 | |||
894 | /* ========================================================================= | ||
895 | Setup and registry function: | ||
896 | |||
897 | Initializes Zoran's JPEG processor | ||
898 | |||
899 | Also sets pixel size, average code size, mode (compr./decompr.) | ||
900 | (the given size is determined by the processor with the video interface) | ||
901 | ========================================================================= */ | ||
902 | |||
903 | static int | ||
904 | zr36060_setup (struct videocodec *codec) | ||
905 | { | ||
906 | struct zr36060 *ptr; | ||
907 | int res; | ||
908 | |||
909 | dprintk(2, "zr36060: initializing MJPEG subsystem #%d.\n", | ||
910 | zr36060_codecs); | ||
911 | |||
912 | if (zr36060_codecs == MAX_CODECS) { | ||
913 | dprintk(1, | ||
914 | KERN_ERR "zr36060: Can't attach more codecs!\n"); | ||
915 | return -ENOSPC; | ||
916 | } | ||
917 | //mem structure init | ||
918 | codec->data = ptr = kzalloc(sizeof(struct zr36060), GFP_KERNEL); | ||
919 | if (NULL == ptr) { | ||
920 | dprintk(1, KERN_ERR "zr36060: Can't get enough memory!\n"); | ||
921 | return -ENOMEM; | ||
922 | } | ||
923 | |||
924 | snprintf(ptr->name, sizeof(ptr->name), "zr36060[%d]", | ||
925 | zr36060_codecs); | ||
926 | ptr->num = zr36060_codecs++; | ||
927 | ptr->codec = codec; | ||
928 | |||
929 | //testing | ||
930 | res = zr36060_basic_test(ptr); | ||
931 | if (res < 0) { | ||
932 | zr36060_unset(codec); | ||
933 | return res; | ||
934 | } | ||
935 | //final setup | ||
936 | memcpy(ptr->h_samp_ratio, zr36060_decimation_h, 8); | ||
937 | memcpy(ptr->v_samp_ratio, zr36060_decimation_v, 8); | ||
938 | |||
939 | ptr->bitrate_ctrl = 0; /* 0 or 1 - fixed file size flag | ||
940 | * (what is the difference?) */ | ||
941 | ptr->mode = CODEC_DO_COMPRESSION; | ||
942 | ptr->width = 384; | ||
943 | ptr->height = 288; | ||
944 | ptr->total_code_vol = 16000; /* CHECKME */ | ||
945 | ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3; | ||
946 | ptr->max_block_vol = 240; /* CHECKME, was 120 is 240 */ | ||
947 | ptr->scalefact = 0x100; | ||
948 | ptr->dri = 1; /* CHECKME, was 8 is 1 */ | ||
949 | |||
950 | /* by default, no COM or APP markers - app should set those */ | ||
951 | ptr->com.len = 0; | ||
952 | ptr->app.appn = 0; | ||
953 | ptr->app.len = 0; | ||
954 | |||
955 | zr36060_init(ptr); | ||
956 | |||
957 | dprintk(1, KERN_INFO "%s: codec attached and running\n", | ||
958 | ptr->name); | ||
959 | |||
960 | return 0; | ||
961 | } | ||
962 | |||
963 | static const struct videocodec zr36060_codec = { | ||
964 | .owner = THIS_MODULE, | ||
965 | .name = "zr36060", | ||
966 | .magic = 0L, // magic not used | ||
967 | .flags = | ||
968 | CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER | | ||
969 | CODEC_FLAG_DECODER | CODEC_FLAG_VFE, | ||
970 | .type = CODEC_TYPE_ZR36060, | ||
971 | .setup = zr36060_setup, // functionality | ||
972 | .unset = zr36060_unset, | ||
973 | .set_mode = zr36060_set_mode, | ||
974 | .set_video = zr36060_set_video, | ||
975 | .control = zr36060_control, | ||
976 | // others are not used | ||
977 | }; | ||
978 | |||
979 | /* ========================================================================= | ||
980 | HOOK IN DRIVER AS KERNEL MODULE | ||
981 | ========================================================================= */ | ||
982 | |||
983 | static int __init | ||
984 | zr36060_init_module (void) | ||
985 | { | ||
986 | //dprintk(1, "zr36060 driver %s\n",ZR060_VERSION); | ||
987 | zr36060_codecs = 0; | ||
988 | return videocodec_register(&zr36060_codec); | ||
989 | } | ||
990 | |||
991 | static void __exit | ||
992 | zr36060_cleanup_module (void) | ||
993 | { | ||
994 | if (zr36060_codecs) { | ||
995 | dprintk(1, | ||
996 | "zr36060: something's wrong - %d codecs left somehow.\n", | ||
997 | zr36060_codecs); | ||
998 | } | ||
999 | |||
1000 | /* however, we can't just stay alive */ | ||
1001 | videocodec_unregister(&zr36060_codec); | ||
1002 | } | ||
1003 | |||
1004 | module_init(zr36060_init_module); | ||
1005 | module_exit(zr36060_cleanup_module); | ||
1006 | |||
1007 | MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@skynet.be>"); | ||
1008 | MODULE_DESCRIPTION("Driver module for ZR36060 jpeg processors " | ||
1009 | ZR060_VERSION); | ||
1010 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/zoran/zr36060.h b/drivers/media/video/zoran/zr36060.h deleted file mode 100644 index 914ffa4ad8d3..000000000000 --- a/drivers/media/video/zoran/zr36060.h +++ /dev/null | |||
@@ -1,220 +0,0 @@ | |||
1 | /* | ||
2 | * Zoran ZR36060 basic configuration functions - header file | ||
3 | * | ||
4 | * Copyright (C) 2002 Laurent Pinchart <laurent.pinchart@skynet.be> | ||
5 | * | ||
6 | * $Id: zr36060.h,v 1.1.1.1.2.3 2003/01/14 21:18:47 rbultje Exp $ | ||
7 | * | ||
8 | * ------------------------------------------------------------------------ | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | * | ||
24 | * ------------------------------------------------------------------------ | ||
25 | */ | ||
26 | |||
27 | #ifndef ZR36060_H | ||
28 | #define ZR36060_H | ||
29 | |||
30 | #include "videocodec.h" | ||
31 | |||
32 | /* data stored for each zoran jpeg codec chip */ | ||
33 | struct zr36060 { | ||
34 | char name[32]; | ||
35 | int num; | ||
36 | /* io datastructure */ | ||
37 | struct videocodec *codec; | ||
38 | // last coder status | ||
39 | __u8 status; | ||
40 | // actual coder setup | ||
41 | int mode; | ||
42 | |||
43 | __u16 width; | ||
44 | __u16 height; | ||
45 | |||
46 | __u16 bitrate_ctrl; | ||
47 | |||
48 | __u32 total_code_vol; | ||
49 | __u32 real_code_vol; | ||
50 | __u16 max_block_vol; | ||
51 | |||
52 | __u8 h_samp_ratio[8]; | ||
53 | __u8 v_samp_ratio[8]; | ||
54 | __u16 scalefact; | ||
55 | __u16 dri; | ||
56 | |||
57 | /* app/com marker data */ | ||
58 | struct jpeg_app_marker app; | ||
59 | struct jpeg_com_marker com; | ||
60 | }; | ||
61 | |||
62 | /* ZR36060 register addresses */ | ||
63 | #define ZR060_LOAD 0x000 | ||
64 | #define ZR060_CFSR 0x001 | ||
65 | #define ZR060_CIR 0x002 | ||
66 | #define ZR060_CMR 0x003 | ||
67 | #define ZR060_MBZ 0x004 | ||
68 | #define ZR060_MBCVR 0x005 | ||
69 | #define ZR060_MER 0x006 | ||
70 | #define ZR060_IMR 0x007 | ||
71 | #define ZR060_ISR 0x008 | ||
72 | #define ZR060_TCV_NET_HI 0x009 | ||
73 | #define ZR060_TCV_NET_MH 0x00a | ||
74 | #define ZR060_TCV_NET_ML 0x00b | ||
75 | #define ZR060_TCV_NET_LO 0x00c | ||
76 | #define ZR060_TCV_DATA_HI 0x00d | ||
77 | #define ZR060_TCV_DATA_MH 0x00e | ||
78 | #define ZR060_TCV_DATA_ML 0x00f | ||
79 | #define ZR060_TCV_DATA_LO 0x010 | ||
80 | #define ZR060_SF_HI 0x011 | ||
81 | #define ZR060_SF_LO 0x012 | ||
82 | #define ZR060_AF_HI 0x013 | ||
83 | #define ZR060_AF_M 0x014 | ||
84 | #define ZR060_AF_LO 0x015 | ||
85 | #define ZR060_ACV_HI 0x016 | ||
86 | #define ZR060_ACV_MH 0x017 | ||
87 | #define ZR060_ACV_ML 0x018 | ||
88 | #define ZR060_ACV_LO 0x019 | ||
89 | #define ZR060_ACT_HI 0x01a | ||
90 | #define ZR060_ACT_MH 0x01b | ||
91 | #define ZR060_ACT_ML 0x01c | ||
92 | #define ZR060_ACT_LO 0x01d | ||
93 | #define ZR060_ACV_TRUN_HI 0x01e | ||
94 | #define ZR060_ACV_TRUN_MH 0x01f | ||
95 | #define ZR060_ACV_TRUN_ML 0x020 | ||
96 | #define ZR060_ACV_TRUN_LO 0x021 | ||
97 | #define ZR060_IDR_DEV 0x022 | ||
98 | #define ZR060_IDR_REV 0x023 | ||
99 | #define ZR060_TCR_HI 0x024 | ||
100 | #define ZR060_TCR_LO 0x025 | ||
101 | #define ZR060_VCR 0x030 | ||
102 | #define ZR060_VPR 0x031 | ||
103 | #define ZR060_SR 0x032 | ||
104 | #define ZR060_BCR_Y 0x033 | ||
105 | #define ZR060_BCR_U 0x034 | ||
106 | #define ZR060_BCR_V 0x035 | ||
107 | #define ZR060_SGR_VTOTAL_HI 0x036 | ||
108 | #define ZR060_SGR_VTOTAL_LO 0x037 | ||
109 | #define ZR060_SGR_HTOTAL_HI 0x038 | ||
110 | #define ZR060_SGR_HTOTAL_LO 0x039 | ||
111 | #define ZR060_SGR_VSYNC 0x03a | ||
112 | #define ZR060_SGR_HSYNC 0x03b | ||
113 | #define ZR060_SGR_BVSTART 0x03c | ||
114 | #define ZR060_SGR_BHSTART 0x03d | ||
115 | #define ZR060_SGR_BVEND_HI 0x03e | ||
116 | #define ZR060_SGR_BVEND_LO 0x03f | ||
117 | #define ZR060_SGR_BHEND_HI 0x040 | ||
118 | #define ZR060_SGR_BHEND_LO 0x041 | ||
119 | #define ZR060_AAR_VSTART_HI 0x042 | ||
120 | #define ZR060_AAR_VSTART_LO 0x043 | ||
121 | #define ZR060_AAR_VEND_HI 0x044 | ||
122 | #define ZR060_AAR_VEND_LO 0x045 | ||
123 | #define ZR060_AAR_HSTART_HI 0x046 | ||
124 | #define ZR060_AAR_HSTART_LO 0x047 | ||
125 | #define ZR060_AAR_HEND_HI 0x048 | ||
126 | #define ZR060_AAR_HEND_LO 0x049 | ||
127 | #define ZR060_SWR_VSTART_HI 0x04a | ||
128 | #define ZR060_SWR_VSTART_LO 0x04b | ||
129 | #define ZR060_SWR_VEND_HI 0x04c | ||
130 | #define ZR060_SWR_VEND_LO 0x04d | ||
131 | #define ZR060_SWR_HSTART_HI 0x04e | ||
132 | #define ZR060_SWR_HSTART_LO 0x04f | ||
133 | #define ZR060_SWR_HEND_HI 0x050 | ||
134 | #define ZR060_SWR_HEND_LO 0x051 | ||
135 | |||
136 | #define ZR060_SOF_IDX 0x060 | ||
137 | #define ZR060_SOS_IDX 0x07a | ||
138 | #define ZR060_DRI_IDX 0x0c0 | ||
139 | #define ZR060_DQT_IDX 0x0cc | ||
140 | #define ZR060_DHT_IDX 0x1d4 | ||
141 | #define ZR060_APP_IDX 0x380 | ||
142 | #define ZR060_COM_IDX 0x3c0 | ||
143 | |||
144 | /* ZR36060 LOAD register bits */ | ||
145 | |||
146 | #define ZR060_LOAD_Load (1 << 7) | ||
147 | #define ZR060_LOAD_SyncRst (1 << 0) | ||
148 | |||
149 | /* ZR36060 Code FIFO Status register bits */ | ||
150 | |||
151 | #define ZR060_CFSR_Busy (1 << 7) | ||
152 | #define ZR060_CFSR_CBusy (1 << 2) | ||
153 | #define ZR060_CFSR_CFIFO (3 << 0) | ||
154 | |||
155 | /* ZR36060 Code Interface register */ | ||
156 | |||
157 | #define ZR060_CIR_Code16 (1 << 7) | ||
158 | #define ZR060_CIR_Endian (1 << 6) | ||
159 | #define ZR060_CIR_CFIS (1 << 2) | ||
160 | #define ZR060_CIR_CodeMstr (1 << 0) | ||
161 | |||
162 | /* ZR36060 Codec Mode register */ | ||
163 | |||
164 | #define ZR060_CMR_Comp (1 << 7) | ||
165 | #define ZR060_CMR_ATP (1 << 6) | ||
166 | #define ZR060_CMR_Pass2 (1 << 5) | ||
167 | #define ZR060_CMR_TLM (1 << 4) | ||
168 | #define ZR060_CMR_BRB (1 << 2) | ||
169 | #define ZR060_CMR_FSF (1 << 1) | ||
170 | |||
171 | /* ZR36060 Markers Enable register */ | ||
172 | |||
173 | #define ZR060_MER_App (1 << 7) | ||
174 | #define ZR060_MER_Com (1 << 6) | ||
175 | #define ZR060_MER_DRI (1 << 5) | ||
176 | #define ZR060_MER_DQT (1 << 4) | ||
177 | #define ZR060_MER_DHT (1 << 3) | ||
178 | |||
179 | /* ZR36060 Interrupt Mask register */ | ||
180 | |||
181 | #define ZR060_IMR_EOAV (1 << 3) | ||
182 | #define ZR060_IMR_EOI (1 << 2) | ||
183 | #define ZR060_IMR_End (1 << 1) | ||
184 | #define ZR060_IMR_DataErr (1 << 0) | ||
185 | |||
186 | /* ZR36060 Interrupt Status register */ | ||
187 | |||
188 | #define ZR060_ISR_ProCnt (3 << 6) | ||
189 | #define ZR060_ISR_EOAV (1 << 3) | ||
190 | #define ZR060_ISR_EOI (1 << 2) | ||
191 | #define ZR060_ISR_End (1 << 1) | ||
192 | #define ZR060_ISR_DataErr (1 << 0) | ||
193 | |||
194 | /* ZR36060 Video Control register */ | ||
195 | |||
196 | #define ZR060_VCR_Video8 (1 << 7) | ||
197 | #define ZR060_VCR_Range (1 << 6) | ||
198 | #define ZR060_VCR_FIDet (1 << 3) | ||
199 | #define ZR060_VCR_FIVedge (1 << 2) | ||
200 | #define ZR060_VCR_FIExt (1 << 1) | ||
201 | #define ZR060_VCR_SyncMstr (1 << 0) | ||
202 | |||
203 | /* ZR36060 Video Polarity register */ | ||
204 | |||
205 | #define ZR060_VPR_VCLKPol (1 << 7) | ||
206 | #define ZR060_VPR_PValPol (1 << 6) | ||
207 | #define ZR060_VPR_PoePol (1 << 5) | ||
208 | #define ZR060_VPR_SImgPol (1 << 4) | ||
209 | #define ZR060_VPR_BLPol (1 << 3) | ||
210 | #define ZR060_VPR_FIPol (1 << 2) | ||
211 | #define ZR060_VPR_HSPol (1 << 1) | ||
212 | #define ZR060_VPR_VSPol (1 << 0) | ||
213 | |||
214 | /* ZR36060 Scaling register */ | ||
215 | |||
216 | #define ZR060_SR_VScale (1 << 2) | ||
217 | #define ZR060_SR_HScale2 (1 << 0) | ||
218 | #define ZR060_SR_HScale4 (2 << 0) | ||
219 | |||
220 | #endif /*fndef ZR36060_H */ | ||