blob: 07f2bdfef4ee95d6127f69d8d84ffa3868d685ba [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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
Linus Torvalds1da177e2005-04-16 15:20:36 -070047#include <linux/version.h>
48#include <linux/init.h>
49#include <linux/module.h>
50#include <linux/delay.h>
51#include <linux/slab.h>
52#include <linux/pci.h>
53#include <linux/vmalloc.h>
54#include <linux/wait.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
56#include <linux/interrupt.h>
57#include <linux/i2c.h>
58#include <linux/i2c-algo-bit.h>
59
60#include <linux/spinlock.h>
61#define MAP_NR(x) virt_to_page(x)
Linus Torvalds1da177e2005-04-16 15:20:36 -070062#define ZORAN_VID_TYPE ( \
63 VID_TYPE_CAPTURE | \
64 VID_TYPE_OVERLAY | \
65 VID_TYPE_CLIPPING | \
66 VID_TYPE_FRAMERAM | \
67 VID_TYPE_SCALES | \
68 VID_TYPE_MJPEG_DECODER | \
69 VID_TYPE_MJPEG_ENCODER \
70 )
71
72#include <linux/videodev.h>
Mauro Carvalho Chehab5e87efa2006-06-05 10:26:32 -030073#include <media/v4l2-common.h>
Hans Verkuil35ea11f2008-07-20 08:12:02 -030074#include <media/v4l2-ioctl.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070075#include "videocodec.h"
76
Harvey Harrison9a6ab762008-05-16 11:20:25 -070077#include <asm/byteorder.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070078#include <asm/io.h>
79#include <asm/uaccess.h>
80#include <linux/proc_fs.h>
81
82#include <linux/video_decoder.h>
83#include <linux/video_encoder.h>
Ingo Molnar384c3682006-03-22 03:54:16 -030084#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070085#include "zoran.h"
86#include "zoran_device.h"
87#include "zoran_card.h"
88
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 /* we declare some card type definitions here, they mean
90 * the same as the v4l1 ZORAN_VID_TYPE above, except it's v4l2 */
91#define ZORAN_V4L2_VID_FLAGS ( \
92 V4L2_CAP_STREAMING |\
93 V4L2_CAP_VIDEO_CAPTURE |\
94 V4L2_CAP_VIDEO_OUTPUT |\
95 V4L2_CAP_VIDEO_OVERLAY \
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -030096 )
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
Linus Torvalds1da177e2005-04-16 15:20:36 -070098
Mauro Carvalho Chehab17de9a42008-04-15 18:11:50 -030099#if defined(CONFIG_VIDEO_V4L1_COMPAT)
Trent Piepho603d6f22007-07-17 18:29:44 -0300100#define ZFMT(pal, fcc, cs) \
101 .palette = (pal), .fourcc = (fcc), .colorspace = (cs)
Trent Piepho603d6f22007-07-17 18:29:44 -0300102#else
103#define ZFMT(pal, fcc, cs) \
Mauro Carvalho Chehab17de9a42008-04-15 18:11:50 -0300104 .fourcc = (fcc), .colorspace = (cs)
Trent Piepho603d6f22007-07-17 18:29:44 -0300105#endif
106
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107const struct zoran_format zoran_formats[] = {
108 {
Trent Piepho603d6f22007-07-17 18:29:44 -0300109 .name = "15-bit RGB LE",
110 ZFMT(VIDEO_PALETTE_RGB555,
111 V4L2_PIX_FMT_RGB555, V4L2_COLORSPACE_SRGB),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112 .depth = 15,
113 .flags = ZORAN_FORMAT_CAPTURE |
114 ZORAN_FORMAT_OVERLAY,
Trent Piepho603d6f22007-07-17 18:29:44 -0300115 .vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif|
116 ZR36057_VFESPFR_LittleEndian,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117 }, {
Trent Piepho603d6f22007-07-17 18:29:44 -0300118 .name = "15-bit RGB BE",
119 ZFMT(-1,
120 V4L2_PIX_FMT_RGB555X, V4L2_COLORSPACE_SRGB),
121 .depth = 15,
122 .flags = ZORAN_FORMAT_CAPTURE |
123 ZORAN_FORMAT_OVERLAY,
124 .vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif,
125 }, {
126 .name = "16-bit RGB LE",
127 ZFMT(VIDEO_PALETTE_RGB565,
128 V4L2_PIX_FMT_RGB565, V4L2_COLORSPACE_SRGB),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129 .depth = 16,
130 .flags = ZORAN_FORMAT_CAPTURE |
131 ZORAN_FORMAT_OVERLAY,
Trent Piepho603d6f22007-07-17 18:29:44 -0300132 .vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif|
133 ZR36057_VFESPFR_LittleEndian,
134 }, {
135 .name = "16-bit RGB BE",
136 ZFMT(-1,
Jean Delvarea30ee3c2008-09-05 10:39:27 -0300137 V4L2_PIX_FMT_RGB565X, V4L2_COLORSPACE_SRGB),
Trent Piepho603d6f22007-07-17 18:29:44 -0300138 .depth = 16,
139 .flags = ZORAN_FORMAT_CAPTURE |
140 ZORAN_FORMAT_OVERLAY,
141 .vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142 }, {
143 .name = "24-bit RGB",
Trent Piepho603d6f22007-07-17 18:29:44 -0300144 ZFMT(VIDEO_PALETTE_RGB24,
145 V4L2_PIX_FMT_BGR24, V4L2_COLORSPACE_SRGB),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 .depth = 24,
147 .flags = ZORAN_FORMAT_CAPTURE |
148 ZORAN_FORMAT_OVERLAY,
Trent Piepho603d6f22007-07-17 18:29:44 -0300149 .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_Pack24,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150 }, {
Trent Piepho603d6f22007-07-17 18:29:44 -0300151 .name = "32-bit RGB LE",
152 ZFMT(VIDEO_PALETTE_RGB32,
153 V4L2_PIX_FMT_BGR32, V4L2_COLORSPACE_SRGB),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154 .depth = 32,
155 .flags = ZORAN_FORMAT_CAPTURE |
156 ZORAN_FORMAT_OVERLAY,
Trent Piepho603d6f22007-07-17 18:29:44 -0300157 .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_LittleEndian,
158 }, {
159 .name = "32-bit RGB BE",
160 ZFMT(-1,
161 V4L2_PIX_FMT_RGB32, V4L2_COLORSPACE_SRGB),
162 .depth = 32,
163 .flags = ZORAN_FORMAT_CAPTURE |
164 ZORAN_FORMAT_OVERLAY,
165 .vfespfr = ZR36057_VFESPFR_RGB888,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 }, {
167 .name = "4:2:2, packed, YUYV",
Trent Piepho603d6f22007-07-17 18:29:44 -0300168 ZFMT(VIDEO_PALETTE_YUV422,
169 V4L2_PIX_FMT_YUYV, V4L2_COLORSPACE_SMPTE170M),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 .depth = 16,
171 .flags = ZORAN_FORMAT_CAPTURE |
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300172 ZORAN_FORMAT_OVERLAY,
Trent Piepho603d6f22007-07-17 18:29:44 -0300173 .vfespfr = ZR36057_VFESPFR_YUV422,
174 }, {
175 .name = "4:2:2, packed, UYVY",
176 ZFMT(VIDEO_PALETTE_UYVY,
177 V4L2_PIX_FMT_UYVY, V4L2_COLORSPACE_SMPTE170M),
178 .depth = 16,
179 .flags = ZORAN_FORMAT_CAPTURE |
180 ZORAN_FORMAT_OVERLAY,
181 .vfespfr = ZR36057_VFESPFR_YUV422|ZR36057_VFESPFR_LittleEndian,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 }, {
183 .name = "Hardware-encoded Motion-JPEG",
Trent Piepho603d6f22007-07-17 18:29:44 -0300184 ZFMT(-1,
185 V4L2_PIX_FMT_MJPEG, V4L2_COLORSPACE_SMPTE170M),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186 .depth = 0,
187 .flags = ZORAN_FORMAT_CAPTURE |
188 ZORAN_FORMAT_PLAYBACK |
189 ZORAN_FORMAT_COMPRESSED,
190 }
191};
Trent Piepho603d6f22007-07-17 18:29:44 -0300192#define NUM_FORMATS ARRAY_SIZE(zoran_formats)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -0300194static int lock_norm; /* 0 = default 1 = Don't change TV standard (norm) */
Trent Piepho60e3cac2007-07-17 18:29:42 -0300195module_param(lock_norm, int, 0644);
196MODULE_PARM_DESC(lock_norm, "Prevent norm changes (1 = ignore, >1 = fail)");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198 /* small helper function for calculating buffersizes for v4l2
199 * we calculate the nearest higher power-of-two, which
200 * will be the recommended buffersize */
201static __u32
202zoran_v4l2_calc_bufsize (struct zoran_jpg_settings *settings)
203{
204 __u8 div = settings->VerDcm * settings->HorDcm * settings->TmpDcm;
205 __u32 num = (1024 * 512) / (div);
206 __u32 result = 2;
207
208 num--;
209 while (num) {
210 num >>= 1;
211 result <<= 1;
212 }
213
214 if (result > jpg_bufsize)
215 return jpg_bufsize;
216 if (result < 8192)
217 return 8192;
218 return result;
219}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220
221/* forward references */
222static void v4l_fbuffer_free(struct file *file);
223static void jpg_fbuffer_free(struct file *file);
224
225/*
226 * Allocate the V4L grab buffers
227 *
228 * These have to be pysically contiguous.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229 */
230
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231static int
232v4l_fbuffer_alloc (struct file *file)
233{
234 struct zoran_fh *fh = file->private_data;
235 struct zoran *zr = fh->zr;
236 int i, off;
237 unsigned char *mem;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239 for (i = 0; i < fh->v4l_buffers.num_buffers; i++) {
240 if (fh->v4l_buffers.buffer[i].fbuffer)
241 dprintk(2,
242 KERN_WARNING
Hans Verkuilb80696b2009-02-18 13:20:05 -0300243 "%s: v4l_fbuffer_alloc() - buffer %d already allocated!?\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244 ZR_DEVNAME(zr), i);
245
246 //udelay(20);
Hans Verkuilb80696b2009-02-18 13:20:05 -0300247 mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL);
248 if (!mem) {
249 dprintk(1,
250 KERN_ERR
251 "%s: v4l_fbuffer_alloc() - kmalloc for V4L buf %d failed\n",
252 ZR_DEVNAME(zr), i);
253 v4l_fbuffer_free(file);
254 return -ENOBUFS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255 }
Hans Verkuilb80696b2009-02-18 13:20:05 -0300256 fh->v4l_buffers.buffer[i].fbuffer = mem;
257 fh->v4l_buffers.buffer[i].fbuffer_phys =
258 virt_to_phys(mem);
259 fh->v4l_buffers.buffer[i].fbuffer_bus =
260 virt_to_bus(mem);
261 for (off = 0; off < fh->v4l_buffers.buffer_size;
262 off += PAGE_SIZE)
263 SetPageReserved(MAP_NR(mem + off));
264 dprintk(4,
265 KERN_INFO
266 "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%lx)\n",
267 ZR_DEVNAME(zr), i, (unsigned long) mem,
268 virt_to_bus(mem));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269 }
270
271 fh->v4l_buffers.allocated = 1;
272
273 return 0;
274}
275
276/* free the V4L grab buffers */
277static void
278v4l_fbuffer_free (struct file *file)
279{
280 struct zoran_fh *fh = file->private_data;
281 struct zoran *zr = fh->zr;
282 int i, off;
283 unsigned char *mem;
284
285 dprintk(4, KERN_INFO "%s: v4l_fbuffer_free()\n", ZR_DEVNAME(zr));
286
287 for (i = 0; i < fh->v4l_buffers.num_buffers; i++) {
288 if (!fh->v4l_buffers.buffer[i].fbuffer)
289 continue;
290
Hans Verkuilb80696b2009-02-18 13:20:05 -0300291 mem = fh->v4l_buffers.buffer[i].fbuffer;
292 for (off = 0; off < fh->v4l_buffers.buffer_size;
293 off += PAGE_SIZE)
294 ClearPageReserved(MAP_NR(mem + off));
295 kfree((void *) fh->v4l_buffers.buffer[i].fbuffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296 fh->v4l_buffers.buffer[i].fbuffer = NULL;
297 }
298
299 fh->v4l_buffers.allocated = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300}
301
302/*
303 * Allocate the MJPEG grab buffers.
304 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305 * If a Natoma chipset is present and this is a revision 1 zr36057,
306 * each MJPEG buffer needs to be physically contiguous.
307 * (RJ: This statement is from Dave Perks' original driver,
308 * I could never check it because I have a zr36067)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309 *
310 * RJ: The contents grab buffers needs never be accessed in the driver.
311 * Therefore there is no need to allocate them with vmalloc in order
312 * to get a contiguous virtual memory space.
313 * I don't understand why many other drivers first allocate them with
314 * vmalloc (which uses internally also get_zeroed_page, but delivers you
315 * virtual addresses) and then again have to make a lot of efforts
316 * to get the physical address.
317 *
318 * Ben Capper:
319 * On big-endian architectures (such as ppc) some extra steps
320 * are needed. When reading and writing to the stat_com array
321 * and fragment buffers, the device expects to see little-
322 * endian values. The use of cpu_to_le32() and le32_to_cpu()
323 * in this function (and one or two others in zoran_device.c)
324 * ensure that these values are always stored in little-endian
325 * form, regardless of architecture. The zr36057 does Very Bad
326 * Things on big endian architectures if the stat_com array
327 * and fragment buffers are not little-endian.
328 */
329
330static int
331jpg_fbuffer_alloc (struct file *file)
332{
333 struct zoran_fh *fh = file->private_data;
334 struct zoran *zr = fh->zr;
335 int i, j, off;
336 unsigned long mem;
337
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338 for (i = 0; i < fh->jpg_buffers.num_buffers; i++) {
339 if (fh->jpg_buffers.buffer[i].frag_tab)
340 dprintk(2,
341 KERN_WARNING
Hans Verkuilb80696b2009-02-18 13:20:05 -0300342 "%s: jpg_fbuffer_alloc() - buffer %d already allocated!?\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343 ZR_DEVNAME(zr), i);
344
345 /* Allocate fragment table for this buffer */
346
347 mem = get_zeroed_page(GFP_KERNEL);
348 if (mem == 0) {
349 dprintk(1,
350 KERN_ERR
351 "%s: jpg_fbuffer_alloc() - get_zeroed_page (frag_tab) failed for buffer %d\n",
352 ZR_DEVNAME(zr), i);
353 jpg_fbuffer_free(file);
354 return -ENOBUFS;
355 }
Al Viro581a7f12008-05-21 00:32:31 -0300356 fh->jpg_buffers.buffer[i].frag_tab = (__le32 *) mem;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357 fh->jpg_buffers.buffer[i].frag_tab_bus =
358 virt_to_bus((void *) mem);
359
360 //if (alloc_contig) {
361 if (fh->jpg_buffers.need_contiguous) {
362 mem =
363 (unsigned long) kmalloc(fh->jpg_buffers.
364 buffer_size,
365 GFP_KERNEL);
366 if (mem == 0) {
367 dprintk(1,
368 KERN_ERR
369 "%s: jpg_fbuffer_alloc() - kmalloc failed for buffer %d\n",
370 ZR_DEVNAME(zr), i);
371 jpg_fbuffer_free(file);
372 return -ENOBUFS;
373 }
374 fh->jpg_buffers.buffer[i].frag_tab[0] =
375 cpu_to_le32(virt_to_bus((void *) mem));
376 fh->jpg_buffers.buffer[i].frag_tab[1] =
377 cpu_to_le32(((fh->jpg_buffers.buffer_size / 4) << 1) | 1);
378 for (off = 0; off < fh->jpg_buffers.buffer_size;
379 off += PAGE_SIZE)
380 SetPageReserved(MAP_NR(mem + off));
381 } else {
Hans Verkuilb80696b2009-02-18 13:20:05 -0300382 /* jpg_bufsize is already page aligned */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 for (j = 0;
384 j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
385 j++) {
386 mem = get_zeroed_page(GFP_KERNEL);
387 if (mem == 0) {
388 dprintk(1,
389 KERN_ERR
390 "%s: jpg_fbuffer_alloc() - get_zeroed_page failed for buffer %d\n",
391 ZR_DEVNAME(zr), i);
392 jpg_fbuffer_free(file);
393 return -ENOBUFS;
394 }
395
396 fh->jpg_buffers.buffer[i].frag_tab[2 * j] =
397 cpu_to_le32(virt_to_bus((void *) mem));
398 fh->jpg_buffers.buffer[i].frag_tab[2 * j +
399 1] =
400 cpu_to_le32((PAGE_SIZE / 4) << 1);
401 SetPageReserved(MAP_NR(mem));
402 }
403
404 fh->jpg_buffers.buffer[i].frag_tab[2 * j - 1] |= cpu_to_le32(1);
405 }
406 }
407
408 dprintk(4,
409 KERN_DEBUG "%s: jpg_fbuffer_alloc() - %d KB allocated\n",
410 ZR_DEVNAME(zr),
411 (fh->jpg_buffers.num_buffers *
412 fh->jpg_buffers.buffer_size) >> 10);
413
414 fh->jpg_buffers.allocated = 1;
415
416 return 0;
417}
418
419/* free the MJPEG grab buffers */
420static void
421jpg_fbuffer_free (struct file *file)
422{
423 struct zoran_fh *fh = file->private_data;
424 struct zoran *zr = fh->zr;
425 int i, j, off;
426 unsigned char *mem;
427
428 dprintk(4, KERN_DEBUG "%s: jpg_fbuffer_free()\n", ZR_DEVNAME(zr));
429
430 for (i = 0; i < fh->jpg_buffers.num_buffers; i++) {
431 if (!fh->jpg_buffers.buffer[i].frag_tab)
432 continue;
433
434 //if (alloc_contig) {
435 if (fh->jpg_buffers.need_contiguous) {
436 if (fh->jpg_buffers.buffer[i].frag_tab[0]) {
437 mem = (unsigned char *) bus_to_virt(le32_to_cpu(
438 fh->jpg_buffers.buffer[i].frag_tab[0]));
439 for (off = 0;
440 off < fh->jpg_buffers.buffer_size;
441 off += PAGE_SIZE)
442 ClearPageReserved(MAP_NR
443 (mem + off));
Jesper Juhlf91012102005-09-10 00:26:54 -0700444 kfree(mem);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 fh->jpg_buffers.buffer[i].frag_tab[0] = 0;
446 fh->jpg_buffers.buffer[i].frag_tab[1] = 0;
447 }
448 } else {
449 for (j = 0;
450 j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
451 j++) {
452 if (!fh->jpg_buffers.buffer[i].
453 frag_tab[2 * j])
454 break;
455 ClearPageReserved(MAP_NR
456 (bus_to_virt
457 (le32_to_cpu
458 (fh->jpg_buffers.
459 buffer[i].frag_tab[2 *
460 j]))));
461 free_page((unsigned long)
462 bus_to_virt
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300463 (le32_to_cpu
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464 (fh->jpg_buffers.
465 buffer[i].
466 frag_tab[2 * j])));
467 fh->jpg_buffers.buffer[i].frag_tab[2 * j] =
468 0;
469 fh->jpg_buffers.buffer[i].frag_tab[2 * j +
470 1] = 0;
471 }
472 }
473
474 free_page((unsigned long) fh->jpg_buffers.buffer[i].
475 frag_tab);
476 fh->jpg_buffers.buffer[i].frag_tab = NULL;
477 }
478
479 fh->jpg_buffers.allocated = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480}
481
482/*
483 * V4L Buffer grabbing
484 */
485
486static int
487zoran_v4l_set_format (struct file *file,
488 int width,
489 int height,
490 const struct zoran_format *format)
491{
492 struct zoran_fh *fh = file->private_data;
493 struct zoran *zr = fh->zr;
494 int bpp;
495
496 /* Check size and format of the grab wanted */
497
498 if (height < BUZ_MIN_HEIGHT || width < BUZ_MIN_WIDTH ||
499 height > BUZ_MAX_HEIGHT || width > BUZ_MAX_WIDTH) {
500 dprintk(1,
501 KERN_ERR
502 "%s: v4l_set_format() - wrong frame size (%dx%d)\n",
503 ZR_DEVNAME(zr), width, height);
504 return -EINVAL;
505 }
506
507 bpp = (format->depth + 7) / 8;
508
509 /* Check against available buffer size */
510 if (height * width * bpp > fh->v4l_buffers.buffer_size) {
511 dprintk(1,
512 KERN_ERR
513 "%s: v4l_set_format() - video buffer size (%d kB) is too small\n",
514 ZR_DEVNAME(zr), fh->v4l_buffers.buffer_size >> 10);
515 return -EINVAL;
516 }
517
518 /* The video front end needs 4-byte alinged line sizes */
519
520 if ((bpp == 2 && (width & 1)) || (bpp == 3 && (width & 3))) {
521 dprintk(1,
522 KERN_ERR
Hans Verkuil96b8e142009-02-18 13:13:31 -0300523 "%s: v4l_set_format() - wrong frame alignment\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524 ZR_DEVNAME(zr));
525 return -EINVAL;
526 }
527
528 fh->v4l_settings.width = width;
529 fh->v4l_settings.height = height;
530 fh->v4l_settings.format = format;
531 fh->v4l_settings.bytesperline = bpp * fh->v4l_settings.width;
532
533 return 0;
534}
535
536static int
537zoran_v4l_queue_frame (struct file *file,
538 int num)
539{
540 struct zoran_fh *fh = file->private_data;
541 struct zoran *zr = fh->zr;
542 unsigned long flags;
543 int res = 0;
544
545 if (!fh->v4l_buffers.allocated) {
546 dprintk(1,
547 KERN_ERR
548 "%s: v4l_queue_frame() - buffers not yet allocated\n",
549 ZR_DEVNAME(zr));
550 res = -ENOMEM;
551 }
552
553 /* No grabbing outside the buffer range! */
554 if (num >= fh->v4l_buffers.num_buffers || num < 0) {
555 dprintk(1,
556 KERN_ERR
557 "%s: v4l_queue_frame() - buffer %d is out of range\n",
558 ZR_DEVNAME(zr), num);
559 res = -EINVAL;
560 }
561
562 spin_lock_irqsave(&zr->spinlock, flags);
563
564 if (fh->v4l_buffers.active == ZORAN_FREE) {
565 if (zr->v4l_buffers.active == ZORAN_FREE) {
566 zr->v4l_buffers = fh->v4l_buffers;
567 fh->v4l_buffers.active = ZORAN_ACTIVE;
568 } else {
569 dprintk(1,
570 KERN_ERR
571 "%s: v4l_queue_frame() - another session is already capturing\n",
572 ZR_DEVNAME(zr));
573 res = -EBUSY;
574 }
575 }
576
577 /* make sure a grab isn't going on currently with this buffer */
578 if (!res) {
579 switch (zr->v4l_buffers.buffer[num].state) {
580 default:
581 case BUZ_STATE_PEND:
582 if (zr->v4l_buffers.active == ZORAN_FREE) {
583 fh->v4l_buffers.active = ZORAN_FREE;
584 zr->v4l_buffers.allocated = 0;
585 }
586 res = -EBUSY; /* what are you doing? */
587 break;
588 case BUZ_STATE_DONE:
589 dprintk(2,
590 KERN_WARNING
591 "%s: v4l_queue_frame() - queueing buffer %d in state DONE!?\n",
592 ZR_DEVNAME(zr), num);
593 case BUZ_STATE_USER:
594 /* since there is at least one unused buffer there's room for at least
595 * one more pend[] entry */
596 zr->v4l_pend[zr->v4l_pend_head++ &
597 V4L_MASK_FRAME] = num;
598 zr->v4l_buffers.buffer[num].state = BUZ_STATE_PEND;
599 zr->v4l_buffers.buffer[num].bs.length =
600 fh->v4l_settings.bytesperline *
601 zr->v4l_settings.height;
602 fh->v4l_buffers.buffer[num] =
603 zr->v4l_buffers.buffer[num];
604 break;
605 }
606 }
607
608 spin_unlock_irqrestore(&zr->spinlock, flags);
609
610 if (!res && zr->v4l_buffers.active == ZORAN_FREE)
611 zr->v4l_buffers.active = fh->v4l_buffers.active;
612
613 return res;
614}
615
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616/*
617 * Sync on a V4L buffer
618 */
619
620static int
621v4l_sync (struct file *file,
622 int frame)
623{
624 struct zoran_fh *fh = file->private_data;
625 struct zoran *zr = fh->zr;
626 unsigned long flags;
627
628 if (fh->v4l_buffers.active == ZORAN_FREE) {
629 dprintk(1,
630 KERN_ERR
631 "%s: v4l_sync() - no grab active for this session\n",
632 ZR_DEVNAME(zr));
633 return -EINVAL;
634 }
635
636 /* check passed-in frame number */
637 if (frame >= fh->v4l_buffers.num_buffers || frame < 0) {
638 dprintk(1,
639 KERN_ERR "%s: v4l_sync() - frame %d is invalid\n",
640 ZR_DEVNAME(zr), frame);
641 return -EINVAL;
642 }
643
644 /* Check if is buffer was queued at all */
645 if (zr->v4l_buffers.buffer[frame].state == BUZ_STATE_USER) {
646 dprintk(1,
647 KERN_ERR
648 "%s: v4l_sync() - attempt to sync on a buffer which was not queued?\n",
649 ZR_DEVNAME(zr));
650 return -EPROTO;
651 }
652
653 /* wait on this buffer to get ready */
654 if (!wait_event_interruptible_timeout(zr->v4l_capq,
655 (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_PEND),
656 10*HZ))
657 return -ETIME;
658 if (signal_pending(current))
659 return -ERESTARTSYS;
660
661 /* buffer should now be in BUZ_STATE_DONE */
662 if (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_DONE)
663 dprintk(2,
664 KERN_ERR "%s: v4l_sync() - internal state error\n",
665 ZR_DEVNAME(zr));
666
667 zr->v4l_buffers.buffer[frame].state = BUZ_STATE_USER;
668 fh->v4l_buffers.buffer[frame] = zr->v4l_buffers.buffer[frame];
669
670 spin_lock_irqsave(&zr->spinlock, flags);
671
672 /* Check if streaming capture has finished */
673 if (zr->v4l_pend_tail == zr->v4l_pend_head) {
674 zr36057_set_memgrab(zr, 0);
675 if (zr->v4l_buffers.active == ZORAN_ACTIVE) {
676 fh->v4l_buffers.active = zr->v4l_buffers.active =
677 ZORAN_FREE;
678 zr->v4l_buffers.allocated = 0;
679 }
680 }
681
682 spin_unlock_irqrestore(&zr->spinlock, flags);
683
684 return 0;
685}
686
687/*
688 * Queue a MJPEG buffer for capture/playback
689 */
690
691static int
692zoran_jpg_queue_frame (struct file *file,
693 int num,
694 enum zoran_codec_mode mode)
695{
696 struct zoran_fh *fh = file->private_data;
697 struct zoran *zr = fh->zr;
698 unsigned long flags;
699 int res = 0;
700
701 /* Check if buffers are allocated */
702 if (!fh->jpg_buffers.allocated) {
703 dprintk(1,
704 KERN_ERR
705 "%s: jpg_queue_frame() - buffers not yet allocated\n",
706 ZR_DEVNAME(zr));
707 return -ENOMEM;
708 }
709
710 /* No grabbing outside the buffer range! */
711 if (num >= fh->jpg_buffers.num_buffers || num < 0) {
712 dprintk(1,
713 KERN_ERR
714 "%s: jpg_queue_frame() - buffer %d out of range\n",
715 ZR_DEVNAME(zr), num);
716 return -EINVAL;
717 }
718
719 /* what is the codec mode right now? */
720 if (zr->codec_mode == BUZ_MODE_IDLE) {
721 zr->jpg_settings = fh->jpg_settings;
722 } else if (zr->codec_mode != mode) {
723 /* wrong codec mode active - invalid */
724 dprintk(1,
725 KERN_ERR
726 "%s: jpg_queue_frame() - codec in wrong mode\n",
727 ZR_DEVNAME(zr));
728 return -EINVAL;
729 }
730
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731 if (fh->jpg_buffers.active == ZORAN_FREE) {
732 if (zr->jpg_buffers.active == ZORAN_FREE) {
733 zr->jpg_buffers = fh->jpg_buffers;
734 fh->jpg_buffers.active = ZORAN_ACTIVE;
735 } else {
736 dprintk(1,
737 KERN_ERR
738 "%s: jpg_queue_frame() - another session is already capturing\n",
739 ZR_DEVNAME(zr));
740 res = -EBUSY;
741 }
742 }
743
744 if (!res && zr->codec_mode == BUZ_MODE_IDLE) {
745 /* Ok load up the jpeg codec */
746 zr36057_enable_jpg(zr, mode);
747 }
748
Ronald S. Bultje8bc3efc2005-11-07 01:00:22 -0800749 spin_lock_irqsave(&zr->spinlock, flags);
750
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751 if (!res) {
752 switch (zr->jpg_buffers.buffer[num].state) {
753 case BUZ_STATE_DONE:
754 dprintk(2,
755 KERN_WARNING
756 "%s: jpg_queue_frame() - queing frame in BUZ_STATE_DONE state!?\n",
757 ZR_DEVNAME(zr));
758 case BUZ_STATE_USER:
759 /* since there is at least one unused buffer there's room for at
760 *least one more pend[] entry */
761 zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] =
762 num;
763 zr->jpg_buffers.buffer[num].state = BUZ_STATE_PEND;
764 fh->jpg_buffers.buffer[num] =
765 zr->jpg_buffers.buffer[num];
766 zoran_feed_stat_com(zr);
767 break;
768 default:
769 case BUZ_STATE_DMA:
770 case BUZ_STATE_PEND:
771 if (zr->jpg_buffers.active == ZORAN_FREE) {
772 fh->jpg_buffers.active = ZORAN_FREE;
773 zr->jpg_buffers.allocated = 0;
774 }
775 res = -EBUSY; /* what are you doing? */
776 break;
777 }
778 }
779
780 spin_unlock_irqrestore(&zr->spinlock, flags);
781
782 if (!res && zr->jpg_buffers.active == ZORAN_FREE) {
783 zr->jpg_buffers.active = fh->jpg_buffers.active;
784 }
785
786 return res;
787}
788
789static int
790jpg_qbuf (struct file *file,
791 int frame,
792 enum zoran_codec_mode mode)
793{
794 struct zoran_fh *fh = file->private_data;
795 struct zoran *zr = fh->zr;
796 int res = 0;
797
798 /* Does the user want to stop streaming? */
799 if (frame < 0) {
800 if (zr->codec_mode == mode) {
801 if (fh->jpg_buffers.active == ZORAN_FREE) {
802 dprintk(1,
803 KERN_ERR
804 "%s: jpg_qbuf(-1) - session not active\n",
805 ZR_DEVNAME(zr));
806 return -EINVAL;
807 }
808 fh->jpg_buffers.active = zr->jpg_buffers.active =
809 ZORAN_FREE;
810 zr->jpg_buffers.allocated = 0;
811 zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
812 return 0;
813 } else {
814 dprintk(1,
815 KERN_ERR
816 "%s: jpg_qbuf() - stop streaming but not in streaming mode\n",
817 ZR_DEVNAME(zr));
818 return -EINVAL;
819 }
820 }
821
822 if ((res = zoran_jpg_queue_frame(file, frame, mode)))
823 return res;
824
825 /* Start the jpeg codec when the first frame is queued */
826 if (!res && zr->jpg_que_head == 1)
827 jpeg_start(zr);
828
829 return res;
830}
831
832/*
833 * Sync on a MJPEG buffer
834 */
835
836static int
837jpg_sync (struct file *file,
838 struct zoran_sync *bs)
839{
840 struct zoran_fh *fh = file->private_data;
841 struct zoran *zr = fh->zr;
842 unsigned long flags;
843 int frame;
844
845 if (fh->jpg_buffers.active == ZORAN_FREE) {
846 dprintk(1,
847 KERN_ERR
848 "%s: jpg_sync() - capture is not currently active\n",
849 ZR_DEVNAME(zr));
850 return -EINVAL;
851 }
852 if (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS &&
853 zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) {
854 dprintk(1,
855 KERN_ERR
856 "%s: jpg_sync() - codec not in streaming mode\n",
857 ZR_DEVNAME(zr));
858 return -EINVAL;
859 }
860 if (!wait_event_interruptible_timeout(zr->jpg_capq,
861 (zr->jpg_que_tail != zr->jpg_dma_tail ||
862 zr->jpg_dma_tail == zr->jpg_dma_head),
863 10*HZ)) {
864 int isr;
865
866 btand(~ZR36057_JMC_Go_en, ZR36057_JMC);
867 udelay(1);
868 zr->codec->control(zr->codec, CODEC_G_STATUS,
869 sizeof(isr), &isr);
870 dprintk(1,
871 KERN_ERR
872 "%s: jpg_sync() - timeout: codec isr=0x%02x\n",
873 ZR_DEVNAME(zr), isr);
874
875 return -ETIME;
876
877 }
878 if (signal_pending(current))
879 return -ERESTARTSYS;
880
881 spin_lock_irqsave(&zr->spinlock, flags);
882
883 if (zr->jpg_dma_tail != zr->jpg_dma_head)
884 frame = zr->jpg_pend[zr->jpg_que_tail++ & BUZ_MASK_FRAME];
885 else
886 frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME];
887
888 /* buffer should now be in BUZ_STATE_DONE */
Jean Delvare18b548c2007-07-17 18:29:41 -0300889 if (zr->jpg_buffers.buffer[frame].state != BUZ_STATE_DONE)
890 dprintk(2,
891 KERN_ERR "%s: jpg_sync() - internal state error\n",
892 ZR_DEVNAME(zr));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893
894 *bs = zr->jpg_buffers.buffer[frame].bs;
895 bs->frame = frame;
896 zr->jpg_buffers.buffer[frame].state = BUZ_STATE_USER;
897 fh->jpg_buffers.buffer[frame] = zr->jpg_buffers.buffer[frame];
898
899 spin_unlock_irqrestore(&zr->spinlock, flags);
900
901 return 0;
902}
903
904static void
905zoran_open_init_session (struct file *file)
906{
907 int i;
908 struct zoran_fh *fh = file->private_data;
909 struct zoran *zr = fh->zr;
910
911 /* Per default, map the V4L Buffers */
912 fh->map_mode = ZORAN_MAP_MODE_RAW;
913
914 /* take over the card's current settings */
915 fh->overlay_settings = zr->overlay_settings;
916 fh->overlay_settings.is_set = 0;
917 fh->overlay_settings.format = zr->overlay_settings.format;
918 fh->overlay_active = ZORAN_FREE;
919
920 /* v4l settings */
921 fh->v4l_settings = zr->v4l_settings;
922
923 /* v4l_buffers */
924 memset(&fh->v4l_buffers, 0, sizeof(struct zoran_v4l_struct));
925 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
926 fh->v4l_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
927 fh->v4l_buffers.buffer[i].bs.frame = i;
928 }
929 fh->v4l_buffers.allocated = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930 fh->v4l_buffers.active = ZORAN_FREE;
931 fh->v4l_buffers.buffer_size = v4l_bufsize;
932 fh->v4l_buffers.num_buffers = v4l_nbufs;
933
934 /* jpg settings */
935 fh->jpg_settings = zr->jpg_settings;
936
937 /* jpg_buffers */
938 memset(&fh->jpg_buffers, 0, sizeof(struct zoran_jpg_struct));
939 for (i = 0; i < BUZ_MAX_FRAME; i++) {
940 fh->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
941 fh->jpg_buffers.buffer[i].bs.frame = i;
942 }
943 fh->jpg_buffers.need_contiguous = zr->jpg_buffers.need_contiguous;
944 fh->jpg_buffers.allocated = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945 fh->jpg_buffers.active = ZORAN_FREE;
946 fh->jpg_buffers.buffer_size = jpg_bufsize;
947 fh->jpg_buffers.num_buffers = jpg_nbufs;
948}
949
950static void
951zoran_close_end_session (struct file *file)
952{
953 struct zoran_fh *fh = file->private_data;
954 struct zoran *zr = fh->zr;
955
956 /* overlay */
957 if (fh->overlay_active != ZORAN_FREE) {
958 fh->overlay_active = zr->overlay_active = ZORAN_FREE;
959 zr->v4l_overlay_active = 0;
960 if (!zr->v4l_memgrab_active)
961 zr36057_overlay(zr, 0);
962 zr->overlay_mask = NULL;
963 }
964
965 /* v4l capture */
966 if (fh->v4l_buffers.active != ZORAN_FREE) {
Andrew Morton81b80212008-05-14 23:14:04 -0300967 unsigned long flags;
Trent Piepho9896bbc2007-07-17 18:29:45 -0300968
969 spin_lock_irqsave(&zr->spinlock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970 zr36057_set_memgrab(zr, 0);
971 zr->v4l_buffers.allocated = 0;
972 zr->v4l_buffers.active = fh->v4l_buffers.active =
973 ZORAN_FREE;
Trent Piepho9896bbc2007-07-17 18:29:45 -0300974 spin_unlock_irqrestore(&zr->spinlock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975 }
976
977 /* v4l buffers */
Hans Verkuil96b8e142009-02-18 13:13:31 -0300978 if (fh->v4l_buffers.allocated)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700979 v4l_fbuffer_free(file);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980
981 /* jpg capture */
982 if (fh->jpg_buffers.active != ZORAN_FREE) {
983 zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
984 zr->jpg_buffers.allocated = 0;
985 zr->jpg_buffers.active = fh->jpg_buffers.active =
986 ZORAN_FREE;
987 }
988
989 /* jpg buffers */
Hans Verkuil96b8e142009-02-18 13:13:31 -0300990 if (fh->jpg_buffers.allocated)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991 jpg_fbuffer_free(file);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992}
993
994/*
995 * Open a zoran card. Right now the flags stuff is just playing
996 */
997
Trent Piepho601139e2009-01-12 13:09:46 -0300998static int zoran_open(struct file *file)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700999{
Trent Piepho601139e2009-01-12 13:09:46 -03001000 struct zoran *zr = video_drvdata(file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001 struct zoran_fh *fh;
Trent Piephofc96ab72009-01-12 13:09:46 -03001002 int res, first_open = 0;
1003
1004 dprintk(2, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",
1005 ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006
Hans Verkuild56dc612008-07-30 08:43:36 -03001007 lock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008
1009 /* see fs/device.c - the kernel already locks during open(),
1010 * so locking ourselves only causes deadlocks */
Ingo Molnar384c3682006-03-22 03:54:16 -03001011 /*mutex_lock(&zr->resource_lock);*/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012
Trent Piephofc96ab72009-01-12 13:09:46 -03001013 if (zr->user >= 2048) {
1014 dprintk(1, KERN_ERR "%s: too many users (%d) on device\n",
1015 ZR_DEVNAME(zr), zr->user);
1016 res = -EBUSY;
1017 goto fail_unlock;
1018 }
1019
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020 if (!zr->decoder) {
1021 dprintk(1,
1022 KERN_ERR "%s: no TV decoder loaded for device!\n",
1023 ZR_DEVNAME(zr));
1024 res = -EIO;
Trent Piephofc96ab72009-01-12 13:09:46 -03001025 goto fail_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001026 }
1027
Laurent Riffard604f28e2005-11-26 20:43:39 +01001028 if (!try_module_get(zr->decoder->driver->driver.owner)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029 dprintk(1,
1030 KERN_ERR
Trent Piephofc96ab72009-01-12 13:09:46 -03001031 "%s: failed to grab ownership of video decoder\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 ZR_DEVNAME(zr));
1033 res = -EIO;
Trent Piephofc96ab72009-01-12 13:09:46 -03001034 goto fail_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035 }
1036 if (zr->encoder &&
Laurent Riffard604f28e2005-11-26 20:43:39 +01001037 !try_module_get(zr->encoder->driver->driver.owner)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038 dprintk(1,
1039 KERN_ERR
Trent Piephofc96ab72009-01-12 13:09:46 -03001040 "%s: failed to grab ownership of video encoder\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 ZR_DEVNAME(zr));
1042 res = -EIO;
Trent Piephofc96ab72009-01-12 13:09:46 -03001043 goto fail_decoder;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 }
1045
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046 /* now, create the open()-specific file_ops struct */
Panagiotis Issaris74081872006-01-11 19:40:56 -02001047 fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048 if (!fh) {
1049 dprintk(1,
1050 KERN_ERR
1051 "%s: zoran_open() - allocation of zoran_fh failed\n",
1052 ZR_DEVNAME(zr));
1053 res = -ENOMEM;
Trent Piephofc96ab72009-01-12 13:09:46 -03001054 goto fail_encoder;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056 /* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows
1057 * on norm-change! */
1058 fh->overlay_mask =
1059 kmalloc(((768 + 31) / 32) * 576 * 4, GFP_KERNEL);
1060 if (!fh->overlay_mask) {
1061 dprintk(1,
1062 KERN_ERR
1063 "%s: zoran_open() - allocation of overlay_mask failed\n",
1064 ZR_DEVNAME(zr));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065 res = -ENOMEM;
Trent Piephofc96ab72009-01-12 13:09:46 -03001066 goto fail_fh;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067 }
1068
1069 if (zr->user++ == 0)
1070 first_open = 1;
1071
Ingo Molnar384c3682006-03-22 03:54:16 -03001072 /*mutex_unlock(&zr->resource_lock);*/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073
1074 /* default setup - TODO: look at flags */
1075 if (first_open) { /* First device open */
1076 zr36057_restart(zr);
1077 zoran_open_init_params(zr);
1078 zoran_init_hardware(zr);
1079
1080 btor(ZR36057_ICR_IntPinEn, ZR36057_ICR);
1081 }
1082
1083 /* set file_ops stuff */
1084 file->private_data = fh;
1085 fh->zr = zr;
1086 zoran_open_init_session(file);
Hans Verkuild56dc612008-07-30 08:43:36 -03001087 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088
1089 return 0;
1090
Trent Piephofc96ab72009-01-12 13:09:46 -03001091fail_fh:
1092 kfree(fh);
1093fail_encoder:
1094 if (zr->encoder)
1095 module_put(zr->encoder->driver->driver.owner);
1096fail_decoder:
1097 module_put(zr->decoder->driver->driver.owner);
1098fail_unlock:
Hans Verkuild56dc612008-07-30 08:43:36 -03001099 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100
Trent Piephofc96ab72009-01-12 13:09:46 -03001101 dprintk(2, KERN_INFO "%s: open failed (%d), users(-)=%d\n",
1102 ZR_DEVNAME(zr), res, zr->user);
1103
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104 return res;
1105}
1106
1107static int
Hans Verkuilbec43662008-12-30 06:58:20 -03001108zoran_close(struct file *file)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109{
1110 struct zoran_fh *fh = file->private_data;
1111 struct zoran *zr = fh->zr;
1112
Trent Piephofc96ab72009-01-12 13:09:46 -03001113 dprintk(2, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",
1114 ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user - 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001115
1116 /* kernel locks (fs/device.c), so don't do that ourselves
1117 * (prevents deadlocks) */
Ingo Molnar384c3682006-03-22 03:54:16 -03001118 /*mutex_lock(&zr->resource_lock);*/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119
1120 zoran_close_end_session(file);
1121
1122 if (zr->user-- == 1) { /* Last process */
1123 /* Clean up JPEG process */
1124 wake_up_interruptible(&zr->jpg_capq);
1125 zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
1126 zr->jpg_buffers.allocated = 0;
1127 zr->jpg_buffers.active = ZORAN_FREE;
1128
1129 /* disable interrupts */
1130 btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR);
1131
Jean Delvare18b548c2007-07-17 18:29:41 -03001132 if (zr36067_debug > 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133 print_interrupts(zr);
1134
1135 /* Overlay off */
1136 zr->v4l_overlay_active = 0;
1137 zr36057_overlay(zr, 0);
1138 zr->overlay_mask = NULL;
1139
1140 /* capture off */
1141 wake_up_interruptible(&zr->v4l_capq);
1142 zr36057_set_memgrab(zr, 0);
1143 zr->v4l_buffers.allocated = 0;
1144 zr->v4l_buffers.active = ZORAN_FREE;
1145 zoran_set_pci_master(zr, 0);
1146
1147 if (!pass_through) { /* Switch to color bar */
1148 int zero = 0, two = 2;
1149 decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);
1150 encoder_command(zr, ENCODER_SET_INPUT, &two);
1151 }
1152 }
1153
1154 file->private_data = NULL;
1155 kfree(fh->overlay_mask);
1156 kfree(fh);
1157
1158 /* release locks on the i2c modules */
Laurent Riffard604f28e2005-11-26 20:43:39 +01001159 module_put(zr->decoder->driver->driver.owner);
Trent Piephofc96ab72009-01-12 13:09:46 -03001160 if (zr->encoder)
1161 module_put(zr->encoder->driver->driver.owner);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001162
Ingo Molnar384c3682006-03-22 03:54:16 -03001163 /*mutex_unlock(&zr->resource_lock);*/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164
1165 dprintk(4, KERN_INFO "%s: zoran_close() done\n", ZR_DEVNAME(zr));
1166
1167 return 0;
1168}
1169
1170
1171static ssize_t
1172zoran_read (struct file *file,
1173 char __user *data,
1174 size_t count,
1175 loff_t *ppos)
1176{
1177 /* we simply don't support read() (yet)... */
1178
1179 return -EINVAL;
1180}
1181
1182static ssize_t
1183zoran_write (struct file *file,
1184 const char __user *data,
1185 size_t count,
1186 loff_t *ppos)
1187{
1188 /* ...and the same goes for write() */
1189
1190 return -EINVAL;
1191}
1192
1193static int
1194setup_fbuffer (struct file *file,
1195 void *base,
1196 const struct zoran_format *fmt,
1197 int width,
1198 int height,
1199 int bytesperline)
1200{
1201 struct zoran_fh *fh = file->private_data;
1202 struct zoran *zr = fh->zr;
1203
1204 /* (Ronald) v4l/v4l2 guidelines */
1205 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
1206 return -EPERM;
1207
Alan Coxe3558802006-09-14 11:47:55 -03001208 /* Don't allow frame buffer overlay if PCI or AGP is buggy, or on
1209 ALi Magik (that needs very low latency while the card needs a
1210 higher value always) */
1211
1212 if (pci_pci_problems & (PCIPCI_FAIL | PCIAGP_FAIL | PCIPCI_ALIMAGIK))
1213 return -ENXIO;
1214
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215 /* we need a bytesperline value, even if not given */
1216 if (!bytesperline)
1217 bytesperline = width * ((fmt->depth + 7) & ~7) / 8;
1218
1219#if 0
1220 if (zr->overlay_active) {
1221 /* dzjee... stupid users... don't even bother to turn off
1222 * overlay before changing the memory location...
1223 * normally, we would return errors here. However, one of
1224 * the tools that does this is... xawtv! and since xawtv
1225 * is used by +/- 99% of the users, we'd rather be user-
1226 * friendly and silently do as if nothing went wrong */
1227 dprintk(3,
1228 KERN_ERR
1229 "%s: setup_fbuffer() - forced overlay turnoff because framebuffer changed\n",
1230 ZR_DEVNAME(zr));
1231 zr36057_overlay(zr, 0);
1232 }
1233#endif
1234
1235 if (!(fmt->flags & ZORAN_FORMAT_OVERLAY)) {
1236 dprintk(1,
1237 KERN_ERR
1238 "%s: setup_fbuffer() - no valid overlay format given\n",
1239 ZR_DEVNAME(zr));
1240 return -EINVAL;
1241 }
1242 if (height <= 0 || width <= 0 || bytesperline <= 0) {
1243 dprintk(1,
1244 KERN_ERR
1245 "%s: setup_fbuffer() - invalid height/width/bpl value (%d|%d|%d)\n",
1246 ZR_DEVNAME(zr), width, height, bytesperline);
1247 return -EINVAL;
1248 }
1249 if (bytesperline & 3) {
1250 dprintk(1,
1251 KERN_ERR
1252 "%s: setup_fbuffer() - bytesperline (%d) must be 4-byte aligned\n",
1253 ZR_DEVNAME(zr), bytesperline);
1254 return -EINVAL;
1255 }
1256
1257 zr->buffer.base = (void *) ((unsigned long) base & ~3);
1258 zr->buffer.height = height;
1259 zr->buffer.width = width;
1260 zr->buffer.depth = fmt->depth;
1261 zr->overlay_settings.format = fmt;
1262 zr->buffer.bytesperline = bytesperline;
1263
1264 /* The user should set new window parameters */
1265 zr->overlay_settings.is_set = 0;
1266
1267 return 0;
1268}
1269
1270
1271static int
1272setup_window (struct file *file,
1273 int x,
1274 int y,
1275 int width,
1276 int height,
1277 struct video_clip __user *clips,
1278 int clipcount,
1279 void __user *bitmap)
1280{
1281 struct zoran_fh *fh = file->private_data;
1282 struct zoran *zr = fh->zr;
1283 struct video_clip *vcp = NULL;
1284 int on, end;
1285
1286
1287 if (!zr->buffer.base) {
1288 dprintk(1,
1289 KERN_ERR
1290 "%s: setup_window() - frame buffer has to be set first\n",
1291 ZR_DEVNAME(zr));
1292 return -EINVAL;
1293 }
1294
1295 if (!fh->overlay_settings.format) {
1296 dprintk(1,
1297 KERN_ERR
1298 "%s: setup_window() - no overlay format set\n",
1299 ZR_DEVNAME(zr));
1300 return -EINVAL;
1301 }
1302
1303 /*
1304 * The video front end needs 4-byte alinged line sizes, we correct that
1305 * silently here if necessary
1306 */
1307 if (zr->buffer.depth == 15 || zr->buffer.depth == 16) {
1308 end = (x + width) & ~1; /* round down */
1309 x = (x + 1) & ~1; /* round up */
1310 width = end - x;
1311 }
1312
1313 if (zr->buffer.depth == 24) {
1314 end = (x + width) & ~3; /* round down */
1315 x = (x + 3) & ~3; /* round up */
1316 width = end - x;
1317 }
1318
1319 if (width > BUZ_MAX_WIDTH)
1320 width = BUZ_MAX_WIDTH;
1321 if (height > BUZ_MAX_HEIGHT)
1322 height = BUZ_MAX_HEIGHT;
1323
1324 /* Check for vaild parameters */
1325 if (width < BUZ_MIN_WIDTH || height < BUZ_MIN_HEIGHT ||
1326 width > BUZ_MAX_WIDTH || height > BUZ_MAX_HEIGHT) {
1327 dprintk(1,
1328 KERN_ERR
1329 "%s: setup_window() - width = %d or height = %d invalid\n",
1330 ZR_DEVNAME(zr), width, height);
1331 return -EINVAL;
1332 }
1333
1334 fh->overlay_settings.x = x;
1335 fh->overlay_settings.y = y;
1336 fh->overlay_settings.width = width;
1337 fh->overlay_settings.height = height;
1338 fh->overlay_settings.clipcount = clipcount;
1339
1340 /*
1341 * If an overlay is running, we have to switch it off
1342 * and switch it on again in order to get the new settings in effect.
1343 *
1344 * We also want to avoid that the overlay mask is written
1345 * when an overlay is running.
1346 */
1347
1348 on = zr->v4l_overlay_active && !zr->v4l_memgrab_active &&
1349 zr->overlay_active != ZORAN_FREE &&
1350 fh->overlay_active != ZORAN_FREE;
1351 if (on)
1352 zr36057_overlay(zr, 0);
1353
1354 /*
1355 * Write the overlay mask if clips are wanted.
1356 * We prefer a bitmap.
1357 */
1358 if (bitmap) {
1359 /* fake value - it just means we want clips */
1360 fh->overlay_settings.clipcount = 1;
1361
1362 if (copy_from_user(fh->overlay_mask, bitmap,
1363 (width * height + 7) / 8)) {
1364 return -EFAULT;
1365 }
1366 } else if (clipcount > 0) {
1367 /* write our own bitmap from the clips */
1368 vcp = vmalloc(sizeof(struct video_clip) * (clipcount + 4));
1369 if (vcp == NULL) {
1370 dprintk(1,
1371 KERN_ERR
1372 "%s: setup_window() - Alloc of clip mask failed\n",
1373 ZR_DEVNAME(zr));
1374 return -ENOMEM;
1375 }
1376 if (copy_from_user
1377 (vcp, clips, sizeof(struct video_clip) * clipcount)) {
1378 vfree(vcp);
1379 return -EFAULT;
1380 }
1381 write_overlay_mask(file, vcp, clipcount);
1382 vfree(vcp);
1383 }
1384
1385 fh->overlay_settings.is_set = 1;
1386 if (fh->overlay_active != ZORAN_FREE &&
1387 zr->overlay_active != ZORAN_FREE)
1388 zr->overlay_settings = fh->overlay_settings;
1389
1390 if (on)
1391 zr36057_overlay(zr, 1);
1392
1393 /* Make sure the changes come into effect */
1394 return wait_grab_pending(zr);
1395}
1396
1397static int
1398setup_overlay (struct file *file,
1399 int on)
1400{
1401 struct zoran_fh *fh = file->private_data;
1402 struct zoran *zr = fh->zr;
1403
1404 /* If there is nothing to do, return immediatly */
1405 if ((on && fh->overlay_active != ZORAN_FREE) ||
1406 (!on && fh->overlay_active == ZORAN_FREE))
1407 return 0;
1408
1409 /* check whether we're touching someone else's overlay */
1410 if (on && zr->overlay_active != ZORAN_FREE &&
1411 fh->overlay_active == ZORAN_FREE) {
1412 dprintk(1,
1413 KERN_ERR
1414 "%s: setup_overlay() - overlay is already active for another session\n",
1415 ZR_DEVNAME(zr));
1416 return -EBUSY;
1417 }
1418 if (!on && zr->overlay_active != ZORAN_FREE &&
1419 fh->overlay_active == ZORAN_FREE) {
1420 dprintk(1,
1421 KERN_ERR
1422 "%s: setup_overlay() - you cannot cancel someone else's session\n",
1423 ZR_DEVNAME(zr));
1424 return -EPERM;
1425 }
1426
1427 if (on == 0) {
1428 zr->overlay_active = fh->overlay_active = ZORAN_FREE;
1429 zr->v4l_overlay_active = 0;
1430 /* When a grab is running, the video simply
1431 * won't be switched on any more */
1432 if (!zr->v4l_memgrab_active)
1433 zr36057_overlay(zr, 0);
1434 zr->overlay_mask = NULL;
1435 } else {
1436 if (!zr->buffer.base || !fh->overlay_settings.is_set) {
1437 dprintk(1,
1438 KERN_ERR
1439 "%s: setup_overlay() - buffer or window not set\n",
1440 ZR_DEVNAME(zr));
1441 return -EINVAL;
1442 }
1443 if (!fh->overlay_settings.format) {
1444 dprintk(1,
1445 KERN_ERR
1446 "%s: setup_overlay() - no overlay format set\n",
1447 ZR_DEVNAME(zr));
1448 return -EINVAL;
1449 }
1450 zr->overlay_active = fh->overlay_active = ZORAN_LOCKED;
1451 zr->v4l_overlay_active = 1;
1452 zr->overlay_mask = fh->overlay_mask;
1453 zr->overlay_settings = fh->overlay_settings;
1454 if (!zr->v4l_memgrab_active)
1455 zr36057_overlay(zr, 1);
1456 /* When a grab is running, the video will be
1457 * switched on when grab is finished */
1458 }
1459
1460 /* Make sure the changes come into effect */
1461 return wait_grab_pending(zr);
1462}
1463
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464 /* get the status of a buffer in the clients buffer queue */
1465static int
1466zoran_v4l2_buffer_status (struct file *file,
1467 struct v4l2_buffer *buf,
1468 int num)
1469{
1470 struct zoran_fh *fh = file->private_data;
1471 struct zoran *zr = fh->zr;
1472
1473 buf->flags = V4L2_BUF_FLAG_MAPPED;
1474
1475 switch (fh->map_mode) {
1476 case ZORAN_MAP_MODE_RAW:
1477
1478 /* check range */
1479 if (num < 0 || num >= fh->v4l_buffers.num_buffers ||
1480 !fh->v4l_buffers.allocated) {
1481 dprintk(1,
1482 KERN_ERR
1483 "%s: v4l2_buffer_status() - wrong number or buffers not allocated\n",
1484 ZR_DEVNAME(zr));
1485 return -EINVAL;
1486 }
1487
1488 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1489 buf->length = fh->v4l_buffers.buffer_size;
1490
1491 /* get buffer */
1492 buf->bytesused = fh->v4l_buffers.buffer[num].bs.length;
1493 if (fh->v4l_buffers.buffer[num].state == BUZ_STATE_DONE ||
1494 fh->v4l_buffers.buffer[num].state == BUZ_STATE_USER) {
1495 buf->sequence = fh->v4l_buffers.buffer[num].bs.seq;
1496 buf->flags |= V4L2_BUF_FLAG_DONE;
1497 buf->timestamp =
1498 fh->v4l_buffers.buffer[num].bs.timestamp;
1499 } else {
1500 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1501 }
1502
1503 if (fh->v4l_settings.height <= BUZ_MAX_HEIGHT / 2)
1504 buf->field = V4L2_FIELD_TOP;
1505 else
1506 buf->field = V4L2_FIELD_INTERLACED;
1507
1508 break;
1509
1510 case ZORAN_MAP_MODE_JPG_REC:
1511 case ZORAN_MAP_MODE_JPG_PLAY:
1512
1513 /* check range */
1514 if (num < 0 || num >= fh->jpg_buffers.num_buffers ||
1515 !fh->jpg_buffers.allocated) {
1516 dprintk(1,
1517 KERN_ERR
1518 "%s: v4l2_buffer_status() - wrong number or buffers not allocated\n",
1519 ZR_DEVNAME(zr));
1520 return -EINVAL;
1521 }
1522
1523 buf->type = (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ?
1524 V4L2_BUF_TYPE_VIDEO_CAPTURE :
1525 V4L2_BUF_TYPE_VIDEO_OUTPUT;
1526 buf->length = fh->jpg_buffers.buffer_size;
1527
1528 /* these variables are only written after frame has been captured */
1529 if (fh->jpg_buffers.buffer[num].state == BUZ_STATE_DONE ||
1530 fh->jpg_buffers.buffer[num].state == BUZ_STATE_USER) {
1531 buf->sequence = fh->jpg_buffers.buffer[num].bs.seq;
1532 buf->timestamp =
1533 fh->jpg_buffers.buffer[num].bs.timestamp;
1534 buf->bytesused =
1535 fh->jpg_buffers.buffer[num].bs.length;
1536 buf->flags |= V4L2_BUF_FLAG_DONE;
1537 } else {
1538 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1539 }
1540
1541 /* which fields are these? */
1542 if (fh->jpg_settings.TmpDcm != 1)
1543 buf->field =
1544 fh->jpg_settings.
1545 odd_even ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
1546 else
1547 buf->field =
1548 fh->jpg_settings.
1549 odd_even ? V4L2_FIELD_SEQ_TB :
1550 V4L2_FIELD_SEQ_BT;
1551
1552 break;
1553
1554 default:
1555
1556 dprintk(5,
1557 KERN_ERR
1558 "%s: v4l2_buffer_status() - invalid buffer type|map_mode (%d|%d)\n",
1559 ZR_DEVNAME(zr), buf->type, fh->map_mode);
1560 return -EINVAL;
1561 }
1562
1563 buf->memory = V4L2_MEMORY_MMAP;
1564 buf->index = num;
1565 buf->m.offset = buf->length * num;
1566
1567 return 0;
1568}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569
1570static int
1571zoran_set_norm (struct zoran *zr,
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -03001572 int norm) /* VIDEO_MODE_* */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001573{
1574 int norm_encoder, on;
1575
1576 if (zr->v4l_buffers.active != ZORAN_FREE ||
1577 zr->jpg_buffers.active != ZORAN_FREE) {
1578 dprintk(1,
1579 KERN_WARNING
1580 "%s: set_norm() called while in playback/capture mode\n",
1581 ZR_DEVNAME(zr));
1582 return -EBUSY;
1583 }
1584
1585 if (lock_norm && norm != zr->norm) {
1586 if (lock_norm > 1) {
1587 dprintk(1,
1588 KERN_WARNING
1589 "%s: set_norm() - TV standard is locked, can not switch norm\n",
1590 ZR_DEVNAME(zr));
1591 return -EPERM;
1592 } else {
1593 dprintk(1,
1594 KERN_WARNING
1595 "%s: set_norm() - TV standard is locked, norm was not changed\n",
1596 ZR_DEVNAME(zr));
1597 norm = zr->norm;
1598 }
1599 }
1600
1601 if (norm != VIDEO_MODE_AUTO &&
1602 (norm < 0 || norm >= zr->card.norms ||
1603 !zr->card.tvn[norm])) {
1604 dprintk(1,
1605 KERN_ERR "%s: set_norm() - unsupported norm %d\n",
1606 ZR_DEVNAME(zr), norm);
1607 return -EINVAL;
1608 }
1609
1610 if (norm == VIDEO_MODE_AUTO) {
1611 int status;
1612
1613 /* if we have autodetect, ... */
1614 struct video_decoder_capability caps;
1615 decoder_command(zr, DECODER_GET_CAPABILITIES, &caps);
1616 if (!(caps.flags & VIDEO_DECODER_AUTO)) {
1617 dprintk(1, KERN_ERR "%s: norm=auto unsupported\n",
1618 ZR_DEVNAME(zr));
1619 return -EINVAL;
1620 }
1621
1622 decoder_command(zr, DECODER_SET_NORM, &norm);
1623
1624 /* let changes come into effect */
1625 ssleep(2);
1626
1627 decoder_command(zr, DECODER_GET_STATUS, &status);
1628 if (!(status & DECODER_STATUS_GOOD)) {
1629 dprintk(1,
1630 KERN_ERR
1631 "%s: set_norm() - no norm detected\n",
1632 ZR_DEVNAME(zr));
1633 /* reset norm */
1634 decoder_command(zr, DECODER_SET_NORM, &zr->norm);
1635 return -EIO;
1636 }
1637
1638 if (status & DECODER_STATUS_NTSC)
1639 norm = VIDEO_MODE_NTSC;
1640 else if (status & DECODER_STATUS_SECAM)
1641 norm = VIDEO_MODE_SECAM;
1642 else
1643 norm = VIDEO_MODE_PAL;
1644 }
1645 zr->timing = zr->card.tvn[norm];
1646 norm_encoder = norm;
1647
1648 /* We switch overlay off and on since a change in the
1649 * norm needs different VFE settings */
1650 on = zr->overlay_active && !zr->v4l_memgrab_active;
1651 if (on)
1652 zr36057_overlay(zr, 0);
1653
1654 decoder_command(zr, DECODER_SET_NORM, &norm);
1655 encoder_command(zr, ENCODER_SET_NORM, &norm_encoder);
1656
1657 if (on)
1658 zr36057_overlay(zr, 1);
1659
1660 /* Make sure the changes come into effect */
1661 zr->norm = norm;
1662
1663 return 0;
1664}
1665
1666static int
1667zoran_set_input (struct zoran *zr,
1668 int input)
1669{
1670 int realinput;
1671
1672 if (input == zr->input) {
1673 return 0;
1674 }
1675
1676 if (zr->v4l_buffers.active != ZORAN_FREE ||
1677 zr->jpg_buffers.active != ZORAN_FREE) {
1678 dprintk(1,
1679 KERN_WARNING
1680 "%s: set_input() called while in playback/capture mode\n",
1681 ZR_DEVNAME(zr));
1682 return -EBUSY;
1683 }
1684
1685 if (input < 0 || input >= zr->card.inputs) {
1686 dprintk(1,
1687 KERN_ERR
1688 "%s: set_input() - unnsupported input %d\n",
1689 ZR_DEVNAME(zr), input);
1690 return -EINVAL;
1691 }
1692
1693 realinput = zr->card.input[input].muxsel;
1694 zr->input = input;
1695
1696 decoder_command(zr, DECODER_SET_INPUT, &realinput);
1697
1698 return 0;
1699}
1700
1701/*
1702 * ioctl routine
1703 */
1704
Hans Verkuildcbd83b2009-02-18 13:51:13 -03001705#ifdef CONFIG_VIDEO_V4L1_COMPAT
Hans Verkuil96b8e142009-02-18 13:13:31 -03001706static long zoran_default(struct file *file, void *__fh, int cmd, void *arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707{
Hans Verkuil96b8e142009-02-18 13:13:31 -03001708 struct zoran_fh *fh = __fh;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709 struct zoran *zr = fh->zr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710 struct zoran_jpg_settings settings;
1711
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712 switch (cmd) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713 case BUZIOC_G_PARAMS:
1714 {
1715 struct zoran_params *bparams = arg;
1716
1717 dprintk(3, KERN_DEBUG "%s: BUZIOC_G_PARAMS\n", ZR_DEVNAME(zr));
1718
1719 memset(bparams, 0, sizeof(struct zoran_params));
1720 bparams->major_version = MAJOR_VERSION;
1721 bparams->minor_version = MINOR_VERSION;
1722
Ingo Molnar384c3682006-03-22 03:54:16 -03001723 mutex_lock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724
1725 bparams->norm = zr->norm;
1726 bparams->input = zr->input;
1727
1728 bparams->decimation = fh->jpg_settings.decimation;
1729 bparams->HorDcm = fh->jpg_settings.HorDcm;
1730 bparams->VerDcm = fh->jpg_settings.VerDcm;
1731 bparams->TmpDcm = fh->jpg_settings.TmpDcm;
1732 bparams->field_per_buff = fh->jpg_settings.field_per_buff;
1733 bparams->img_x = fh->jpg_settings.img_x;
1734 bparams->img_y = fh->jpg_settings.img_y;
1735 bparams->img_width = fh->jpg_settings.img_width;
1736 bparams->img_height = fh->jpg_settings.img_height;
1737 bparams->odd_even = fh->jpg_settings.odd_even;
1738
1739 bparams->quality = fh->jpg_settings.jpg_comp.quality;
1740 bparams->APPn = fh->jpg_settings.jpg_comp.APPn;
1741 bparams->APP_len = fh->jpg_settings.jpg_comp.APP_len;
1742 memcpy(bparams->APP_data,
1743 fh->jpg_settings.jpg_comp.APP_data,
1744 sizeof(bparams->APP_data));
1745 bparams->COM_len = zr->jpg_settings.jpg_comp.COM_len;
1746 memcpy(bparams->COM_data,
1747 fh->jpg_settings.jpg_comp.COM_data,
1748 sizeof(bparams->COM_data));
1749 bparams->jpeg_markers =
1750 fh->jpg_settings.jpg_comp.jpeg_markers;
1751
Ingo Molnar384c3682006-03-22 03:54:16 -03001752 mutex_unlock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753
1754 bparams->VFIFO_FB = 0;
1755
1756 return 0;
1757 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758
1759 case BUZIOC_S_PARAMS:
1760 {
1761 struct zoran_params *bparams = arg;
1762 int res = 0;
1763
1764 dprintk(3, KERN_DEBUG "%s: BUZIOC_S_PARAMS\n", ZR_DEVNAME(zr));
1765
1766 settings.decimation = bparams->decimation;
1767 settings.HorDcm = bparams->HorDcm;
1768 settings.VerDcm = bparams->VerDcm;
1769 settings.TmpDcm = bparams->TmpDcm;
1770 settings.field_per_buff = bparams->field_per_buff;
1771 settings.img_x = bparams->img_x;
1772 settings.img_y = bparams->img_y;
1773 settings.img_width = bparams->img_width;
1774 settings.img_height = bparams->img_height;
1775 settings.odd_even = bparams->odd_even;
1776
1777 settings.jpg_comp.quality = bparams->quality;
1778 settings.jpg_comp.APPn = bparams->APPn;
1779 settings.jpg_comp.APP_len = bparams->APP_len;
1780 memcpy(settings.jpg_comp.APP_data, bparams->APP_data,
1781 sizeof(bparams->APP_data));
1782 settings.jpg_comp.COM_len = bparams->COM_len;
1783 memcpy(settings.jpg_comp.COM_data, bparams->COM_data,
1784 sizeof(bparams->COM_data));
1785 settings.jpg_comp.jpeg_markers = bparams->jpeg_markers;
1786
Ingo Molnar384c3682006-03-22 03:54:16 -03001787 mutex_lock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788
1789 if (zr->codec_mode != BUZ_MODE_IDLE) {
1790 dprintk(1,
1791 KERN_ERR
1792 "%s: BUZIOC_S_PARAMS called, but Buz in capture/playback mode\n",
1793 ZR_DEVNAME(zr));
1794 res = -EINVAL;
1795 goto sparams_unlock_and_return;
1796 }
1797
1798 /* Check the params first before overwriting our
1799 * nternal values */
Hans Verkuil0ba514d2009-02-18 17:11:17 -03001800 if (zoran_check_jpg_settings(zr, &settings, 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 res = -EINVAL;
1802 goto sparams_unlock_and_return;
1803 }
1804
1805 fh->jpg_settings = settings;
Hans Verkuil96b8e142009-02-18 13:13:31 -03001806sparams_unlock_and_return:
Ingo Molnar384c3682006-03-22 03:54:16 -03001807 mutex_unlock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808
1809 return res;
1810 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811
1812 case BUZIOC_REQBUFS:
1813 {
1814 struct zoran_requestbuffers *breq = arg;
1815 int res = 0;
1816
1817 dprintk(3,
1818 KERN_DEBUG
1819 "%s: BUZIOC_REQBUFS - count=%lu, size=%lu\n",
1820 ZR_DEVNAME(zr), breq->count, breq->size);
1821
1822 /* Enforce reasonable lower and upper limits */
1823 if (breq->count < 4)
1824 breq->count = 4; /* Could be choosen smaller */
1825 if (breq->count > jpg_nbufs)
1826 breq->count = jpg_nbufs;
1827 breq->size = PAGE_ALIGN(breq->size);
1828 if (breq->size < 8192)
1829 breq->size = 8192; /* Arbitrary */
1830 /* breq->size is limited by 1 page for the stat_com
1831 * tables to a Maximum of 2 MB */
1832 if (breq->size > jpg_bufsize)
1833 breq->size = jpg_bufsize;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834
Ingo Molnar384c3682006-03-22 03:54:16 -03001835 mutex_lock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836
1837 if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) {
1838 dprintk(1,
1839 KERN_ERR
Hans Verkuilb80696b2009-02-18 13:20:05 -03001840 "%s: BUZIOC_REQBUFS - buffers already allocated\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 ZR_DEVNAME(zr));
1842 res = -EBUSY;
1843 goto jpgreqbuf_unlock_and_return;
1844 }
1845
1846 fh->jpg_buffers.num_buffers = breq->count;
1847 fh->jpg_buffers.buffer_size = breq->size;
1848
1849 if (jpg_fbuffer_alloc(file)) {
1850 res = -ENOMEM;
1851 goto jpgreqbuf_unlock_and_return;
1852 }
1853
1854 /* The next mmap will map the MJPEG buffers - could
1855 * also be *_PLAY, but it doesn't matter here */
1856 fh->map_mode = ZORAN_MAP_MODE_JPG_REC;
Hans Verkuil96b8e142009-02-18 13:13:31 -03001857jpgreqbuf_unlock_and_return:
Ingo Molnar384c3682006-03-22 03:54:16 -03001858 mutex_unlock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859
1860 return res;
1861 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862
1863 case BUZIOC_QBUF_CAPT:
1864 {
1865 int *frame = arg, res;
1866
1867 dprintk(3, KERN_DEBUG "%s: BUZIOC_QBUF_CAPT - frame=%d\n",
1868 ZR_DEVNAME(zr), *frame);
1869
Ingo Molnar384c3682006-03-22 03:54:16 -03001870 mutex_lock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871 res = jpg_qbuf(file, *frame, BUZ_MODE_MOTION_COMPRESS);
Ingo Molnar384c3682006-03-22 03:54:16 -03001872 mutex_unlock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873
1874 return res;
1875 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876
1877 case BUZIOC_QBUF_PLAY:
1878 {
1879 int *frame = arg, res;
1880
1881 dprintk(3, KERN_DEBUG "%s: BUZIOC_QBUF_PLAY - frame=%d\n",
1882 ZR_DEVNAME(zr), *frame);
1883
Ingo Molnar384c3682006-03-22 03:54:16 -03001884 mutex_lock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885 res = jpg_qbuf(file, *frame, BUZ_MODE_MOTION_DECOMPRESS);
Ingo Molnar384c3682006-03-22 03:54:16 -03001886 mutex_unlock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887
1888 return res;
1889 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890
1891 case BUZIOC_SYNC:
1892 {
1893 struct zoran_sync *bsync = arg;
1894 int res;
1895
1896 dprintk(3, KERN_DEBUG "%s: BUZIOC_SYNC\n", ZR_DEVNAME(zr));
1897
Ingo Molnar384c3682006-03-22 03:54:16 -03001898 mutex_lock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899 res = jpg_sync(file, bsync);
Ingo Molnar384c3682006-03-22 03:54:16 -03001900 mutex_unlock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901
1902 return res;
1903 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904
1905 case BUZIOC_G_STATUS:
1906 {
1907 struct zoran_status *bstat = arg;
1908 int norm, input, status, res = 0;
1909
1910 dprintk(3, KERN_DEBUG "%s: BUZIOC_G_STATUS\n", ZR_DEVNAME(zr));
1911
1912 if (zr->codec_mode != BUZ_MODE_IDLE) {
1913 dprintk(1,
1914 KERN_ERR
1915 "%s: BUZIOC_G_STATUS called but Buz in capture/playback mode\n",
1916 ZR_DEVNAME(zr));
1917 return -EINVAL;
1918 }
1919
1920 input = zr->card.input[bstat->input].muxsel;
1921 norm = VIDEO_MODE_AUTO;
1922
Ingo Molnar384c3682006-03-22 03:54:16 -03001923 mutex_lock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924
1925 if (zr->codec_mode != BUZ_MODE_IDLE) {
1926 dprintk(1,
1927 KERN_ERR
1928 "%s: BUZIOC_G_STATUS called, but Buz in capture/playback mode\n",
1929 ZR_DEVNAME(zr));
1930 res = -EINVAL;
1931 goto gstat_unlock_and_return;
1932 }
1933
1934 decoder_command(zr, DECODER_SET_INPUT, &input);
1935 decoder_command(zr, DECODER_SET_NORM, &norm);
1936
1937 /* sleep 1 second */
1938 ssleep(1);
1939
1940 /* Get status of video decoder */
1941 decoder_command(zr, DECODER_GET_STATUS, &status);
1942
1943 /* restore previous input and norm */
1944 input = zr->card.input[zr->input].muxsel;
1945 decoder_command(zr, DECODER_SET_INPUT, &input);
1946 decoder_command(zr, DECODER_SET_NORM, &zr->norm);
Hans Verkuil96b8e142009-02-18 13:13:31 -03001947gstat_unlock_and_return:
Ingo Molnar384c3682006-03-22 03:54:16 -03001948 mutex_unlock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949
1950 if (!res) {
1951 bstat->signal =
1952 (status & DECODER_STATUS_GOOD) ? 1 : 0;
1953 if (status & DECODER_STATUS_NTSC)
1954 bstat->norm = VIDEO_MODE_NTSC;
1955 else if (status & DECODER_STATUS_SECAM)
1956 bstat->norm = VIDEO_MODE_SECAM;
1957 else
1958 bstat->norm = VIDEO_MODE_PAL;
1959
1960 bstat->color =
1961 (status & DECODER_STATUS_COLOR) ? 1 : 0;
1962 }
1963
1964 return res;
1965 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001966
1967 default:
Hans Verkuil96b8e142009-02-18 13:13:31 -03001968 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969 }
Hans Verkuil96b8e142009-02-18 13:13:31 -03001970}
1971
Hans Verkuildcbd83b2009-02-18 13:51:13 -03001972static int zoran_vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *vmbuf)
1973{
1974 struct zoran_fh *fh = __fh;
1975 struct zoran *zr = fh->zr;
1976 int i, res = 0;
1977
1978 vmbuf->size =
1979 fh->v4l_buffers.num_buffers *
1980 fh->v4l_buffers.buffer_size;
1981 vmbuf->frames = fh->v4l_buffers.num_buffers;
1982 for (i = 0; i < vmbuf->frames; i++) {
1983 vmbuf->offsets[i] =
1984 i * fh->v4l_buffers.buffer_size;
1985 }
1986
1987 mutex_lock(&zr->resource_lock);
1988
1989 if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) {
1990 dprintk(1,
1991 KERN_ERR
1992 "%s: VIDIOCGMBUF - buffers already allocated\n",
1993 ZR_DEVNAME(zr));
1994 res = -EINVAL;
1995 goto v4l1reqbuf_unlock_and_return;
1996 }
1997
1998 if (v4l_fbuffer_alloc(file)) {
1999 res = -ENOMEM;
2000 goto v4l1reqbuf_unlock_and_return;
2001 }
2002
2003 /* The next mmap will map the V4L buffers */
2004 fh->map_mode = ZORAN_MAP_MODE_RAW;
2005v4l1reqbuf_unlock_and_return:
2006 mutex_unlock(&zr->resource_lock);
2007
2008 return res;
2009}
2010#endif
2011
Hans Verkuil96b8e142009-02-18 13:13:31 -03002012static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap)
2013{
2014 struct zoran_fh *fh = __fh;
2015 struct zoran *zr = fh->zr;
2016
2017 memset(cap, 0, sizeof(*cap));
2018 strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1);
2019 strncpy(cap->driver, "zoran", sizeof(cap->driver)-1);
2020 snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
2021 pci_name(zr->pci_dev));
2022 cap->version =
2023 KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION,
2024 RELEASE_VERSION);
2025 cap->capabilities = ZORAN_V4L2_VID_FLAGS;
2026
Linus Torvalds1da177e2005-04-16 15:20:36 -07002027 return 0;
2028}
2029
Hans Verkuil96b8e142009-02-18 13:13:31 -03002030static int zoran_enum_fmt(struct zoran *zr, struct v4l2_fmtdesc *fmt, int flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002031{
Hans Verkuil96b8e142009-02-18 13:13:31 -03002032 int num = -1, i;
2033
2034 for (i = 0; i < NUM_FORMATS; i++) {
2035 if (zoran_formats[i].flags & flag)
2036 num++;
2037 if (num == fmt->index)
2038 break;
2039 }
2040 if (fmt->index < 0 /* late, but not too late */ || i == NUM_FORMATS)
2041 return -EINVAL;
2042
2043 strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1);
2044 fmt->pixelformat = zoran_formats[i].fourcc;
2045 if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)
2046 fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
2047 return 0;
2048}
2049
2050static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh,
2051 struct v4l2_fmtdesc *f)
2052{
2053 struct zoran_fh *fh = __fh;
2054 struct zoran *zr = fh->zr;
2055
2056 return zoran_enum_fmt(zr, f, ZORAN_FORMAT_CAPTURE);
2057}
2058
2059static int zoran_enum_fmt_vid_out(struct file *file, void *__fh,
2060 struct v4l2_fmtdesc *f)
2061{
2062 struct zoran_fh *fh = __fh;
2063 struct zoran *zr = fh->zr;
2064
2065 return zoran_enum_fmt(zr, f, ZORAN_FORMAT_PLAYBACK);
2066}
2067
2068static int zoran_enum_fmt_vid_overlay(struct file *file, void *__fh,
2069 struct v4l2_fmtdesc *f)
2070{
2071 struct zoran_fh *fh = __fh;
2072 struct zoran *zr = fh->zr;
2073
2074 return zoran_enum_fmt(zr, f, ZORAN_FORMAT_OVERLAY);
2075}
2076
2077static int zoran_g_fmt_vid_out(struct file *file, void *__fh,
2078 struct v4l2_format *fmt)
2079{
2080 struct zoran_fh *fh = __fh;
2081 struct zoran *zr = fh->zr;
2082
2083 mutex_lock(&zr->resource_lock);
2084
2085 fmt->fmt.pix.width = fh->jpg_settings.img_width / fh->jpg_settings.HorDcm;
Hans Verkuil5ca75b02009-02-18 17:12:34 -03002086 fmt->fmt.pix.height = fh->jpg_settings.img_height * 2 /
Hans Verkuil96b8e142009-02-18 13:13:31 -03002087 (fh->jpg_settings.VerDcm * fh->jpg_settings.TmpDcm);
2088 fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&fh->jpg_settings);
2089 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
2090 if (fh->jpg_settings.TmpDcm == 1)
2091 fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
Hans Verkuil3e667932009-02-18 13:24:56 -03002092 V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
Hans Verkuil96b8e142009-02-18 13:13:31 -03002093 else
2094 fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
2095 V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
2096 fmt->fmt.pix.bytesperline = 0;
2097 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
2098
2099 mutex_unlock(&zr->resource_lock);
2100 return 0;
2101}
2102
2103static int zoran_g_fmt_vid_cap(struct file *file, void *__fh,
2104 struct v4l2_format *fmt)
2105{
2106 struct zoran_fh *fh = __fh;
2107 struct zoran *zr = fh->zr;
2108
2109 if (fh->map_mode != ZORAN_MAP_MODE_RAW)
2110 return zoran_g_fmt_vid_out(file, fh, fmt);
2111
2112 mutex_lock(&zr->resource_lock);
2113 fmt->fmt.pix.width = fh->v4l_settings.width;
2114 fmt->fmt.pix.height = fh->v4l_settings.height;
2115 fmt->fmt.pix.sizeimage = fh->v4l_settings.bytesperline *
2116 fh->v4l_settings.height;
2117 fmt->fmt.pix.pixelformat = fh->v4l_settings.format->fourcc;
2118 fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace;
2119 fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline;
2120 if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2))
2121 fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
2122 else
2123 fmt->fmt.pix.field = V4L2_FIELD_TOP;
2124 mutex_unlock(&zr->resource_lock);
2125 return 0;
2126}
2127
2128static int zoran_g_fmt_vid_overlay(struct file *file, void *__fh,
2129 struct v4l2_format *fmt)
2130{
2131 struct zoran_fh *fh = __fh;
2132 struct zoran *zr = fh->zr;
2133
2134 mutex_lock(&zr->resource_lock);
2135
2136 fmt->fmt.win.w.left = fh->overlay_settings.x;
2137 fmt->fmt.win.w.top = fh->overlay_settings.y;
2138 fmt->fmt.win.w.width = fh->overlay_settings.width;
2139 fmt->fmt.win.w.height = fh->overlay_settings.height;
2140 if (fh->overlay_settings.width * 2 > BUZ_MAX_HEIGHT)
2141 fmt->fmt.win.field = V4L2_FIELD_INTERLACED;
2142 else
2143 fmt->fmt.win.field = V4L2_FIELD_TOP;
2144
2145 mutex_unlock(&zr->resource_lock);
2146 return 0;
2147}
2148
2149static int zoran_try_fmt_vid_overlay(struct file *file, void *__fh,
2150 struct v4l2_format *fmt)
2151{
2152 struct zoran_fh *fh = __fh;
2153 struct zoran *zr = fh->zr;
2154
2155 mutex_lock(&zr->resource_lock);
2156
2157 if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH)
2158 fmt->fmt.win.w.width = BUZ_MAX_WIDTH;
2159 if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH)
2160 fmt->fmt.win.w.width = BUZ_MIN_WIDTH;
2161 if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT)
2162 fmt->fmt.win.w.height = BUZ_MAX_HEIGHT;
2163 if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT)
2164 fmt->fmt.win.w.height = BUZ_MIN_HEIGHT;
2165
2166 mutex_unlock(&zr->resource_lock);
2167 return 0;
2168}
2169
2170static int zoran_try_fmt_vid_out(struct file *file, void *__fh,
2171 struct v4l2_format *fmt)
2172{
2173 struct zoran_fh *fh = __fh;
2174 struct zoran *zr = fh->zr;
2175 struct zoran_jpg_settings settings;
2176 int res = 0;
2177
Hans Verkuil96b8e142009-02-18 13:13:31 -03002178 if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
2179 return -EINVAL;
2180
Hans Verkuil9f1b9ef2009-02-18 13:28:28 -03002181 fmt->fmt.pix.bytesperline = 0;
2182
Hans Verkuil96b8e142009-02-18 13:13:31 -03002183 mutex_lock(&zr->resource_lock);
2184 settings = fh->jpg_settings;
2185
2186 /* we actually need to set 'real' parameters now */
2187 if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT)
2188 settings.TmpDcm = 1;
2189 else
2190 settings.TmpDcm = 2;
2191 settings.decimation = 0;
2192 if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2)
2193 settings.VerDcm = 2;
2194 else
2195 settings.VerDcm = 1;
2196 if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4)
2197 settings.HorDcm = 4;
2198 else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2)
2199 settings.HorDcm = 2;
2200 else
2201 settings.HorDcm = 1;
2202 if (settings.TmpDcm == 1)
2203 settings.field_per_buff = 2;
2204 else
2205 settings.field_per_buff = 1;
2206
2207 /* check */
Hans Verkuil0ba514d2009-02-18 17:11:17 -03002208 res = zoran_check_jpg_settings(zr, &settings, 1);
Hans Verkuil96b8e142009-02-18 13:13:31 -03002209 if (res)
2210 goto tryfmt_unlock_and_return;
2211
2212 /* tell the user what we actually did */
2213 fmt->fmt.pix.width = settings.img_width / settings.HorDcm;
2214 fmt->fmt.pix.height = settings.img_height * 2 /
2215 (settings.TmpDcm * settings.VerDcm);
2216 if (settings.TmpDcm == 1)
2217 fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
2218 V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
2219 else
2220 fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
2221 V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
2222
2223 fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&settings);
2224tryfmt_unlock_and_return:
2225 mutex_unlock(&zr->resource_lock);
2226 return res;
2227}
2228
2229static int zoran_try_fmt_vid_cap(struct file *file, void *__fh,
2230 struct v4l2_format *fmt)
2231{
2232 struct zoran_fh *fh = __fh;
2233 struct zoran *zr = fh->zr;
Hans Verkuil0ba514d2009-02-18 17:11:17 -03002234 int bpp;
Hans Verkuil96b8e142009-02-18 13:13:31 -03002235 int i;
2236
Hans Verkuil96b8e142009-02-18 13:13:31 -03002237 if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
2238 return zoran_try_fmt_vid_out(file, fh, fmt);
2239
2240 mutex_lock(&zr->resource_lock);
2241
2242 for (i = 0; i < NUM_FORMATS; i++)
2243 if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat)
2244 break;
2245
2246 if (i == NUM_FORMATS) {
2247 mutex_unlock(&zr->resource_lock);
2248 return -EINVAL;
2249 }
2250
Hans Verkuil0ba514d2009-02-18 17:11:17 -03002251 bpp = (zoran_formats[i].depth + 7) / 8;
2252 fmt->fmt.pix.width &= ~((bpp == 2) ? 1 : 3);
Hans Verkuil96b8e142009-02-18 13:13:31 -03002253 if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
2254 fmt->fmt.pix.width = BUZ_MAX_WIDTH;
2255 if (fmt->fmt.pix.width < BUZ_MIN_WIDTH)
2256 fmt->fmt.pix.width = BUZ_MIN_WIDTH;
2257 if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
2258 fmt->fmt.pix.height = BUZ_MAX_HEIGHT;
2259 if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT)
2260 fmt->fmt.pix.height = BUZ_MIN_HEIGHT;
2261 mutex_unlock(&zr->resource_lock);
2262
2263 return 0;
2264}
2265
2266static int zoran_s_fmt_vid_overlay(struct file *file, void *__fh,
2267 struct v4l2_format *fmt)
2268{
2269 struct zoran_fh *fh = __fh;
2270 struct zoran *zr = fh->zr;
2271 int res;
2272
2273 dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n",
2274 fmt->fmt.win.w.left, fmt->fmt.win.w.top,
2275 fmt->fmt.win.w.width,
2276 fmt->fmt.win.w.height,
2277 fmt->fmt.win.clipcount,
2278 fmt->fmt.win.bitmap);
2279 mutex_lock(&zr->resource_lock);
2280 res = setup_window(file, fmt->fmt.win.w.left,
2281 fmt->fmt.win.w.top,
2282 fmt->fmt.win.w.width,
2283 fmt->fmt.win.w.height,
2284 (struct video_clip __user *)
2285 fmt->fmt.win.clips,
2286 fmt->fmt.win.clipcount,
2287 fmt->fmt.win.bitmap);
2288 mutex_unlock(&zr->resource_lock);
2289 return res;
2290}
2291
2292static int zoran_s_fmt_vid_out(struct file *file, void *__fh,
2293 struct v4l2_format *fmt)
2294{
2295 struct zoran_fh *fh = __fh;
2296 struct zoran *zr = fh->zr;
2297 __le32 printformat = __cpu_to_le32(fmt->fmt.pix.pixelformat);
2298 struct zoran_jpg_settings settings;
2299 int res = 0;
2300
2301 dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n",
2302 fmt->fmt.pix.width, fmt->fmt.pix.height,
2303 fmt->fmt.pix.pixelformat,
2304 (char *) &printformat);
2305 if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
2306 return -EINVAL;
2307
2308 mutex_lock(&zr->resource_lock);
2309
2310 settings = fh->jpg_settings;
2311
2312 if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) {
2313 dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n",
2314 ZR_DEVNAME(zr));
2315 res = -EBUSY;
2316 goto sfmtjpg_unlock_and_return;
2317 }
2318
2319 /* we actually need to set 'real' parameters now */
Hans Verkuil7f37cc92009-02-18 17:00:37 -03002320 if (fmt->fmt.pix.height * 2 > BUZ_MAX_HEIGHT)
Hans Verkuil96b8e142009-02-18 13:13:31 -03002321 settings.TmpDcm = 1;
2322 else
2323 settings.TmpDcm = 2;
2324 settings.decimation = 0;
2325 if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2)
2326 settings.VerDcm = 2;
2327 else
2328 settings.VerDcm = 1;
2329 if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4)
2330 settings.HorDcm = 4;
2331 else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2)
2332 settings.HorDcm = 2;
2333 else
2334 settings.HorDcm = 1;
2335 if (settings.TmpDcm == 1)
2336 settings.field_per_buff = 2;
2337 else
2338 settings.field_per_buff = 1;
2339
Hans Verkuil0ba514d2009-02-18 17:11:17 -03002340 if (settings.HorDcm > 1) {
2341 settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
2342 settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
2343 } else {
2344 settings.img_x = 0;
2345 settings.img_width = BUZ_MAX_WIDTH;
2346 }
2347
Hans Verkuil96b8e142009-02-18 13:13:31 -03002348 /* check */
Hans Verkuil0ba514d2009-02-18 17:11:17 -03002349 res = zoran_check_jpg_settings(zr, &settings, 0);
Hans Verkuil96b8e142009-02-18 13:13:31 -03002350 if (res)
2351 goto sfmtjpg_unlock_and_return;
2352
2353 /* it's ok, so set them */
2354 fh->jpg_settings = settings;
2355
2356 /* tell the user what we actually did */
2357 fmt->fmt.pix.width = settings.img_width / settings.HorDcm;
2358 fmt->fmt.pix.height = settings.img_height * 2 /
2359 (settings.TmpDcm * settings.VerDcm);
2360 if (settings.TmpDcm == 1)
2361 fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
2362 V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
2363 else
2364 fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
2365 V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
2366 fh->jpg_buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings);
2367 fmt->fmt.pix.bytesperline = 0;
2368 fmt->fmt.pix.sizeimage = fh->jpg_buffers.buffer_size;
2369 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
2370
2371 /* we hereby abuse this variable to show that
2372 * we're gonna do mjpeg capture */
2373 fh->map_mode = (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ?
2374 ZORAN_MAP_MODE_JPG_REC : ZORAN_MAP_MODE_JPG_PLAY;
2375sfmtjpg_unlock_and_return:
2376 mutex_unlock(&zr->resource_lock);
2377 return res;
2378}
2379
2380static int zoran_s_fmt_vid_cap(struct file *file, void *__fh,
2381 struct v4l2_format *fmt)
2382{
2383 struct zoran_fh *fh = __fh;
2384 struct zoran *zr = fh->zr;
2385 int i;
2386 int res = 0;
2387
2388 if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
2389 return zoran_s_fmt_vid_out(file, fh, fmt);
2390
2391 for (i = 0; i < NUM_FORMATS; i++)
2392 if (fmt->fmt.pix.pixelformat == zoran_formats[i].fourcc)
2393 break;
2394 if (i == NUM_FORMATS) {
2395 dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x\n",
2396 ZR_DEVNAME(zr), fmt->fmt.pix.pixelformat);
2397 return -EINVAL;
2398 }
2399 mutex_lock(&zr->resource_lock);
2400 if (fh->jpg_buffers.allocated ||
2401 (fh->v4l_buffers.allocated && fh->v4l_buffers.active != ZORAN_FREE)) {
2402 dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n",
2403 ZR_DEVNAME(zr));
2404 res = -EBUSY;
2405 goto sfmtv4l_unlock_and_return;
2406 }
2407 if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
2408 fmt->fmt.pix.height = BUZ_MAX_HEIGHT;
2409 if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
2410 fmt->fmt.pix.width = BUZ_MAX_WIDTH;
2411
2412 res = zoran_v4l_set_format(file, fmt->fmt.pix.width,
2413 fmt->fmt.pix.height, &zoran_formats[i]);
2414 if (res)
2415 goto sfmtv4l_unlock_and_return;
2416
2417 /* tell the user the
2418 * results/missing stuff */
2419 fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline;
2420 fmt->fmt.pix.sizeimage = fh->v4l_settings.height * fh->v4l_settings.bytesperline;
2421 fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace;
2422 if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2))
2423 fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
2424 else
2425 fmt->fmt.pix.field = V4L2_FIELD_TOP;
2426
2427 fh->map_mode = ZORAN_MAP_MODE_RAW;
2428sfmtv4l_unlock_and_return:
2429 mutex_unlock(&zr->resource_lock);
2430 return res;
2431}
2432
2433static int zoran_g_fbuf(struct file *file, void *__fh,
2434 struct v4l2_framebuffer *fb)
2435{
2436 struct zoran_fh *fh = __fh;
2437 struct zoran *zr = fh->zr;
2438
2439 memset(fb, 0, sizeof(*fb));
2440 mutex_lock(&zr->resource_lock);
2441 fb->base = zr->buffer.base;
2442 fb->fmt.width = zr->buffer.width;
2443 fb->fmt.height = zr->buffer.height;
2444 if (zr->overlay_settings.format)
2445 fb->fmt.pixelformat = fh->overlay_settings.format->fourcc;
2446 fb->fmt.bytesperline = zr->buffer.bytesperline;
2447 mutex_unlock(&zr->resource_lock);
2448 fb->fmt.colorspace = V4L2_COLORSPACE_SRGB;
2449 fb->fmt.field = V4L2_FIELD_INTERLACED;
2450 fb->flags = V4L2_FBUF_FLAG_OVERLAY;
2451 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
2452
2453 return 0;
2454}
2455
2456static int zoran_s_fbuf(struct file *file, void *__fh,
2457 struct v4l2_framebuffer *fb)
2458{
2459 struct zoran_fh *fh = __fh;
2460 struct zoran *zr = fh->zr;
2461 int i, res = 0;
2462 __le32 printformat = __cpu_to_le32(fb->fmt.pixelformat);
2463
2464 for (i = 0; i < NUM_FORMATS; i++)
2465 if (zoran_formats[i].fourcc == fb->fmt.pixelformat)
2466 break;
2467 if (i == NUM_FORMATS) {
2468 dprintk(1, KERN_ERR "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n",
2469 ZR_DEVNAME(zr), fb->fmt.pixelformat,
2470 (char *)&printformat);
2471 return -EINVAL;
2472 }
2473
2474 mutex_lock(&zr->resource_lock);
2475 res = setup_fbuffer(file, fb->base, &zoran_formats[i],
2476 fb->fmt.width, fb->fmt.height,
2477 fb->fmt.bytesperline);
2478 mutex_unlock(&zr->resource_lock);
2479
2480 return res;
2481}
2482
2483static int zoran_overlay(struct file *file, void *__fh, unsigned int on)
2484{
2485 struct zoran_fh *fh = __fh;
2486 struct zoran *zr = fh->zr;
2487 int res;
2488
2489 mutex_lock(&zr->resource_lock);
2490 res = setup_overlay(file, on);
2491 mutex_unlock(&zr->resource_lock);
2492
2493 return res;
2494}
2495
Hans Verkuil84c1b092009-02-18 17:15:46 -03002496static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type);
2497
Hans Verkuil96b8e142009-02-18 13:13:31 -03002498static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *req)
2499{
2500 struct zoran_fh *fh = __fh;
2501 struct zoran *zr = fh->zr;
2502 int res = 0;
2503
2504 if (req->memory != V4L2_MEMORY_MMAP) {
Hans Verkuil84c1b092009-02-18 17:15:46 -03002505 dprintk(2,
Hans Verkuil96b8e142009-02-18 13:13:31 -03002506 KERN_ERR
2507 "%s: only MEMORY_MMAP capture is supported, not %d\n",
2508 ZR_DEVNAME(zr), req->memory);
2509 return -EINVAL;
2510 }
2511
Hans Verkuil84c1b092009-02-18 17:15:46 -03002512 if (req->count == 0)
2513 return zoran_streamoff(file, fh, req->type);
Hans Verkuil96b8e142009-02-18 13:13:31 -03002514
Hans Verkuil84c1b092009-02-18 17:15:46 -03002515 mutex_lock(&zr->resource_lock);
Hans Verkuil96b8e142009-02-18 13:13:31 -03002516 if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) {
Hans Verkuil84c1b092009-02-18 17:15:46 -03002517 dprintk(2,
Hans Verkuil96b8e142009-02-18 13:13:31 -03002518 KERN_ERR
Hans Verkuil7f37cc92009-02-18 17:00:37 -03002519 "%s: VIDIOC_REQBUFS - buffers already allocated\n",
Hans Verkuil96b8e142009-02-18 13:13:31 -03002520 ZR_DEVNAME(zr));
2521 res = -EBUSY;
2522 goto v4l2reqbuf_unlock_and_return;
2523 }
2524
2525 if (fh->map_mode == ZORAN_MAP_MODE_RAW &&
2526 req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2527
2528 /* control user input */
2529 if (req->count < 2)
2530 req->count = 2;
2531 if (req->count > v4l_nbufs)
2532 req->count = v4l_nbufs;
2533 fh->v4l_buffers.num_buffers = req->count;
2534
2535 if (v4l_fbuffer_alloc(file)) {
2536 res = -ENOMEM;
2537 goto v4l2reqbuf_unlock_and_return;
2538 }
2539
2540 /* The next mmap will map the V4L buffers */
2541 fh->map_mode = ZORAN_MAP_MODE_RAW;
2542
2543 } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC ||
2544 fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
2545
2546 /* we need to calculate size ourselves now */
2547 if (req->count < 4)
2548 req->count = 4;
2549 if (req->count > jpg_nbufs)
2550 req->count = jpg_nbufs;
2551 fh->jpg_buffers.num_buffers = req->count;
2552 fh->jpg_buffers.buffer_size =
2553 zoran_v4l2_calc_bufsize(&fh->jpg_settings);
2554
2555 if (jpg_fbuffer_alloc(file)) {
2556 res = -ENOMEM;
2557 goto v4l2reqbuf_unlock_and_return;
2558 }
2559
2560 /* The next mmap will map the MJPEG buffers */
2561 if (req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
2562 fh->map_mode = ZORAN_MAP_MODE_JPG_REC;
2563 else
2564 fh->map_mode = ZORAN_MAP_MODE_JPG_PLAY;
2565
2566 } else {
2567 dprintk(1,
2568 KERN_ERR
2569 "%s: VIDIOC_REQBUFS - unknown type %d\n",
2570 ZR_DEVNAME(zr), req->type);
2571 res = -EINVAL;
2572 goto v4l2reqbuf_unlock_and_return;
2573 }
2574v4l2reqbuf_unlock_and_return:
2575 mutex_unlock(&zr->resource_lock);
2576
2577 return res;
2578}
2579
2580static int zoran_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
2581{
2582 struct zoran_fh *fh = __fh;
2583 struct zoran *zr = fh->zr;
2584 __u32 type = buf->type;
2585 int index = buf->index, res;
2586
2587 memset(buf, 0, sizeof(*buf));
2588 buf->type = type;
2589 buf->index = index;
2590
2591 mutex_lock(&zr->resource_lock);
2592 res = zoran_v4l2_buffer_status(file, buf, buf->index);
2593 mutex_unlock(&zr->resource_lock);
2594
2595 return res;
2596}
2597
2598static int zoran_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
2599{
2600 struct zoran_fh *fh = __fh;
2601 struct zoran *zr = fh->zr;
2602 int res = 0, codec_mode, buf_type;
2603
2604 mutex_lock(&zr->resource_lock);
2605
2606 switch (fh->map_mode) {
2607 case ZORAN_MAP_MODE_RAW:
2608 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2609 dprintk(1, KERN_ERR
2610 "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
2611 ZR_DEVNAME(zr), buf->type, fh->map_mode);
2612 res = -EINVAL;
2613 goto qbuf_unlock_and_return;
2614 }
2615
2616 res = zoran_v4l_queue_frame(file, buf->index);
2617 if (res)
2618 goto qbuf_unlock_and_return;
2619 if (!zr->v4l_memgrab_active &&
2620 fh->v4l_buffers.active == ZORAN_LOCKED)
2621 zr36057_set_memgrab(zr, 1);
2622 break;
2623
2624 case ZORAN_MAP_MODE_JPG_REC:
2625 case ZORAN_MAP_MODE_JPG_PLAY:
2626 if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
2627 buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2628 codec_mode = BUZ_MODE_MOTION_DECOMPRESS;
2629 } else {
2630 buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2631 codec_mode = BUZ_MODE_MOTION_COMPRESS;
2632 }
2633
2634 if (buf->type != buf_type) {
2635 dprintk(1, KERN_ERR
2636 "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
2637 ZR_DEVNAME(zr), buf->type, fh->map_mode);
2638 res = -EINVAL;
2639 goto qbuf_unlock_and_return;
2640 }
2641
2642 res = zoran_jpg_queue_frame(file, buf->index,
2643 codec_mode);
2644 if (res != 0)
2645 goto qbuf_unlock_and_return;
2646 if (zr->codec_mode == BUZ_MODE_IDLE &&
2647 fh->jpg_buffers.active == ZORAN_LOCKED) {
2648 zr36057_enable_jpg(zr, codec_mode);
2649 }
2650 break;
2651
2652 default:
2653 dprintk(1, KERN_ERR
2654 "%s: VIDIOC_QBUF - unsupported type %d\n",
2655 ZR_DEVNAME(zr), buf->type);
2656 res = -EINVAL;
2657 break;
2658 }
2659qbuf_unlock_and_return:
2660 mutex_unlock(&zr->resource_lock);
2661
2662 return res;
2663}
2664
2665static int zoran_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
2666{
2667 struct zoran_fh *fh = __fh;
2668 struct zoran *zr = fh->zr;
2669 int res = 0, buf_type, num = -1; /* compiler borks here (?) */
2670
2671 mutex_lock(&zr->resource_lock);
2672
2673 switch (fh->map_mode) {
2674 case ZORAN_MAP_MODE_RAW:
2675 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2676 dprintk(1, KERN_ERR
2677 "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
2678 ZR_DEVNAME(zr), buf->type, fh->map_mode);
2679 res = -EINVAL;
2680 goto dqbuf_unlock_and_return;
2681 }
2682
2683 num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME];
2684 if (file->f_flags & O_NONBLOCK &&
2685 zr->v4l_buffers.buffer[num].state != BUZ_STATE_DONE) {
2686 res = -EAGAIN;
2687 goto dqbuf_unlock_and_return;
2688 }
2689 res = v4l_sync(file, num);
2690 if (res)
2691 goto dqbuf_unlock_and_return;
2692 zr->v4l_sync_tail++;
2693 res = zoran_v4l2_buffer_status(file, buf, num);
2694 break;
2695
2696 case ZORAN_MAP_MODE_JPG_REC:
2697 case ZORAN_MAP_MODE_JPG_PLAY:
2698 {
2699 struct zoran_sync bs;
2700
2701 if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY)
2702 buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2703 else
2704 buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2705
2706 if (buf->type != buf_type) {
2707 dprintk(1, KERN_ERR
2708 "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
2709 ZR_DEVNAME(zr), buf->type, fh->map_mode);
2710 res = -EINVAL;
2711 goto dqbuf_unlock_and_return;
2712 }
2713
2714 num = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME];
2715
2716 if (file->f_flags & O_NONBLOCK &&
2717 zr->jpg_buffers.buffer[num].state != BUZ_STATE_DONE) {
2718 res = -EAGAIN;
2719 goto dqbuf_unlock_and_return;
2720 }
2721 res = jpg_sync(file, &bs);
2722 if (res)
2723 goto dqbuf_unlock_and_return;
2724 res = zoran_v4l2_buffer_status(file, buf, bs.frame);
2725 break;
2726 }
2727
2728 default:
2729 dprintk(1, KERN_ERR
2730 "%s: VIDIOC_DQBUF - unsupported type %d\n",
2731 ZR_DEVNAME(zr), buf->type);
2732 res = -EINVAL;
2733 break;
2734 }
2735dqbuf_unlock_and_return:
2736 mutex_unlock(&zr->resource_lock);
2737
2738 return res;
2739}
2740
2741static int zoran_streamon(struct file *file, void *__fh, enum v4l2_buf_type type)
2742{
2743 struct zoran_fh *fh = __fh;
2744 struct zoran *zr = fh->zr;
2745 int res = 0;
2746
2747 mutex_lock(&zr->resource_lock);
2748
2749 switch (fh->map_mode) {
2750 case ZORAN_MAP_MODE_RAW: /* raw capture */
2751 if (zr->v4l_buffers.active != ZORAN_ACTIVE ||
2752 fh->v4l_buffers.active != ZORAN_ACTIVE) {
2753 res = -EBUSY;
2754 goto strmon_unlock_and_return;
2755 }
2756
2757 zr->v4l_buffers.active = fh->v4l_buffers.active = ZORAN_LOCKED;
2758 zr->v4l_settings = fh->v4l_settings;
2759
2760 zr->v4l_sync_tail = zr->v4l_pend_tail;
2761 if (!zr->v4l_memgrab_active &&
2762 zr->v4l_pend_head != zr->v4l_pend_tail) {
2763 zr36057_set_memgrab(zr, 1);
2764 }
2765 break;
2766
2767 case ZORAN_MAP_MODE_JPG_REC:
2768 case ZORAN_MAP_MODE_JPG_PLAY:
2769 /* what is the codec mode right now? */
2770 if (zr->jpg_buffers.active != ZORAN_ACTIVE ||
2771 fh->jpg_buffers.active != ZORAN_ACTIVE) {
2772 res = -EBUSY;
2773 goto strmon_unlock_and_return;
2774 }
2775
2776 zr->jpg_buffers.active = fh->jpg_buffers.active = ZORAN_LOCKED;
2777
2778 if (zr->jpg_que_head != zr->jpg_que_tail) {
2779 /* Start the jpeg codec when the first frame is queued */
2780 jpeg_start(zr);
2781 }
2782 break;
2783
2784 default:
2785 dprintk(1,
2786 KERN_ERR
2787 "%s: VIDIOC_STREAMON - invalid map mode %d\n",
2788 ZR_DEVNAME(zr), fh->map_mode);
2789 res = -EINVAL;
2790 break;
2791 }
2792strmon_unlock_and_return:
2793 mutex_unlock(&zr->resource_lock);
2794
2795 return res;
2796}
2797
2798static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type)
2799{
2800 struct zoran_fh *fh = __fh;
2801 struct zoran *zr = fh->zr;
2802 int i, res = 0;
2803
2804 mutex_lock(&zr->resource_lock);
2805
2806 switch (fh->map_mode) {
2807 case ZORAN_MAP_MODE_RAW: /* raw capture */
2808 if (fh->v4l_buffers.active == ZORAN_FREE &&
2809 zr->v4l_buffers.active != ZORAN_FREE) {
2810 res = -EPERM; /* stay off other's settings! */
2811 goto strmoff_unlock_and_return;
2812 }
2813 if (zr->v4l_buffers.active == ZORAN_FREE)
2814 goto strmoff_unlock_and_return;
2815
2816 /* unload capture */
2817 if (zr->v4l_memgrab_active) {
2818 unsigned long flags;
2819
2820 spin_lock_irqsave(&zr->spinlock, flags);
2821 zr36057_set_memgrab(zr, 0);
2822 spin_unlock_irqrestore(&zr->spinlock, flags);
2823 }
2824
2825 for (i = 0; i < fh->v4l_buffers.num_buffers; i++)
2826 zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER;
2827 fh->v4l_buffers = zr->v4l_buffers;
2828
2829 zr->v4l_buffers.active = fh->v4l_buffers.active = ZORAN_FREE;
2830
2831 zr->v4l_grab_seq = 0;
2832 zr->v4l_pend_head = zr->v4l_pend_tail = 0;
2833 zr->v4l_sync_tail = 0;
2834
2835 break;
2836
2837 case ZORAN_MAP_MODE_JPG_REC:
2838 case ZORAN_MAP_MODE_JPG_PLAY:
2839 if (fh->jpg_buffers.active == ZORAN_FREE &&
2840 zr->jpg_buffers.active != ZORAN_FREE) {
2841 res = -EPERM; /* stay off other's settings! */
2842 goto strmoff_unlock_and_return;
2843 }
2844 if (zr->jpg_buffers.active == ZORAN_FREE)
2845 goto strmoff_unlock_and_return;
2846
2847 res = jpg_qbuf(file, -1,
2848 (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ?
2849 BUZ_MODE_MOTION_COMPRESS :
2850 BUZ_MODE_MOTION_DECOMPRESS);
2851 if (res)
2852 goto strmoff_unlock_and_return;
2853 break;
2854 default:
2855 dprintk(1, KERN_ERR
2856 "%s: VIDIOC_STREAMOFF - invalid map mode %d\n",
2857 ZR_DEVNAME(zr), fh->map_mode);
2858 res = -EINVAL;
2859 break;
2860 }
2861strmoff_unlock_and_return:
2862 mutex_unlock(&zr->resource_lock);
2863
2864 return res;
2865}
2866
2867static int zoran_queryctrl(struct file *file, void *__fh,
2868 struct v4l2_queryctrl *ctrl)
2869{
2870 /* we only support hue/saturation/contrast/brightness */
2871 if (ctrl->id < V4L2_CID_BRIGHTNESS ||
2872 ctrl->id > V4L2_CID_HUE)
2873 return -EINVAL;
2874 else {
2875 int id = ctrl->id;
2876 memset(ctrl, 0, sizeof(*ctrl));
2877 ctrl->id = id;
2878 }
2879
2880 switch (ctrl->id) {
2881 case V4L2_CID_BRIGHTNESS:
2882 strncpy(ctrl->name, "Brightness", sizeof(ctrl->name)-1);
2883 break;
2884 case V4L2_CID_CONTRAST:
2885 strncpy(ctrl->name, "Contrast", sizeof(ctrl->name)-1);
2886 break;
2887 case V4L2_CID_SATURATION:
2888 strncpy(ctrl->name, "Saturation", sizeof(ctrl->name)-1);
2889 break;
2890 case V4L2_CID_HUE:
2891 strncpy(ctrl->name, "Hue", sizeof(ctrl->name)-1);
2892 break;
2893 }
2894
2895 ctrl->minimum = 0;
2896 ctrl->maximum = 65535;
2897 ctrl->step = 1;
2898 ctrl->default_value = 32768;
2899 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
Hans Verkuil869826a2009-02-18 13:23:24 -03002900 ctrl->flags = V4L2_CTRL_FLAG_SLIDER;
Hans Verkuil96b8e142009-02-18 13:13:31 -03002901
2902 return 0;
2903}
2904
2905static int zoran_g_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl)
2906{
2907 struct zoran_fh *fh = __fh;
2908 struct zoran *zr = fh->zr;
2909
2910 /* we only support hue/saturation/contrast/brightness */
2911 if (ctrl->id < V4L2_CID_BRIGHTNESS ||
2912 ctrl->id > V4L2_CID_HUE)
2913 return -EINVAL;
2914
2915 mutex_lock(&zr->resource_lock);
2916 switch (ctrl->id) {
2917 case V4L2_CID_BRIGHTNESS:
2918 ctrl->value = zr->brightness;
2919 break;
2920 case V4L2_CID_CONTRAST:
2921 ctrl->value = zr->contrast;
2922 break;
2923 case V4L2_CID_SATURATION:
2924 ctrl->value = zr->saturation;
2925 break;
2926 case V4L2_CID_HUE:
2927 ctrl->value = zr->hue;
2928 break;
2929 }
2930 mutex_unlock(&zr->resource_lock);
2931
2932 return 0;
2933}
2934
2935static int zoran_s_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl)
2936{
2937 struct zoran_fh *fh = __fh;
2938 struct zoran *zr = fh->zr;
2939 struct video_picture pict;
2940
2941 /* we only support hue/saturation/contrast/brightness */
2942 if (ctrl->id < V4L2_CID_BRIGHTNESS ||
2943 ctrl->id > V4L2_CID_HUE)
2944 return -EINVAL;
2945
2946 if (ctrl->value < 0 || ctrl->value > 65535) {
2947 dprintk(1, KERN_ERR
2948 "%s: VIDIOC_S_CTRL - invalid value %d for id=%d\n",
2949 ZR_DEVNAME(zr), ctrl->value, ctrl->id);
2950 return -EINVAL;
2951 }
2952
2953 mutex_lock(&zr->resource_lock);
2954 switch (ctrl->id) {
2955 case V4L2_CID_BRIGHTNESS:
2956 zr->brightness = ctrl->value;
2957 break;
2958 case V4L2_CID_CONTRAST:
2959 zr->contrast = ctrl->value;
2960 break;
2961 case V4L2_CID_SATURATION:
2962 zr->saturation = ctrl->value;
2963 break;
2964 case V4L2_CID_HUE:
2965 zr->hue = ctrl->value;
2966 break;
2967 }
2968 pict.brightness = zr->brightness;
2969 pict.contrast = zr->contrast;
2970 pict.colour = zr->saturation;
2971 pict.hue = zr->hue;
2972
2973 decoder_command(zr, DECODER_SET_PICTURE, &pict);
2974
2975 mutex_unlock(&zr->resource_lock);
2976
2977 return 0;
2978}
2979
2980static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std)
2981{
2982 struct zoran_fh *fh = __fh;
2983 struct zoran *zr = fh->zr;
2984 int norm;
2985
2986 mutex_lock(&zr->resource_lock);
2987 norm = zr->norm;
2988 mutex_unlock(&zr->resource_lock);
2989
2990 switch (norm) {
2991 case VIDEO_MODE_PAL:
2992 *std = V4L2_STD_PAL;
2993 break;
2994 case VIDEO_MODE_NTSC:
2995 *std = V4L2_STD_NTSC;
2996 break;
2997 case VIDEO_MODE_SECAM:
2998 *std = V4L2_STD_SECAM;
2999 break;
3000 }
3001
3002 return 0;
3003}
3004
3005static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id *std)
3006{
3007 struct zoran_fh *fh = __fh;
3008 struct zoran *zr = fh->zr;
3009 int norm = -1, res = 0;
3010
3011 if ((*std & V4L2_STD_PAL) && !(*std & ~V4L2_STD_PAL))
3012 norm = VIDEO_MODE_PAL;
3013 else if ((*std & V4L2_STD_NTSC) && !(*std & ~V4L2_STD_NTSC))
3014 norm = VIDEO_MODE_NTSC;
3015 else if ((*std & V4L2_STD_SECAM) && !(*std & ~V4L2_STD_SECAM))
3016 norm = VIDEO_MODE_SECAM;
3017 else if (*std == V4L2_STD_ALL)
3018 norm = VIDEO_MODE_AUTO;
3019 else {
3020 dprintk(1, KERN_ERR
3021 "%s: VIDIOC_S_STD - invalid norm 0x%llx\n",
3022 ZR_DEVNAME(zr), (unsigned long long)*std);
3023 return -EINVAL;
3024 }
3025
3026 mutex_lock(&zr->resource_lock);
3027 res = zoran_set_norm(zr, norm);
3028 if (res)
3029 goto sstd_unlock_and_return;
3030
3031 res = wait_grab_pending(zr);
3032sstd_unlock_and_return:
3033 mutex_unlock(&zr->resource_lock);
3034 return res;
3035}
3036
3037static int zoran_enum_input(struct file *file, void *__fh,
3038 struct v4l2_input *inp)
3039{
3040 struct zoran_fh *fh = __fh;
3041 struct zoran *zr = fh->zr;
3042 int status;
3043
3044 if (inp->index < 0 || inp->index >= zr->card.inputs)
3045 return -EINVAL;
3046 else {
3047 int id = inp->index;
3048 memset(inp, 0, sizeof(*inp));
3049 inp->index = id;
3050 }
3051
3052 strncpy(inp->name, zr->card.input[inp->index].name,
3053 sizeof(inp->name) - 1);
3054 inp->type = V4L2_INPUT_TYPE_CAMERA;
3055 inp->std = V4L2_STD_ALL;
3056
3057 /* Get status of video decoder */
3058 mutex_lock(&zr->resource_lock);
3059 decoder_command(zr, DECODER_GET_STATUS, &status);
3060 mutex_unlock(&zr->resource_lock);
3061
3062 if (!(status & DECODER_STATUS_GOOD)) {
3063 inp->status |= V4L2_IN_ST_NO_POWER;
3064 inp->status |= V4L2_IN_ST_NO_SIGNAL;
3065 }
3066 if (!(status & DECODER_STATUS_COLOR))
3067 inp->status |= V4L2_IN_ST_NO_COLOR;
3068
3069 return 0;
3070}
3071
3072static int zoran_g_input(struct file *file, void *__fh, unsigned int *input)
3073{
3074 struct zoran_fh *fh = __fh;
3075 struct zoran *zr = fh->zr;
3076
3077 mutex_lock(&zr->resource_lock);
3078 *input = zr->input;
3079 mutex_unlock(&zr->resource_lock);
3080
3081 return 0;
3082}
3083
3084static int zoran_s_input(struct file *file, void *__fh, unsigned int input)
3085{
3086 struct zoran_fh *fh = __fh;
3087 struct zoran *zr = fh->zr;
3088 int res;
3089
3090 mutex_lock(&zr->resource_lock);
3091 res = zoran_set_input(zr, input);
3092 if (res)
3093 goto sinput_unlock_and_return;
3094
3095 /* Make sure the changes come into effect */
3096 res = wait_grab_pending(zr);
3097sinput_unlock_and_return:
3098 mutex_unlock(&zr->resource_lock);
3099 return res;
3100}
3101
3102static int zoran_enum_output(struct file *file, void *__fh,
3103 struct v4l2_output *outp)
3104{
3105 if (outp->index != 0)
3106 return -EINVAL;
3107
3108 memset(outp, 0, sizeof(*outp));
3109 outp->index = 0;
3110 outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY;
3111 strncpy(outp->name, "Autodetect", sizeof(outp->name)-1);
3112
3113 return 0;
3114}
3115
3116static int zoran_g_output(struct file *file, void *__fh, unsigned int *output)
3117{
3118 *output = 0;
3119
3120 return 0;
3121}
3122
3123static int zoran_s_output(struct file *file, void *__fh, unsigned int output)
3124{
3125 if (output != 0)
3126 return -EINVAL;
3127
3128 return 0;
3129}
3130
3131/* cropping (sub-frame capture) */
3132static int zoran_cropcap(struct file *file, void *__fh,
3133 struct v4l2_cropcap *cropcap)
3134{
3135 struct zoran_fh *fh = __fh;
3136 struct zoran *zr = fh->zr;
3137 int type = cropcap->type, res = 0;
3138
3139 memset(cropcap, 0, sizeof(*cropcap));
3140 cropcap->type = type;
3141
3142 mutex_lock(&zr->resource_lock);
3143
3144 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
3145 (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
3146 fh->map_mode == ZORAN_MAP_MODE_RAW)) {
3147 dprintk(1, KERN_ERR
3148 "%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n",
3149 ZR_DEVNAME(zr));
3150 res = -EINVAL;
3151 goto cropcap_unlock_and_return;
3152 }
3153
3154 cropcap->bounds.top = cropcap->bounds.left = 0;
3155 cropcap->bounds.width = BUZ_MAX_WIDTH;
3156 cropcap->bounds.height = BUZ_MAX_HEIGHT;
3157 cropcap->defrect.top = cropcap->defrect.left = 0;
3158 cropcap->defrect.width = BUZ_MIN_WIDTH;
3159 cropcap->defrect.height = BUZ_MIN_HEIGHT;
3160cropcap_unlock_and_return:
3161 mutex_unlock(&zr->resource_lock);
3162 return res;
3163}
3164
3165static int zoran_g_crop(struct file *file, void *__fh, struct v4l2_crop *crop)
3166{
3167 struct zoran_fh *fh = __fh;
3168 struct zoran *zr = fh->zr;
3169 int type = crop->type, res = 0;
3170
3171 memset(crop, 0, sizeof(*crop));
3172 crop->type = type;
3173
3174 mutex_lock(&zr->resource_lock);
3175
3176 if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
3177 (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
3178 fh->map_mode == ZORAN_MAP_MODE_RAW)) {
3179 dprintk(1,
3180 KERN_ERR
3181 "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
3182 ZR_DEVNAME(zr));
3183 res = -EINVAL;
3184 goto gcrop_unlock_and_return;
3185 }
3186
3187 crop->c.top = fh->jpg_settings.img_y;
3188 crop->c.left = fh->jpg_settings.img_x;
3189 crop->c.width = fh->jpg_settings.img_width;
3190 crop->c.height = fh->jpg_settings.img_height;
3191
3192gcrop_unlock_and_return:
3193 mutex_unlock(&zr->resource_lock);
3194
3195 return res;
3196}
3197
3198static int zoran_s_crop(struct file *file, void *__fh, struct v4l2_crop *crop)
3199{
3200 struct zoran_fh *fh = __fh;
3201 struct zoran *zr = fh->zr;
3202 int res = 0;
3203 struct zoran_jpg_settings settings;
3204
3205 settings = fh->jpg_settings;
3206
3207 mutex_lock(&zr->resource_lock);
3208
3209 if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) {
3210 dprintk(1, KERN_ERR
3211 "%s: VIDIOC_S_CROP - cannot change settings while active\n",
3212 ZR_DEVNAME(zr));
3213 res = -EBUSY;
3214 goto scrop_unlock_and_return;
3215 }
3216
3217 if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
3218 (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
3219 fh->map_mode == ZORAN_MAP_MODE_RAW)) {
3220 dprintk(1, KERN_ERR
3221 "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
3222 ZR_DEVNAME(zr));
3223 res = -EINVAL;
3224 goto scrop_unlock_and_return;
3225 }
3226
3227 /* move into a form that we understand */
3228 settings.img_x = crop->c.left;
3229 settings.img_y = crop->c.top;
3230 settings.img_width = crop->c.width;
3231 settings.img_height = crop->c.height;
3232
3233 /* check validity */
Hans Verkuil0ba514d2009-02-18 17:11:17 -03003234 res = zoran_check_jpg_settings(zr, &settings, 0);
Hans Verkuil96b8e142009-02-18 13:13:31 -03003235 if (res)
3236 goto scrop_unlock_and_return;
3237
3238 /* accept */
3239 fh->jpg_settings = settings;
3240
3241scrop_unlock_and_return:
3242 mutex_unlock(&zr->resource_lock);
3243 return res;
3244}
3245
3246static int zoran_g_jpegcomp(struct file *file, void *__fh,
3247 struct v4l2_jpegcompression *params)
3248{
3249 struct zoran_fh *fh = __fh;
3250 struct zoran *zr = fh->zr;
3251 memset(params, 0, sizeof(*params));
3252
3253 mutex_lock(&zr->resource_lock);
3254
3255 params->quality = fh->jpg_settings.jpg_comp.quality;
3256 params->APPn = fh->jpg_settings.jpg_comp.APPn;
3257 memcpy(params->APP_data,
3258 fh->jpg_settings.jpg_comp.APP_data,
3259 fh->jpg_settings.jpg_comp.APP_len);
3260 params->APP_len = fh->jpg_settings.jpg_comp.APP_len;
3261 memcpy(params->COM_data,
3262 fh->jpg_settings.jpg_comp.COM_data,
3263 fh->jpg_settings.jpg_comp.COM_len);
3264 params->COM_len = fh->jpg_settings.jpg_comp.COM_len;
3265 params->jpeg_markers =
3266 fh->jpg_settings.jpg_comp.jpeg_markers;
3267
3268 mutex_unlock(&zr->resource_lock);
3269
3270 return 0;
3271}
3272
3273static int zoran_s_jpegcomp(struct file *file, void *__fh,
3274 struct v4l2_jpegcompression *params)
3275{
3276 struct zoran_fh *fh = __fh;
3277 struct zoran *zr = fh->zr;
3278 int res = 0;
3279 struct zoran_jpg_settings settings;
3280
3281 settings = fh->jpg_settings;
3282
3283 settings.jpg_comp = *params;
3284
3285 mutex_lock(&zr->resource_lock);
3286
3287 if (fh->v4l_buffers.active != ZORAN_FREE ||
3288 fh->jpg_buffers.active != ZORAN_FREE) {
3289 dprintk(1, KERN_WARNING
3290 "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n",
3291 ZR_DEVNAME(zr));
3292 res = -EBUSY;
3293 goto sjpegc_unlock_and_return;
3294 }
3295
Hans Verkuil0ba514d2009-02-18 17:11:17 -03003296 res = zoran_check_jpg_settings(zr, &settings, 0);
Hans Verkuil96b8e142009-02-18 13:13:31 -03003297 if (res)
3298 goto sjpegc_unlock_and_return;
3299 if (!fh->jpg_buffers.allocated)
3300 fh->jpg_buffers.buffer_size =
3301 zoran_v4l2_calc_bufsize(&fh->jpg_settings);
3302 fh->jpg_settings.jpg_comp = *params = settings.jpg_comp;
3303sjpegc_unlock_and_return:
3304 mutex_unlock(&zr->resource_lock);
3305
3306 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003307}
3308
3309static unsigned int
3310zoran_poll (struct file *file,
3311 poll_table *wait)
3312{
3313 struct zoran_fh *fh = file->private_data;
3314 struct zoran *zr = fh->zr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003315 int res = 0, frame;
Trent Piephoe42af832007-07-17 18:29:43 -03003316 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003317
3318 /* we should check whether buffers are ready to be synced on
3319 * (w/o waits - O_NONBLOCK) here
3320 * if ready for read (sync), return POLLIN|POLLRDNORM,
3321 * if ready for write (sync), return POLLOUT|POLLWRNORM,
3322 * if error, return POLLERR,
3323 * if no buffers queued or so, return POLLNVAL
3324 */
3325
Ingo Molnar384c3682006-03-22 03:54:16 -03003326 mutex_lock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003327
3328 switch (fh->map_mode) {
3329 case ZORAN_MAP_MODE_RAW:
Trent Piephoe42af832007-07-17 18:29:43 -03003330 poll_wait(file, &zr->v4l_capq, wait);
3331 frame = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME];
3332
3333 spin_lock_irqsave(&zr->spinlock, flags);
3334 dprintk(3,
3335 KERN_DEBUG
3336 "%s: %s() raw - active=%c, sync_tail=%lu/%c, pend_tail=%lu, pend_head=%lu\n",
Harvey Harrison7e28adb2008-04-08 23:20:00 -03003337 ZR_DEVNAME(zr), __func__,
Trent Piephoe42af832007-07-17 18:29:43 -03003338 "FAL"[fh->v4l_buffers.active], zr->v4l_sync_tail,
3339 "UPMD"[zr->v4l_buffers.buffer[frame].state],
3340 zr->v4l_pend_tail, zr->v4l_pend_head);
3341 /* Process is the one capturing? */
3342 if (fh->v4l_buffers.active != ZORAN_FREE &&
3343 /* Buffer ready to DQBUF? */
3344 zr->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003345 res = POLLIN | POLLRDNORM;
Trent Piephoe42af832007-07-17 18:29:43 -03003346 spin_unlock_irqrestore(&zr->spinlock, flags);
3347
Linus Torvalds1da177e2005-04-16 15:20:36 -07003348 break;
3349
3350 case ZORAN_MAP_MODE_JPG_REC:
3351 case ZORAN_MAP_MODE_JPG_PLAY:
Trent Piephoe42af832007-07-17 18:29:43 -03003352 poll_wait(file, &zr->jpg_capq, wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003353 frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME];
Trent Piephoe42af832007-07-17 18:29:43 -03003354
3355 spin_lock_irqsave(&zr->spinlock, flags);
3356 dprintk(3,
3357 KERN_DEBUG
3358 "%s: %s() jpg - active=%c, que_tail=%lu/%c, que_head=%lu, dma=%lu/%lu\n",
Harvey Harrison7e28adb2008-04-08 23:20:00 -03003359 ZR_DEVNAME(zr), __func__,
Trent Piephoe42af832007-07-17 18:29:43 -03003360 "FAL"[fh->jpg_buffers.active], zr->jpg_que_tail,
3361 "UPMD"[zr->jpg_buffers.buffer[frame].state],
3362 zr->jpg_que_head, zr->jpg_dma_tail, zr->jpg_dma_head);
3363 if (fh->jpg_buffers.active != ZORAN_FREE &&
3364 zr->jpg_buffers.buffer[frame].state == BUZ_STATE_DONE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003365 if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC)
3366 res = POLLIN | POLLRDNORM;
3367 else
3368 res = POLLOUT | POLLWRNORM;
3369 }
Trent Piephoe42af832007-07-17 18:29:43 -03003370 spin_unlock_irqrestore(&zr->spinlock, flags);
3371
Linus Torvalds1da177e2005-04-16 15:20:36 -07003372 break;
3373
3374 default:
3375 dprintk(1,
Trent Piephoe42af832007-07-17 18:29:43 -03003376 KERN_ERR
Linus Torvalds1da177e2005-04-16 15:20:36 -07003377 "%s: zoran_poll() - internal error, unknown map_mode=%d\n",
3378 ZR_DEVNAME(zr), fh->map_mode);
3379 res = POLLNVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003380 }
3381
Ingo Molnar384c3682006-03-22 03:54:16 -03003382 mutex_unlock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003383
3384 return res;
3385}
3386
3387
3388/*
3389 * This maps the buffers to user space.
3390 *
3391 * Depending on the state of fh->map_mode
3392 * the V4L or the MJPEG buffers are mapped
3393 * per buffer or all together
3394 *
3395 * Note that we need to connect to some
3396 * unmap signal event to unmap the de-allocate
3397 * the buffer accordingly (zoran_vm_close())
3398 */
3399
3400static void
3401zoran_vm_open (struct vm_area_struct *vma)
3402{
3403 struct zoran_mapping *map = vma->vm_private_data;
3404
3405 map->count++;
3406}
3407
3408static void
3409zoran_vm_close (struct vm_area_struct *vma)
3410{
3411 struct zoran_mapping *map = vma->vm_private_data;
3412 struct file *file = map->file;
3413 struct zoran_fh *fh = file->private_data;
3414 struct zoran *zr = fh->zr;
3415 int i;
3416
3417 map->count--;
3418 if (map->count == 0) {
3419 switch (fh->map_mode) {
3420 case ZORAN_MAP_MODE_JPG_REC:
3421 case ZORAN_MAP_MODE_JPG_PLAY:
3422
3423 dprintk(3, KERN_INFO "%s: munmap(MJPEG)\n",
3424 ZR_DEVNAME(zr));
3425
3426 for (i = 0; i < fh->jpg_buffers.num_buffers; i++) {
3427 if (fh->jpg_buffers.buffer[i].map == map) {
3428 fh->jpg_buffers.buffer[i].map =
3429 NULL;
3430 }
3431 }
3432 kfree(map);
3433
3434 for (i = 0; i < fh->jpg_buffers.num_buffers; i++)
3435 if (fh->jpg_buffers.buffer[i].map)
3436 break;
3437 if (i == fh->jpg_buffers.num_buffers) {
Ingo Molnar384c3682006-03-22 03:54:16 -03003438 mutex_lock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003439
3440 if (fh->jpg_buffers.active != ZORAN_FREE) {
3441 jpg_qbuf(file, -1, zr->codec_mode);
3442 zr->jpg_buffers.allocated = 0;
3443 zr->jpg_buffers.active =
3444 fh->jpg_buffers.active =
3445 ZORAN_FREE;
3446 }
Hans Verkuil96b8e142009-02-18 13:13:31 -03003447 jpg_fbuffer_free(file);
Ingo Molnar384c3682006-03-22 03:54:16 -03003448 mutex_unlock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003449 }
3450
3451 break;
3452
3453 case ZORAN_MAP_MODE_RAW:
3454
3455 dprintk(3, KERN_INFO "%s: munmap(V4L)\n",
3456 ZR_DEVNAME(zr));
3457
3458 for (i = 0; i < fh->v4l_buffers.num_buffers; i++) {
3459 if (fh->v4l_buffers.buffer[i].map == map) {
3460 /* unqueue/unmap */
3461 fh->v4l_buffers.buffer[i].map =
3462 NULL;
3463 }
3464 }
3465 kfree(map);
3466
3467 for (i = 0; i < fh->v4l_buffers.num_buffers; i++)
3468 if (fh->v4l_buffers.buffer[i].map)
3469 break;
3470 if (i == fh->v4l_buffers.num_buffers) {
Ingo Molnar384c3682006-03-22 03:54:16 -03003471 mutex_lock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003472
3473 if (fh->v4l_buffers.active != ZORAN_FREE) {
Andrew Morton81b80212008-05-14 23:14:04 -03003474 unsigned long flags;
Trent Piepho9896bbc2007-07-17 18:29:45 -03003475
3476 spin_lock_irqsave(&zr->spinlock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003477 zr36057_set_memgrab(zr, 0);
3478 zr->v4l_buffers.allocated = 0;
3479 zr->v4l_buffers.active =
3480 fh->v4l_buffers.active =
3481 ZORAN_FREE;
Trent Piepho9896bbc2007-07-17 18:29:45 -03003482 spin_unlock_irqrestore(&zr->spinlock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003483 }
Hans Verkuil96b8e142009-02-18 13:13:31 -03003484 v4l_fbuffer_free(file);
Ingo Molnar384c3682006-03-22 03:54:16 -03003485 mutex_unlock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003486 }
3487
3488 break;
3489
3490 default:
3491 printk(KERN_ERR
3492 "%s: munmap() - internal error - unknown map mode %d\n",
3493 ZR_DEVNAME(zr), fh->map_mode);
3494 break;
3495
3496 }
3497 }
3498}
3499
3500static struct vm_operations_struct zoran_vm_ops = {
3501 .open = zoran_vm_open,
3502 .close = zoran_vm_close,
3503};
3504
3505static int
3506zoran_mmap (struct file *file,
3507 struct vm_area_struct *vma)
3508{
3509 struct zoran_fh *fh = file->private_data;
3510 struct zoran *zr = fh->zr;
3511 unsigned long size = (vma->vm_end - vma->vm_start);
3512 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
3513 int i, j;
3514 unsigned long page, start = vma->vm_start, todo, pos, fraglen;
3515 int first, last;
3516 struct zoran_mapping *map;
3517 int res = 0;
3518
3519 dprintk(3,
3520 KERN_INFO "%s: mmap(%s) of 0x%08lx-0x%08lx (size=%lu)\n",
3521 ZR_DEVNAME(zr),
3522 fh->map_mode == ZORAN_MAP_MODE_RAW ? "V4L" : "MJPEG",
3523 vma->vm_start, vma->vm_end, size);
3524
3525 if (!(vma->vm_flags & VM_SHARED) || !(vma->vm_flags & VM_READ) ||
3526 !(vma->vm_flags & VM_WRITE)) {
3527 dprintk(1,
3528 KERN_ERR
3529 "%s: mmap() - no MAP_SHARED/PROT_{READ,WRITE} given\n",
3530 ZR_DEVNAME(zr));
3531 return -EINVAL;
3532 }
3533
3534 switch (fh->map_mode) {
3535
3536 case ZORAN_MAP_MODE_JPG_REC:
3537 case ZORAN_MAP_MODE_JPG_PLAY:
3538
3539 /* lock */
Ingo Molnar384c3682006-03-22 03:54:16 -03003540 mutex_lock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003541
3542 /* Map the MJPEG buffers */
3543 if (!fh->jpg_buffers.allocated) {
3544 dprintk(1,
3545 KERN_ERR
3546 "%s: zoran_mmap(MJPEG) - buffers not yet allocated\n",
3547 ZR_DEVNAME(zr));
3548 res = -ENOMEM;
3549 goto jpg_mmap_unlock_and_return;
3550 }
3551
3552 first = offset / fh->jpg_buffers.buffer_size;
3553 last = first - 1 + size / fh->jpg_buffers.buffer_size;
3554 if (offset % fh->jpg_buffers.buffer_size != 0 ||
3555 size % fh->jpg_buffers.buffer_size != 0 || first < 0 ||
3556 last < 0 || first >= fh->jpg_buffers.num_buffers ||
3557 last >= fh->jpg_buffers.num_buffers) {
3558 dprintk(1,
3559 KERN_ERR
3560 "%s: mmap(MJPEG) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n",
3561 ZR_DEVNAME(zr), offset, size,
3562 fh->jpg_buffers.buffer_size,
3563 fh->jpg_buffers.num_buffers);
3564 res = -EINVAL;
3565 goto jpg_mmap_unlock_and_return;
3566 }
3567 for (i = first; i <= last; i++) {
3568 if (fh->jpg_buffers.buffer[i].map) {
3569 dprintk(1,
3570 KERN_ERR
3571 "%s: mmap(MJPEG) - buffer %d already mapped\n",
3572 ZR_DEVNAME(zr), i);
3573 res = -EBUSY;
3574 goto jpg_mmap_unlock_and_return;
3575 }
3576 }
3577
3578 /* map these buffers (v4l_buffers[i]) */
3579 map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL);
3580 if (!map) {
3581 res = -ENOMEM;
3582 goto jpg_mmap_unlock_and_return;
3583 }
3584 map->file = file;
3585 map->count = 1;
3586
3587 vma->vm_ops = &zoran_vm_ops;
3588 vma->vm_flags |= VM_DONTEXPAND;
3589 vma->vm_private_data = map;
3590
3591 for (i = first; i <= last; i++) {
3592 for (j = 0;
3593 j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
3594 j++) {
3595 fraglen =
3596 (le32_to_cpu(fh->jpg_buffers.buffer[i].
3597 frag_tab[2 * j + 1]) & ~1) << 1;
3598 todo = size;
3599 if (todo > fraglen)
3600 todo = fraglen;
3601 pos =
Al Viro581a7f12008-05-21 00:32:31 -03003602 le32_to_cpu(fh->jpg_buffers.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003603 buffer[i].frag_tab[2 * j]);
3604 /* should just be pos on i386 */
3605 page = virt_to_phys(bus_to_virt(pos))
3606 >> PAGE_SHIFT;
3607 if (remap_pfn_range(vma, start, page,
3608 todo, PAGE_SHARED)) {
3609 dprintk(1,
3610 KERN_ERR
3611 "%s: zoran_mmap(V4L) - remap_pfn_range failed\n",
3612 ZR_DEVNAME(zr));
3613 res = -EAGAIN;
3614 goto jpg_mmap_unlock_and_return;
3615 }
3616 size -= todo;
3617 start += todo;
3618 if (size == 0)
3619 break;
3620 if (le32_to_cpu(fh->jpg_buffers.buffer[i].
3621 frag_tab[2 * j + 1]) & 1)
3622 break; /* was last fragment */
3623 }
3624 fh->jpg_buffers.buffer[i].map = map;
3625 if (size == 0)
3626 break;
3627
3628 }
3629 jpg_mmap_unlock_and_return:
Ingo Molnar384c3682006-03-22 03:54:16 -03003630 mutex_unlock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003631
3632 break;
3633
3634 case ZORAN_MAP_MODE_RAW:
3635
Ingo Molnar384c3682006-03-22 03:54:16 -03003636 mutex_lock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003637
3638 /* Map the V4L buffers */
3639 if (!fh->v4l_buffers.allocated) {
3640 dprintk(1,
3641 KERN_ERR
3642 "%s: zoran_mmap(V4L) - buffers not yet allocated\n",
3643 ZR_DEVNAME(zr));
3644 res = -ENOMEM;
3645 goto v4l_mmap_unlock_and_return;
3646 }
3647
3648 first = offset / fh->v4l_buffers.buffer_size;
3649 last = first - 1 + size / fh->v4l_buffers.buffer_size;
3650 if (offset % fh->v4l_buffers.buffer_size != 0 ||
3651 size % fh->v4l_buffers.buffer_size != 0 || first < 0 ||
3652 last < 0 || first >= fh->v4l_buffers.num_buffers ||
3653 last >= fh->v4l_buffers.buffer_size) {
3654 dprintk(1,
3655 KERN_ERR
3656 "%s: mmap(V4L) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n",
3657 ZR_DEVNAME(zr), offset, size,
3658 fh->v4l_buffers.buffer_size,
3659 fh->v4l_buffers.num_buffers);
3660 res = -EINVAL;
3661 goto v4l_mmap_unlock_and_return;
3662 }
3663 for (i = first; i <= last; i++) {
3664 if (fh->v4l_buffers.buffer[i].map) {
3665 dprintk(1,
3666 KERN_ERR
3667 "%s: mmap(V4L) - buffer %d already mapped\n",
3668 ZR_DEVNAME(zr), i);
3669 res = -EBUSY;
3670 goto v4l_mmap_unlock_and_return;
3671 }
3672 }
3673
3674 /* map these buffers (v4l_buffers[i]) */
3675 map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL);
3676 if (!map) {
3677 res = -ENOMEM;
3678 goto v4l_mmap_unlock_and_return;
3679 }
3680 map->file = file;
3681 map->count = 1;
3682
3683 vma->vm_ops = &zoran_vm_ops;
3684 vma->vm_flags |= VM_DONTEXPAND;
3685 vma->vm_private_data = map;
3686
3687 for (i = first; i <= last; i++) {
3688 todo = size;
3689 if (todo > fh->v4l_buffers.buffer_size)
3690 todo = fh->v4l_buffers.buffer_size;
3691 page = fh->v4l_buffers.buffer[i].fbuffer_phys;
3692 if (remap_pfn_range(vma, start, page >> PAGE_SHIFT,
3693 todo, PAGE_SHARED)) {
3694 dprintk(1,
3695 KERN_ERR
3696 "%s: zoran_mmap(V4L)i - remap_pfn_range failed\n",
3697 ZR_DEVNAME(zr));
3698 res = -EAGAIN;
3699 goto v4l_mmap_unlock_and_return;
3700 }
3701 size -= todo;
3702 start += todo;
3703 fh->v4l_buffers.buffer[i].map = map;
3704 if (size == 0)
3705 break;
3706 }
3707 v4l_mmap_unlock_and_return:
Ingo Molnar384c3682006-03-22 03:54:16 -03003708 mutex_unlock(&zr->resource_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003709
3710 break;
3711
3712 default:
3713 dprintk(1,
3714 KERN_ERR
3715 "%s: zoran_mmap() - internal error - unknown map mode %d\n",
3716 ZR_DEVNAME(zr), fh->map_mode);
3717 break;
3718 }
3719
3720 return 0;
3721}
3722
Hans Verkuil96b8e142009-02-18 13:13:31 -03003723static const struct v4l2_ioctl_ops zoran_ioctl_ops = {
3724 .vidioc_querycap = zoran_querycap,
3725 .vidioc_cropcap = zoran_cropcap,
3726 .vidioc_s_crop = zoran_s_crop,
3727 .vidioc_g_crop = zoran_g_crop,
3728 .vidioc_enum_input = zoran_enum_input,
3729 .vidioc_g_input = zoran_g_input,
3730 .vidioc_s_input = zoran_s_input,
3731 .vidioc_enum_output = zoran_enum_output,
3732 .vidioc_g_output = zoran_g_output,
3733 .vidioc_s_output = zoran_s_output,
3734 .vidioc_g_fbuf = zoran_g_fbuf,
3735 .vidioc_s_fbuf = zoran_s_fbuf,
3736 .vidioc_g_std = zoran_g_std,
3737 .vidioc_s_std = zoran_s_std,
3738 .vidioc_g_jpegcomp = zoran_g_jpegcomp,
3739 .vidioc_s_jpegcomp = zoran_s_jpegcomp,
3740 .vidioc_overlay = zoran_overlay,
3741 .vidioc_reqbufs = zoran_reqbufs,
3742 .vidioc_querybuf = zoran_querybuf,
3743 .vidioc_qbuf = zoran_qbuf,
3744 .vidioc_dqbuf = zoran_dqbuf,
3745 .vidioc_streamon = zoran_streamon,
3746 .vidioc_streamoff = zoran_streamoff,
3747 .vidioc_enum_fmt_vid_cap = zoran_enum_fmt_vid_cap,
3748 .vidioc_enum_fmt_vid_out = zoran_enum_fmt_vid_out,
3749 .vidioc_enum_fmt_vid_overlay = zoran_enum_fmt_vid_overlay,
3750 .vidioc_g_fmt_vid_cap = zoran_g_fmt_vid_cap,
3751 .vidioc_g_fmt_vid_out = zoran_g_fmt_vid_out,
3752 .vidioc_g_fmt_vid_overlay = zoran_g_fmt_vid_overlay,
3753 .vidioc_s_fmt_vid_cap = zoran_s_fmt_vid_cap,
3754 .vidioc_s_fmt_vid_out = zoran_s_fmt_vid_out,
3755 .vidioc_s_fmt_vid_overlay = zoran_s_fmt_vid_overlay,
3756 .vidioc_try_fmt_vid_cap = zoran_try_fmt_vid_cap,
3757 .vidioc_try_fmt_vid_out = zoran_try_fmt_vid_out,
3758 .vidioc_try_fmt_vid_overlay = zoran_try_fmt_vid_overlay,
3759 .vidioc_queryctrl = zoran_queryctrl,
3760 .vidioc_s_ctrl = zoran_s_ctrl,
3761 .vidioc_g_ctrl = zoran_g_ctrl,
Hans Verkuildcbd83b2009-02-18 13:51:13 -03003762#ifdef CONFIG_VIDEO_V4L1_COMPAT
Hans Verkuil96b8e142009-02-18 13:13:31 -03003763 .vidioc_default = zoran_default,
Hans Verkuildcbd83b2009-02-18 13:51:13 -03003764 .vidiocgmbuf = zoran_vidiocgmbuf,
3765#endif
Hans Verkuil96b8e142009-02-18 13:13:31 -03003766};
3767
Hans Verkuilbec43662008-12-30 06:58:20 -03003768static const struct v4l2_file_operations zoran_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003769 .owner = THIS_MODULE,
3770 .open = zoran_open,
3771 .release = zoran_close,
Hans Verkuil96b8e142009-02-18 13:13:31 -03003772 .ioctl = video_ioctl2,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003773 .read = zoran_read,
3774 .write = zoran_write,
3775 .mmap = zoran_mmap,
3776 .poll = zoran_poll,
3777};
3778
3779struct video_device zoran_template __devinitdata = {
3780 .name = ZORAN_NAME,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003781 .fops = &zoran_fops,
Hans Verkuil96b8e142009-02-18 13:13:31 -03003782 .ioctl_ops = &zoran_ioctl_ops,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003783 .release = &zoran_vdev_release,
Hans Verkuil96b8e142009-02-18 13:13:31 -03003784 .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003785 .minor = -1
3786};
3787