1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Zoran zr36057/zr36067 PCI controller driver, for the
4 * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
5 * Media Labs LML33/LML33R10.
7 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9 * Changes for BUZ by Wolfgang Scherr <scherr@net4you.net>
11 * Changes for DC10/DC30 by Laurent Pinchart <laurent.pinchart@skynet.be>
13 * Changes for LML33R10 by Maxim Yevtyushkin <max@linuxmedialabs.com>
15 * Changes for videodev2/v4l2 by Ronald Bultje <rbultje@ronald.bitfreak.net>
20 * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
22 * Iomega Buz driver version 1.0
23 * Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de>
26 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
28 * bttv - Bt848 frame grabber driver
29 * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
30 * & Marcus Metzler (mocm@thp.uni-koeln.de)
33 #include <linux/init.h>
34 #include <linux/module.h>
35 #include <linux/delay.h>
36 #include <linux/slab.h>
37 #include <linux/pci.h>
38 #include <linux/wait.h>
40 #include <linux/interrupt.h>
41 #include <linux/i2c.h>
42 #include <linux/i2c-algo-bit.h>
44 #include <linux/spinlock.h>
46 #include <linux/videodev2.h>
47 #include <media/v4l2-common.h>
48 #include <media/v4l2-ioctl.h>
49 #include <media/v4l2-event.h>
50 #include "videocodec.h"
53 #include <linux/uaccess.h>
55 #include <linux/mutex.h>
57 #include "zoran_device.h"
58 #include "zoran_card.h"
60 const struct zoran_format zoran_formats
[] = {
62 .name
= "15-bit RGB LE",
63 .fourcc
= V4L2_PIX_FMT_RGB555
,
64 .colorspace
= V4L2_COLORSPACE_SRGB
,
66 .flags
= ZORAN_FORMAT_CAPTURE
,
67 .vfespfr
= ZR36057_VFESPFR_RGB555
| ZR36057_VFESPFR_ERR_DIF
|
68 ZR36057_VFESPFR_LITTLE_ENDIAN
,
70 .name
= "15-bit RGB BE",
71 .fourcc
= V4L2_PIX_FMT_RGB555X
,
72 .colorspace
= V4L2_COLORSPACE_SRGB
,
74 .flags
= ZORAN_FORMAT_CAPTURE
,
75 .vfespfr
= ZR36057_VFESPFR_RGB555
| ZR36057_VFESPFR_ERR_DIF
,
77 .name
= "16-bit RGB LE",
78 .fourcc
= V4L2_PIX_FMT_RGB565
,
79 .colorspace
= V4L2_COLORSPACE_SRGB
,
81 .flags
= ZORAN_FORMAT_CAPTURE
,
82 .vfespfr
= ZR36057_VFESPFR_RGB565
| ZR36057_VFESPFR_ERR_DIF
|
83 ZR36057_VFESPFR_LITTLE_ENDIAN
,
85 .name
= "16-bit RGB BE",
86 .fourcc
= V4L2_PIX_FMT_RGB565X
,
87 .colorspace
= V4L2_COLORSPACE_SRGB
,
89 .flags
= ZORAN_FORMAT_CAPTURE
,
90 .vfespfr
= ZR36057_VFESPFR_RGB565
| ZR36057_VFESPFR_ERR_DIF
,
93 .fourcc
= V4L2_PIX_FMT_BGR24
,
94 .colorspace
= V4L2_COLORSPACE_SRGB
,
96 .flags
= ZORAN_FORMAT_CAPTURE
,
97 .vfespfr
= ZR36057_VFESPFR_RGB888
| ZR36057_VFESPFR_PACK24
,
99 .name
= "32-bit RGB LE",
100 .fourcc
= V4L2_PIX_FMT_BGR32
,
101 .colorspace
= V4L2_COLORSPACE_SRGB
,
103 .flags
= ZORAN_FORMAT_CAPTURE
,
104 .vfespfr
= ZR36057_VFESPFR_RGB888
| ZR36057_VFESPFR_LITTLE_ENDIAN
,
106 .name
= "32-bit RGB BE",
107 .fourcc
= V4L2_PIX_FMT_RGB32
,
108 .colorspace
= V4L2_COLORSPACE_SRGB
,
110 .flags
= ZORAN_FORMAT_CAPTURE
,
111 .vfespfr
= ZR36057_VFESPFR_RGB888
,
113 .name
= "4:2:2, packed, YUYV",
114 .fourcc
= V4L2_PIX_FMT_YUYV
,
115 .colorspace
= V4L2_COLORSPACE_SMPTE170M
,
117 .flags
= ZORAN_FORMAT_CAPTURE
,
118 .vfespfr
= ZR36057_VFESPFR_YUV422
,
120 .name
= "4:2:2, packed, UYVY",
121 .fourcc
= V4L2_PIX_FMT_UYVY
,
122 .colorspace
= V4L2_COLORSPACE_SMPTE170M
,
124 .flags
= ZORAN_FORMAT_CAPTURE
,
125 .vfespfr
= ZR36057_VFESPFR_YUV422
| ZR36057_VFESPFR_LITTLE_ENDIAN
,
127 .name
= "Hardware-encoded Motion-JPEG",
128 .fourcc
= V4L2_PIX_FMT_MJPEG
,
129 .colorspace
= V4L2_COLORSPACE_SMPTE170M
,
131 .flags
= ZORAN_FORMAT_CAPTURE
|
132 ZORAN_FORMAT_PLAYBACK
|
133 ZORAN_FORMAT_COMPRESSED
,
137 #define NUM_FORMATS ARRAY_SIZE(zoran_formats)
140 * small helper function for calculating buffersizes for v4l2
141 * we calculate the nearest higher power-of-two, which
142 * will be the recommended buffersize
144 static __u32
zoran_v4l2_calc_bufsize(struct zoran_jpg_settings
*settings
)
146 __u8 div
= settings
->ver_dcm
* settings
->hor_dcm
* settings
->tmp_dcm
;
147 __u32 num
= (1024 * 512) / (div
);
163 * V4L Buffer grabbing
165 static int zoran_v4l_set_format(struct zoran
*zr
, int width
, int height
,
166 const struct zoran_format
*format
)
170 /* Check size and format of the grab wanted */
172 if (height
< BUZ_MIN_HEIGHT
|| width
< BUZ_MIN_WIDTH
||
173 height
> BUZ_MAX_HEIGHT
|| width
> BUZ_MAX_WIDTH
) {
174 pci_dbg(zr
->pci_dev
, "%s - wrong frame size (%dx%d)\n", __func__
, width
, height
);
178 bpp
= (format
->depth
+ 7) / 8;
180 zr
->buffer_size
= height
* width
* bpp
;
182 /* Check against available buffer size */
183 if (height
* width
* bpp
> zr
->buffer_size
) {
184 pci_dbg(zr
->pci_dev
, "%s - video buffer size (%d kB) is too small\n",
185 __func__
, zr
->buffer_size
>> 10);
189 /* The video front end needs 4-byte alinged line sizes */
191 if ((bpp
== 2 && (width
& 1)) || (bpp
== 3 && (width
& 3))) {
192 pci_dbg(zr
->pci_dev
, "%s - wrong frame alignment\n", __func__
);
196 zr
->v4l_settings
.width
= width
;
197 zr
->v4l_settings
.height
= height
;
198 zr
->v4l_settings
.format
= format
;
199 zr
->v4l_settings
.bytesperline
= bpp
* zr
->v4l_settings
.width
;
204 static int zoran_set_norm(struct zoran
*zr
, v4l2_std_id norm
)
206 if (!(norm
& zr
->card
.norms
)) {
207 pci_dbg(zr
->pci_dev
, "%s - unsupported norm %llx\n", __func__
, norm
);
211 if (norm
& V4L2_STD_SECAM
)
212 zr
->timing
= zr
->card
.tvn
[ZR_NORM_SECAM
];
213 else if (norm
& V4L2_STD_NTSC
)
214 zr
->timing
= zr
->card
.tvn
[ZR_NORM_NTSC
];
216 zr
->timing
= zr
->card
.tvn
[ZR_NORM_PAL
];
218 decoder_call(zr
, video
, s_std
, norm
);
219 encoder_call(zr
, video
, s_std_output
, norm
);
221 /* Make sure the changes come into effect */
227 static int zoran_set_input(struct zoran
*zr
, int input
)
229 if (input
== zr
->input
)
232 if (input
< 0 || input
>= zr
->card
.inputs
) {
233 pci_dbg(zr
->pci_dev
, "%s - unsupported input %d\n", __func__
, input
);
239 decoder_call(zr
, video
, s_routing
, zr
->card
.input
[input
].muxsel
, 0, 0);
248 static int zoran_querycap(struct file
*file
, void *__fh
, struct v4l2_capability
*cap
)
250 struct zoran
*zr
= video_drvdata(file
);
252 strscpy(cap
->card
, ZR_DEVNAME(zr
), sizeof(cap
->card
));
253 strscpy(cap
->driver
, "zoran", sizeof(cap
->driver
));
254 snprintf(cap
->bus_info
, sizeof(cap
->bus_info
), "PCI:%s", pci_name(zr
->pci_dev
));
258 static int zoran_enum_fmt(struct zoran
*zr
, struct v4l2_fmtdesc
*fmt
, int flag
)
262 if (fmt
->index
>= ARRAY_SIZE(zoran_formats
))
264 if (fmt
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
267 for (num
= i
= 0; i
< NUM_FORMATS
; i
++) {
268 if (zoran_formats
[i
].flags
& flag
&& num
++ == fmt
->index
) {
269 strscpy(fmt
->description
, zoran_formats
[i
].name
,
270 sizeof(fmt
->description
));
271 /* fmt struct pre-zeroed, so adding '\0' not needed */
272 fmt
->pixelformat
= zoran_formats
[i
].fourcc
;
273 if (zoran_formats
[i
].flags
& ZORAN_FORMAT_COMPRESSED
)
274 fmt
->flags
|= V4L2_FMT_FLAG_COMPRESSED
;
281 static int zoran_enum_fmt_vid_cap(struct file
*file
, void *__fh
,
282 struct v4l2_fmtdesc
*f
)
284 struct zoran
*zr
= video_drvdata(file
);
286 return zoran_enum_fmt(zr
, f
, ZORAN_FORMAT_CAPTURE
);
289 static int zoran_g_fmt_vid_out(struct file
*file
, void *__fh
,
290 struct v4l2_format
*fmt
)
292 struct zoran
*zr
= video_drvdata(file
);
294 fmt
->fmt
.pix
.width
= zr
->jpg_settings
.img_width
/ zr
->jpg_settings
.hor_dcm
;
295 fmt
->fmt
.pix
.height
= zr
->jpg_settings
.img_height
* 2 /
296 (zr
->jpg_settings
.ver_dcm
* zr
->jpg_settings
.tmp_dcm
);
297 fmt
->fmt
.pix
.sizeimage
= zr
->buffer_size
;
298 fmt
->fmt
.pix
.pixelformat
= V4L2_PIX_FMT_MJPEG
;
299 if (zr
->jpg_settings
.tmp_dcm
== 1)
300 fmt
->fmt
.pix
.field
= (zr
->jpg_settings
.odd_even
?
301 V4L2_FIELD_SEQ_TB
: V4L2_FIELD_SEQ_BT
);
303 fmt
->fmt
.pix
.field
= (zr
->jpg_settings
.odd_even
?
304 V4L2_FIELD_TOP
: V4L2_FIELD_BOTTOM
);
305 fmt
->fmt
.pix
.bytesperline
= 0;
306 fmt
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SMPTE170M
;
311 static int zoran_g_fmt_vid_cap(struct file
*file
, void *__fh
,
312 struct v4l2_format
*fmt
)
314 struct zoran
*zr
= video_drvdata(file
);
316 if (zr
->map_mode
!= ZORAN_MAP_MODE_RAW
)
317 return zoran_g_fmt_vid_out(file
, __fh
, fmt
);
318 fmt
->fmt
.pix
.width
= zr
->v4l_settings
.width
;
319 fmt
->fmt
.pix
.height
= zr
->v4l_settings
.height
;
320 fmt
->fmt
.pix
.sizeimage
= zr
->buffer_size
;
321 fmt
->fmt
.pix
.pixelformat
= zr
->v4l_settings
.format
->fourcc
;
322 fmt
->fmt
.pix
.colorspace
= zr
->v4l_settings
.format
->colorspace
;
323 fmt
->fmt
.pix
.bytesperline
= zr
->v4l_settings
.bytesperline
;
324 if (BUZ_MAX_HEIGHT
< (zr
->v4l_settings
.height
* 2))
325 fmt
->fmt
.pix
.field
= V4L2_FIELD_INTERLACED
;
327 fmt
->fmt
.pix
.field
= V4L2_FIELD_TOP
;
331 static int zoran_try_fmt_vid_out(struct file
*file
, void *__fh
,
332 struct v4l2_format
*fmt
)
334 struct zoran
*zr
= video_drvdata(file
);
335 struct zoran_jpg_settings settings
;
338 if (fmt
->fmt
.pix
.pixelformat
!= V4L2_PIX_FMT_MJPEG
)
341 settings
= zr
->jpg_settings
;
343 /* we actually need to set 'real' parameters now */
344 if ((fmt
->fmt
.pix
.height
* 2) > BUZ_MAX_HEIGHT
)
345 settings
.tmp_dcm
= 1;
347 settings
.tmp_dcm
= 2;
348 settings
.decimation
= 0;
349 if (fmt
->fmt
.pix
.height
<= zr
->jpg_settings
.img_height
/ 2)
350 settings
.ver_dcm
= 2;
352 settings
.ver_dcm
= 1;
353 if (fmt
->fmt
.pix
.width
<= zr
->jpg_settings
.img_width
/ 4)
354 settings
.hor_dcm
= 4;
355 else if (fmt
->fmt
.pix
.width
<= zr
->jpg_settings
.img_width
/ 2)
356 settings
.hor_dcm
= 2;
358 settings
.hor_dcm
= 1;
359 if (settings
.tmp_dcm
== 1)
360 settings
.field_per_buff
= 2;
362 settings
.field_per_buff
= 1;
364 if (settings
.hor_dcm
> 1) {
365 settings
.img_x
= (BUZ_MAX_WIDTH
== 720) ? 8 : 0;
366 settings
.img_width
= (BUZ_MAX_WIDTH
== 720) ? 704 : BUZ_MAX_WIDTH
;
369 settings
.img_width
= BUZ_MAX_WIDTH
;
373 res
= zoran_check_jpg_settings(zr
, &settings
, 1);
377 /* tell the user what we actually did */
378 fmt
->fmt
.pix
.width
= settings
.img_width
/ settings
.hor_dcm
;
379 fmt
->fmt
.pix
.height
= settings
.img_height
* 2 /
380 (settings
.tmp_dcm
* settings
.ver_dcm
);
381 if (settings
.tmp_dcm
== 1)
382 fmt
->fmt
.pix
.field
= (zr
->jpg_settings
.odd_even
?
383 V4L2_FIELD_SEQ_TB
: V4L2_FIELD_SEQ_BT
);
385 fmt
->fmt
.pix
.field
= (zr
->jpg_settings
.odd_even
?
386 V4L2_FIELD_TOP
: V4L2_FIELD_BOTTOM
);
388 fmt
->fmt
.pix
.sizeimage
= zoran_v4l2_calc_bufsize(&settings
);
389 fmt
->fmt
.pix
.bytesperline
= 0;
390 fmt
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SMPTE170M
;
394 static int zoran_try_fmt_vid_cap(struct file
*file
, void *__fh
,
395 struct v4l2_format
*fmt
)
397 struct zoran
*zr
= video_drvdata(file
);
401 if (fmt
->fmt
.pix
.pixelformat
== V4L2_PIX_FMT_MJPEG
)
402 return zoran_try_fmt_vid_out(file
, __fh
, fmt
);
404 for (i
= 0; i
< NUM_FORMATS
; i
++)
405 if (zoran_formats
[i
].fourcc
== fmt
->fmt
.pix
.pixelformat
)
408 if (i
== NUM_FORMATS
) {
409 /* TODO do not return here to fix the TRY_FMT cannot handle an invalid pixelformat*/
413 fmt
->fmt
.pix
.pixelformat
= zoran_formats
[i
].fourcc
;
414 fmt
->fmt
.pix
.colorspace
= zoran_formats
[i
].colorspace
;
415 if (BUZ_MAX_HEIGHT
< (fmt
->fmt
.pix
.height
* 2))
416 fmt
->fmt
.pix
.field
= V4L2_FIELD_INTERLACED
;
418 fmt
->fmt
.pix
.field
= V4L2_FIELD_TOP
;
420 bpp
= DIV_ROUND_UP(zoran_formats
[i
].depth
, 8);
421 v4l_bound_align_image(&fmt
->fmt
.pix
.width
, BUZ_MIN_WIDTH
, BUZ_MAX_WIDTH
,
423 &fmt
->fmt
.pix
.height
, BUZ_MIN_HEIGHT
, BUZ_MAX_HEIGHT
,
425 fmt
->fmt
.pix
.bytesperline
= fmt
->fmt
.pix
.width
* bpp
;
426 fmt
->fmt
.pix
.sizeimage
= fmt
->fmt
.pix
.bytesperline
* fmt
->fmt
.pix
.height
;
430 static int zoran_s_fmt_vid_out(struct file
*file
, void *__fh
,
431 struct v4l2_format
*fmt
)
433 struct zoran
*zr
= video_drvdata(file
);
434 __le32 printformat
= __cpu_to_le32(fmt
->fmt
.pix
.pixelformat
);
435 struct zoran_jpg_settings settings
;
438 pci_dbg(zr
->pci_dev
, "size=%dx%d, fmt=0x%x (%4.4s)\n",
439 fmt
->fmt
.pix
.width
, fmt
->fmt
.pix
.height
,
440 fmt
->fmt
.pix
.pixelformat
,
441 (char *)&printformat
);
442 if (fmt
->fmt
.pix
.pixelformat
!= V4L2_PIX_FMT_MJPEG
)
445 if (!fmt
->fmt
.pix
.height
|| !fmt
->fmt
.pix
.width
)
448 settings
= zr
->jpg_settings
;
450 /* we actually need to set 'real' parameters now */
451 if (fmt
->fmt
.pix
.height
* 2 > BUZ_MAX_HEIGHT
)
452 settings
.tmp_dcm
= 1;
454 settings
.tmp_dcm
= 2;
455 settings
.decimation
= 0;
456 if (fmt
->fmt
.pix
.height
<= zr
->jpg_settings
.img_height
/ 2)
457 settings
.ver_dcm
= 2;
459 settings
.ver_dcm
= 1;
460 if (fmt
->fmt
.pix
.width
<= zr
->jpg_settings
.img_width
/ 4)
461 settings
.hor_dcm
= 4;
462 else if (fmt
->fmt
.pix
.width
<= zr
->jpg_settings
.img_width
/ 2)
463 settings
.hor_dcm
= 2;
465 settings
.hor_dcm
= 1;
466 if (settings
.tmp_dcm
== 1)
467 settings
.field_per_buff
= 2;
469 settings
.field_per_buff
= 1;
471 if (settings
.hor_dcm
> 1) {
472 settings
.img_x
= (BUZ_MAX_WIDTH
== 720) ? 8 : 0;
473 settings
.img_width
= (BUZ_MAX_WIDTH
== 720) ? 704 : BUZ_MAX_WIDTH
;
476 settings
.img_width
= BUZ_MAX_WIDTH
;
480 res
= zoran_check_jpg_settings(zr
, &settings
, 0);
484 /* it's ok, so set them */
485 zr
->jpg_settings
= settings
;
487 if (fmt
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT
)
488 zr
->map_mode
= ZORAN_MAP_MODE_JPG_REC
;
490 zr
->map_mode
= ZORAN_MAP_MODE_JPG_PLAY
;
492 zr
->buffer_size
= zoran_v4l2_calc_bufsize(&zr
->jpg_settings
);
494 /* tell the user what we actually did */
495 fmt
->fmt
.pix
.width
= settings
.img_width
/ settings
.hor_dcm
;
496 fmt
->fmt
.pix
.height
= settings
.img_height
* 2 /
497 (settings
.tmp_dcm
* settings
.ver_dcm
);
498 if (settings
.tmp_dcm
== 1)
499 fmt
->fmt
.pix
.field
= (zr
->jpg_settings
.odd_even
?
500 V4L2_FIELD_SEQ_TB
: V4L2_FIELD_SEQ_BT
);
502 fmt
->fmt
.pix
.field
= (zr
->jpg_settings
.odd_even
?
503 V4L2_FIELD_TOP
: V4L2_FIELD_BOTTOM
);
504 fmt
->fmt
.pix
.bytesperline
= 0;
505 fmt
->fmt
.pix
.sizeimage
= zr
->buffer_size
;
506 fmt
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SMPTE170M
;
510 static int zoran_s_fmt_vid_cap(struct file
*file
, void *__fh
,
511 struct v4l2_format
*fmt
)
513 struct zoran
*zr
= video_drvdata(file
);
514 struct zoran_fh
*fh
= __fh
;
518 if (fmt
->fmt
.pix
.pixelformat
== V4L2_PIX_FMT_MJPEG
)
519 return zoran_s_fmt_vid_out(file
, fh
, fmt
);
521 for (i
= 0; i
< NUM_FORMATS
; i
++)
522 if (fmt
->fmt
.pix
.pixelformat
== zoran_formats
[i
].fourcc
)
524 if (i
== NUM_FORMATS
) {
525 pci_dbg(zr
->pci_dev
, "VIDIOC_S_FMT - unknown/unsupported format 0x%x\n",
526 fmt
->fmt
.pix
.pixelformat
);
527 /* TODO do not return here to fix the TRY_FMT cannot handle an invalid pixelformat*/
531 fmt
->fmt
.pix
.pixelformat
= zoran_formats
[i
].fourcc
;
532 if (fmt
->fmt
.pix
.height
> BUZ_MAX_HEIGHT
)
533 fmt
->fmt
.pix
.height
= BUZ_MAX_HEIGHT
;
534 if (fmt
->fmt
.pix
.width
> BUZ_MAX_WIDTH
)
535 fmt
->fmt
.pix
.width
= BUZ_MAX_WIDTH
;
536 if (fmt
->fmt
.pix
.height
< BUZ_MIN_HEIGHT
)
537 fmt
->fmt
.pix
.height
= BUZ_MIN_HEIGHT
;
538 if (fmt
->fmt
.pix
.width
< BUZ_MIN_WIDTH
)
539 fmt
->fmt
.pix
.width
= BUZ_MIN_WIDTH
;
541 zr
->map_mode
= ZORAN_MAP_MODE_RAW
;
543 res
= zoran_v4l_set_format(zr
, fmt
->fmt
.pix
.width
, fmt
->fmt
.pix
.height
,
548 /* tell the user the results/missing stuff */
549 fmt
->fmt
.pix
.bytesperline
= zr
->v4l_settings
.bytesperline
;
550 fmt
->fmt
.pix
.sizeimage
= zr
->buffer_size
;
551 fmt
->fmt
.pix
.colorspace
= zr
->v4l_settings
.format
->colorspace
;
552 if (BUZ_MAX_HEIGHT
< (zr
->v4l_settings
.height
* 2))
553 fmt
->fmt
.pix
.field
= V4L2_FIELD_INTERLACED
;
555 fmt
->fmt
.pix
.field
= V4L2_FIELD_TOP
;
559 static int zoran_g_std(struct file
*file
, void *__fh
, v4l2_std_id
*std
)
561 struct zoran
*zr
= video_drvdata(file
);
567 static int zoran_s_std(struct file
*file
, void *__fh
, v4l2_std_id std
)
569 struct zoran
*zr
= video_drvdata(file
);
575 if (zr
->running
!= ZORAN_MAP_MODE_NONE
)
578 res
= zoran_set_norm(zr
, std
);
582 static int zoran_enum_input(struct file
*file
, void *__fh
,
583 struct v4l2_input
*inp
)
585 struct zoran
*zr
= video_drvdata(file
);
587 if (inp
->index
>= zr
->card
.inputs
)
590 strscpy(inp
->name
, zr
->card
.input
[inp
->index
].name
, sizeof(inp
->name
));
591 inp
->type
= V4L2_INPUT_TYPE_CAMERA
;
592 inp
->std
= V4L2_STD_NTSC
| V4L2_STD_PAL
| V4L2_STD_SECAM
;
594 /* Get status of video decoder */
595 decoder_call(zr
, video
, g_input_status
, &inp
->status
);
599 static int zoran_g_input(struct file
*file
, void *__fh
, unsigned int *input
)
601 struct zoran
*zr
= video_drvdata(file
);
608 static int zoran_s_input(struct file
*file
, void *__fh
, unsigned int input
)
610 struct zoran
*zr
= video_drvdata(file
);
613 if (zr
->running
!= ZORAN_MAP_MODE_NONE
)
616 res
= zoran_set_input(zr
, input
);
620 /* cropping (sub-frame capture) */
621 static int zoran_g_selection(struct file
*file
, void *__fh
, struct v4l2_selection
*sel
)
623 struct zoran
*zr
= video_drvdata(file
);
625 if (sel
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
&&
626 sel
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
) {
627 pci_dbg(zr
->pci_dev
, "%s invalid selection type combination\n", __func__
);
631 switch (sel
->target
) {
632 case V4L2_SEL_TGT_CROP
:
633 sel
->r
.top
= zr
->jpg_settings
.img_y
;
634 sel
->r
.left
= zr
->jpg_settings
.img_x
;
635 sel
->r
.width
= zr
->jpg_settings
.img_width
;
636 sel
->r
.height
= zr
->jpg_settings
.img_height
;
638 case V4L2_SEL_TGT_CROP_DEFAULT
:
641 sel
->r
.width
= BUZ_MIN_WIDTH
;
642 sel
->r
.height
= BUZ_MIN_HEIGHT
;
644 case V4L2_SEL_TGT_CROP_BOUNDS
:
647 sel
->r
.width
= BUZ_MAX_WIDTH
;
648 sel
->r
.height
= BUZ_MAX_HEIGHT
;
656 static int zoran_s_selection(struct file
*file
, void *__fh
, struct v4l2_selection
*sel
)
658 struct zoran
*zr
= video_drvdata(file
);
659 struct zoran_jpg_settings settings
;
662 if (sel
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
&&
663 sel
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
666 if (!sel
->r
.width
|| !sel
->r
.height
)
669 if (sel
->target
!= V4L2_SEL_TGT_CROP
)
672 if (zr
->map_mode
== ZORAN_MAP_MODE_RAW
) {
673 pci_dbg(zr
->pci_dev
, "VIDIOC_S_SELECTION - subcapture only supported for compressed capture\n");
677 settings
= zr
->jpg_settings
;
679 /* move into a form that we understand */
680 settings
.img_x
= sel
->r
.left
;
681 settings
.img_y
= sel
->r
.top
;
682 settings
.img_width
= sel
->r
.width
;
683 settings
.img_height
= sel
->r
.height
;
686 res
= zoran_check_jpg_settings(zr
, &settings
, 0);
691 zr
->jpg_settings
= settings
;
696 * Output is disabled temporarily
697 * Zoran is picky about jpeg data it accepts. At least it seems to unsupport COM and APPn.
698 * So until a way to filter data will be done, disable output.
700 static const struct v4l2_ioctl_ops zoran_ioctl_ops
= {
701 .vidioc_querycap
= zoran_querycap
,
702 .vidioc_s_selection
= zoran_s_selection
,
703 .vidioc_g_selection
= zoran_g_selection
,
704 .vidioc_enum_input
= zoran_enum_input
,
705 .vidioc_g_input
= zoran_g_input
,
706 .vidioc_s_input
= zoran_s_input
,
707 .vidioc_g_std
= zoran_g_std
,
708 .vidioc_s_std
= zoran_s_std
,
709 .vidioc_create_bufs
= vb2_ioctl_create_bufs
,
710 .vidioc_reqbufs
= vb2_ioctl_reqbufs
,
711 .vidioc_querybuf
= vb2_ioctl_querybuf
,
712 .vidioc_qbuf
= vb2_ioctl_qbuf
,
713 .vidioc_dqbuf
= vb2_ioctl_dqbuf
,
714 .vidioc_expbuf
= vb2_ioctl_expbuf
,
715 .vidioc_streamon
= vb2_ioctl_streamon
,
716 .vidioc_streamoff
= vb2_ioctl_streamoff
,
717 .vidioc_enum_fmt_vid_cap
= zoran_enum_fmt_vid_cap
,
718 .vidioc_g_fmt_vid_cap
= zoran_g_fmt_vid_cap
,
719 .vidioc_s_fmt_vid_cap
= zoran_s_fmt_vid_cap
,
720 .vidioc_try_fmt_vid_cap
= zoran_try_fmt_vid_cap
,
721 .vidioc_subscribe_event
= v4l2_ctrl_subscribe_event
,
722 .vidioc_unsubscribe_event
= v4l2_event_unsubscribe
,
725 static const struct v4l2_file_operations zoran_fops
= {
726 .owner
= THIS_MODULE
,
727 .unlocked_ioctl
= video_ioctl2
,
728 .open
= v4l2_fh_open
,
729 .release
= vb2_fop_release
,
730 .mmap
= vb2_fop_mmap
,
731 .poll
= vb2_fop_poll
,
734 const struct video_device zoran_template
= {
737 .ioctl_ops
= &zoran_ioctl_ops
,
738 .release
= &zoran_vdev_release
,
739 .tvnorms
= V4L2_STD_NTSC
| V4L2_STD_PAL
| V4L2_STD_SECAM
,
742 static int zr_vb2_queue_setup(struct vb2_queue
*vq
, unsigned int *nbuffers
, unsigned int *nplanes
,
743 unsigned int sizes
[], struct device
*alloc_devs
[])
745 struct zoran
*zr
= vb2_get_drv_priv(vq
);
746 unsigned int size
= zr
->buffer_size
;
748 pci_dbg(zr
->pci_dev
, "%s nbuf=%u nplanes=%u", __func__
, *nbuffers
, *nplanes
);
750 zr
->buf_in_reserve
= 0;
752 if (*nbuffers
< vq
->min_queued_buffers
)
753 *nbuffers
= vq
->min_queued_buffers
;
768 static void zr_vb2_queue(struct vb2_buffer
*vb
)
770 struct zoran
*zr
= vb2_get_drv_priv(vb
->vb2_queue
);
771 struct zr_buffer
*buf
= vb2_to_zr_buffer(vb
);
774 spin_lock_irqsave(&zr
->queued_bufs_lock
, flags
);
775 list_add_tail(&buf
->queue
, &zr
->queued_bufs
);
776 zr
->buf_in_reserve
++;
777 spin_unlock_irqrestore(&zr
->queued_bufs_lock
, flags
);
778 if (zr
->running
== ZORAN_MAP_MODE_JPG_REC
)
779 zoran_feed_stat_com(zr
);
783 static int zr_vb2_prepare(struct vb2_buffer
*vb
)
785 struct zoran
*zr
= vb2_get_drv_priv(vb
->vb2_queue
);
787 if (vb2_plane_size(vb
, 0) < zr
->buffer_size
)
794 int zr_set_buf(struct zoran
*zr
)
796 struct zr_buffer
*buf
;
797 struct vb2_v4l2_buffer
*vbuf
;
798 dma_addr_t phys_addr
;
802 if (zr
->running
== ZORAN_MAP_MODE_NONE
)
807 buf
->vbuf
.vb2_buf
.timestamp
= ktime_get_ns();
808 buf
->vbuf
.sequence
= zr
->vbseq
++;
811 buf
->vbuf
.field
= V4L2_FIELD_INTERLACED
;
812 if (BUZ_MAX_HEIGHT
< (zr
->v4l_settings
.height
* 2))
813 buf
->vbuf
.field
= V4L2_FIELD_INTERLACED
;
815 buf
->vbuf
.field
= V4L2_FIELD_TOP
;
816 vb2_set_plane_payload(&buf
->vbuf
.vb2_buf
, 0, zr
->buffer_size
);
817 vb2_buffer_done(&buf
->vbuf
.vb2_buf
, VB2_BUF_STATE_DONE
);
821 spin_lock_irqsave(&zr
->queued_bufs_lock
, flags
);
822 if (list_empty(&zr
->queued_bufs
)) {
823 btand(~ZR36057_ICR_INT_PIN_EN
, ZR36057_ICR
);
824 vb2_queue_error(zr
->video_dev
->queue
);
825 spin_unlock_irqrestore(&zr
->queued_bufs_lock
, flags
);
828 buf
= list_first_entry_or_null(&zr
->queued_bufs
, struct zr_buffer
, queue
);
830 btand(~ZR36057_ICR_INT_PIN_EN
, ZR36057_ICR
);
831 vb2_queue_error(zr
->video_dev
->queue
);
832 spin_unlock_irqrestore(&zr
->queued_bufs_lock
, flags
);
835 list_del(&buf
->queue
);
836 zr
->buf_in_reserve
--;
837 spin_unlock_irqrestore(&zr
->queued_bufs_lock
, flags
);
840 vbuf
->vb2_buf
.state
= VB2_BUF_STATE_ACTIVE
;
841 phys_addr
= vb2_dma_contig_plane_dma_addr(&vbuf
->vb2_buf
, 0);
849 btwrite(reg
, ZR36057_VDTR
);
850 if (zr
->v4l_settings
.height
> BUZ_MAX_HEIGHT
/ 2)
851 reg
+= zr
->v4l_settings
.bytesperline
;
852 btwrite(reg
, ZR36057_VDBR
);
855 if (zr
->v4l_settings
.height
> BUZ_MAX_HEIGHT
/ 2)
856 reg
+= zr
->v4l_settings
.bytesperline
;
857 reg
= (reg
<< ZR36057_VSSFGR_DISP_STRIDE
);
858 reg
|= ZR36057_VSSFGR_VID_OVF
;
859 reg
|= ZR36057_VSSFGR_SNAP_SHOT
;
860 reg
|= ZR36057_VSSFGR_FRAME_GRAB
;
861 btwrite(reg
, ZR36057_VSSFGR
);
863 btor(ZR36057_VDCR_VID_EN
, ZR36057_VDCR
);
867 static int zr_vb2_start_streaming(struct vb2_queue
*vq
, unsigned int count
)
869 struct zoran
*zr
= vq
->drv_priv
;
872 for (j
= 0; j
< BUZ_NUM_STAT_COM
; j
++) {
873 zr
->stat_com
[j
] = cpu_to_le32(1);
878 if (zr
->map_mode
!= ZORAN_MAP_MODE_RAW
) {
879 pci_dbg(zr
->pci_dev
, "START JPG\n");
881 zoran_init_hardware(zr
);
882 if (zr
->map_mode
== ZORAN_MAP_MODE_JPG_REC
)
883 zr36057_enable_jpg(zr
, BUZ_MODE_MOTION_DECOMPRESS
);
885 zr36057_enable_jpg(zr
, BUZ_MODE_MOTION_COMPRESS
);
886 zoran_feed_stat_com(zr
);
888 zr
->running
= zr
->map_mode
;
889 btor(ZR36057_ICR_INT_PIN_EN
, ZR36057_ICR
);
893 pci_dbg(zr
->pci_dev
, "START RAW\n");
895 zoran_init_hardware(zr
);
897 zr36057_enable_jpg(zr
, BUZ_MODE_IDLE
);
898 zr36057_set_memgrab(zr
, 1);
899 zr
->running
= zr
->map_mode
;
900 btor(ZR36057_ICR_INT_PIN_EN
, ZR36057_ICR
);
904 static void zr_vb2_stop_streaming(struct vb2_queue
*vq
)
906 struct zoran
*zr
= vq
->drv_priv
;
907 struct zr_buffer
*buf
;
911 btand(~ZR36057_ICR_INT_PIN_EN
, ZR36057_ICR
);
912 if (zr
->map_mode
!= ZORAN_MAP_MODE_RAW
)
913 zr36057_enable_jpg(zr
, BUZ_MODE_IDLE
);
914 zr36057_set_memgrab(zr
, 0);
915 zr
->running
= ZORAN_MAP_MODE_NONE
;
917 zoran_set_pci_master(zr
, 0);
919 if (!pass_through
) { /* Switch to color bar */
920 decoder_call(zr
, video
, s_stream
, 0);
921 encoder_call(zr
, video
, s_routing
, 2, 0, 0);
924 for (j
= 0; j
< BUZ_NUM_STAT_COM
; j
++) {
925 zr
->stat_com
[j
] = cpu_to_le32(1);
929 pci_dbg(zr
->pci_dev
, "%s clean buf %d\n", __func__
, j
);
930 vb2_buffer_done(&buf
->vbuf
.vb2_buf
, VB2_BUF_STATE_ERROR
);
934 spin_lock_irqsave(&zr
->queued_bufs_lock
, flags
);
935 while (!list_empty(&zr
->queued_bufs
)) {
936 buf
= list_entry(zr
->queued_bufs
.next
, struct zr_buffer
, queue
);
937 list_del(&buf
->queue
);
938 vb2_buffer_done(&buf
->vbuf
.vb2_buf
, VB2_BUF_STATE_ERROR
);
939 zr
->buf_in_reserve
--;
941 spin_unlock_irqrestore(&zr
->queued_bufs_lock
, flags
);
942 if (zr
->buf_in_reserve
)
943 pci_dbg(zr
->pci_dev
, "Buffer remaining %d\n", zr
->buf_in_reserve
);
944 zr
->map_mode
= ZORAN_MAP_MODE_RAW
;
947 static const struct vb2_ops zr_video_qops
= {
948 .queue_setup
= zr_vb2_queue_setup
,
949 .buf_queue
= zr_vb2_queue
,
950 .buf_prepare
= zr_vb2_prepare
,
951 .start_streaming
= zr_vb2_start_streaming
,
952 .stop_streaming
= zr_vb2_stop_streaming
,
953 .wait_prepare
= vb2_ops_wait_prepare
,
954 .wait_finish
= vb2_ops_wait_finish
,
957 int zoran_queue_init(struct zoran
*zr
, struct vb2_queue
*vq
, int dir
)
961 spin_lock_init(&zr
->queued_bufs_lock
);
962 INIT_LIST_HEAD(&zr
->queued_bufs
);
964 vq
->dev
= &zr
->pci_dev
->dev
;
967 vq
->io_modes
= VB2_DMABUF
| VB2_MMAP
;
969 vq
->buf_struct_size
= sizeof(struct zr_buffer
);
970 vq
->ops
= &zr_video_qops
;
971 vq
->mem_ops
= &vb2_dma_contig_memops
;
972 vq
->gfp_flags
= GFP_DMA32
;
973 vq
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
;
974 vq
->min_queued_buffers
= 9;
975 vq
->lock
= &zr
->lock
;
976 err
= vb2_queue_init(vq
);
979 zr
->video_dev
->queue
= vq
;
983 void zoran_queue_exit(struct zoran
*zr
)
985 vb2_queue_release(zr
->video_dev
->queue
);