xref: /linux/drivers/media/pci/zoran/zoran_driver.c (revision 5d435a3f7b6cb1db566d0f56f5f8dc33be0dde69)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Zoran zr36057/zr36067 PCI controller driver, for the
4  * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
5  * Media Labs LML33/LML33R10.
6  *
7  * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
8  *
9  * Changes for BUZ by Wolfgang Scherr <scherr@net4you.net>
10  *
11  * Changes for DC10/DC30 by Laurent Pinchart <laurent.pinchart@skynet.be>
12  *
13  * Changes for LML33R10 by Maxim Yevtyushkin <max@linuxmedialabs.com>
14  *
15  * Changes for videodev2/v4l2 by Ronald Bultje <rbultje@ronald.bitfreak.net>
16  *
17  * Based on
18  *
19  * Miro DC10 driver
20  * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
21  *
22  * Iomega Buz driver version 1.0
23  * Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de>
24  *
25  * buz.0.0.3
26  * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
27  *
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)
31  */
32 
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>
39 
40 #include <linux/interrupt.h>
41 #include <linux/i2c.h>
42 #include <linux/i2c-algo-bit.h>
43 
44 #include <linux/spinlock.h>
45 
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"
51 
52 #include <linux/io.h>
53 #include <linux/uaccess.h>
54 
55 #include <linux/mutex.h>
56 #include "zoran.h"
57 #include "zoran_device.h"
58 #include "zoran_card.h"
59 
60 const struct zoran_format zoran_formats[] = {
61 	{
62 		.name = "15-bit RGB LE",
63 		.fourcc = V4L2_PIX_FMT_RGB555,
64 		.colorspace = V4L2_COLORSPACE_SRGB,
65 		.depth = 15,
66 		.flags = ZORAN_FORMAT_CAPTURE,
67 		.vfespfr = ZR36057_VFESPFR_RGB555 | ZR36057_VFESPFR_ERR_DIF |
68 			   ZR36057_VFESPFR_LITTLE_ENDIAN,
69 	}, {
70 		.name = "15-bit RGB BE",
71 		.fourcc = V4L2_PIX_FMT_RGB555X,
72 		.colorspace = V4L2_COLORSPACE_SRGB,
73 		.depth = 15,
74 		.flags = ZORAN_FORMAT_CAPTURE,
75 		.vfespfr = ZR36057_VFESPFR_RGB555 | ZR36057_VFESPFR_ERR_DIF,
76 	}, {
77 		.name = "16-bit RGB LE",
78 		.fourcc = V4L2_PIX_FMT_RGB565,
79 		.colorspace = V4L2_COLORSPACE_SRGB,
80 		.depth = 16,
81 		.flags = ZORAN_FORMAT_CAPTURE,
82 		.vfespfr = ZR36057_VFESPFR_RGB565 | ZR36057_VFESPFR_ERR_DIF |
83 			   ZR36057_VFESPFR_LITTLE_ENDIAN,
84 	}, {
85 		.name = "16-bit RGB BE",
86 		.fourcc = V4L2_PIX_FMT_RGB565X,
87 		.colorspace = V4L2_COLORSPACE_SRGB,
88 		.depth = 16,
89 		.flags = ZORAN_FORMAT_CAPTURE,
90 		.vfespfr = ZR36057_VFESPFR_RGB565 | ZR36057_VFESPFR_ERR_DIF,
91 	}, {
92 		.name = "24-bit RGB",
93 		.fourcc = V4L2_PIX_FMT_BGR24,
94 		.colorspace = V4L2_COLORSPACE_SRGB,
95 		.depth = 24,
96 		.flags = ZORAN_FORMAT_CAPTURE,
97 		.vfespfr = ZR36057_VFESPFR_RGB888 | ZR36057_VFESPFR_PACK24,
98 	}, {
99 		.name = "32-bit RGB LE",
100 		.fourcc = V4L2_PIX_FMT_BGR32,
101 		.colorspace = V4L2_COLORSPACE_SRGB,
102 		.depth = 32,
103 		.flags = ZORAN_FORMAT_CAPTURE,
104 		.vfespfr = ZR36057_VFESPFR_RGB888 | ZR36057_VFESPFR_LITTLE_ENDIAN,
105 	}, {
106 		.name = "32-bit RGB BE",
107 		.fourcc = V4L2_PIX_FMT_RGB32,
108 		.colorspace = V4L2_COLORSPACE_SRGB,
109 		.depth = 32,
110 		.flags = ZORAN_FORMAT_CAPTURE,
111 		.vfespfr = ZR36057_VFESPFR_RGB888,
112 	}, {
113 		.name = "4:2:2, packed, YUYV",
114 		.fourcc = V4L2_PIX_FMT_YUYV,
115 		.colorspace = V4L2_COLORSPACE_SMPTE170M,
116 		.depth = 16,
117 		.flags = ZORAN_FORMAT_CAPTURE,
118 		.vfespfr = ZR36057_VFESPFR_YUV422,
119 	}, {
120 		.name = "4:2:2, packed, UYVY",
121 		.fourcc = V4L2_PIX_FMT_UYVY,
122 		.colorspace = V4L2_COLORSPACE_SMPTE170M,
123 		.depth = 16,
124 		.flags = ZORAN_FORMAT_CAPTURE,
125 		.vfespfr = ZR36057_VFESPFR_YUV422 | ZR36057_VFESPFR_LITTLE_ENDIAN,
126 	}, {
127 		.name = "Hardware-encoded Motion-JPEG",
128 		.fourcc = V4L2_PIX_FMT_MJPEG,
129 		.colorspace = V4L2_COLORSPACE_SMPTE170M,
130 		.depth = 0,
131 		.flags = ZORAN_FORMAT_CAPTURE |
132 			 ZORAN_FORMAT_PLAYBACK |
133 			 ZORAN_FORMAT_COMPRESSED,
134 	}
135 };
136 
137 #define NUM_FORMATS ARRAY_SIZE(zoran_formats)
138 
139 	/*
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
143 	 */
144 static __u32 zoran_v4l2_calc_bufsize(struct zoran_jpg_settings *settings)
145 {
146 	__u8 div = settings->ver_dcm * settings->hor_dcm * settings->tmp_dcm;
147 	__u32 num = (1024 * 512) / (div);
148 	__u32 result = 2;
149 
150 	num--;
151 	while (num) {
152 		num >>= 1;
153 		result <<= 1;
154 	}
155 
156 	if (result < 8192)
157 		return 8192;
158 
159 	return result;
160 }
161 
162 /*
163  *   V4L Buffer grabbing
164  */
165 static int zoran_v4l_set_format(struct zoran *zr, int width, int height,
166 				const struct zoran_format *format)
167 {
168 	int bpp;
169 
170 	/* Check size and format of the grab wanted */
171 
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);
175 		return -EINVAL;
176 	}
177 
178 	bpp = (format->depth + 7) / 8;
179 
180 	zr->buffer_size = height * width * bpp;
181 
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);
186 		return -EINVAL;
187 	}
188 
189 	/* The video front end needs 4-byte alinged line sizes */
190 
191 	if ((bpp == 2 && (width & 1)) || (bpp == 3 && (width & 3))) {
192 		pci_dbg(zr->pci_dev, "%s - wrong frame alignment\n", __func__);
193 		return -EINVAL;
194 	}
195 
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;
200 
201 	return 0;
202 }
203 
204 static int zoran_set_norm(struct zoran *zr, v4l2_std_id norm)
205 {
206 	if (!(norm & zr->card.norms)) {
207 		pci_dbg(zr->pci_dev, "%s - unsupported norm %llx\n", __func__, norm);
208 		return -EINVAL;
209 	}
210 
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];
215 	else
216 		zr->timing = zr->card.tvn[ZR_NORM_PAL];
217 
218 	decoder_call(zr, video, s_std, norm);
219 	encoder_call(zr, video, s_std_output, norm);
220 
221 	/* Make sure the changes come into effect */
222 	zr->norm = norm;
223 
224 	return 0;
225 }
226 
227 static int zoran_set_input(struct zoran *zr, int input)
228 {
229 	if (input == zr->input)
230 		return 0;
231 
232 	if (input < 0 || input >= zr->card.inputs) {
233 		pci_dbg(zr->pci_dev, "%s - unsupported input %d\n", __func__, input);
234 		return -EINVAL;
235 	}
236 
237 	zr->input = input;
238 
239 	decoder_call(zr, video, s_routing, zr->card.input[input].muxsel, 0, 0);
240 
241 	return 0;
242 }
243 
244 /*
245  *   ioctl routine
246  */
247 
248 static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap)
249 {
250 	struct zoran *zr = video_drvdata(file);
251 
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));
255 	return 0;
256 }
257 
258 static int zoran_enum_fmt(struct zoran *zr, struct v4l2_fmtdesc *fmt, int flag)
259 {
260 	unsigned int num, i;
261 
262 	if (fmt->index >= ARRAY_SIZE(zoran_formats))
263 		return -EINVAL;
264 	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
265 		return -EINVAL;
266 
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;
275 			return 0;
276 		}
277 	}
278 	return -EINVAL;
279 }
280 
281 static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh,
282 				  struct v4l2_fmtdesc *f)
283 {
284 	struct zoran *zr = video_drvdata(file);
285 
286 	return zoran_enum_fmt(zr, f, ZORAN_FORMAT_CAPTURE);
287 }
288 
289 static int zoran_g_fmt_vid_out(struct file *file, void *__fh,
290 			       struct v4l2_format *fmt)
291 {
292 	struct zoran *zr = video_drvdata(file);
293 
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);
302 	else
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;
307 
308 	return 0;
309 }
310 
311 static int zoran_g_fmt_vid_cap(struct file *file, void *__fh,
312 			       struct v4l2_format *fmt)
313 {
314 	struct zoran *zr = video_drvdata(file);
315 
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;
326 	else
327 		fmt->fmt.pix.field = V4L2_FIELD_TOP;
328 	return 0;
329 }
330 
331 static int zoran_try_fmt_vid_out(struct file *file, void *__fh,
332 				 struct v4l2_format *fmt)
333 {
334 	struct zoran *zr = video_drvdata(file);
335 	struct zoran_jpg_settings settings;
336 	int res = 0;
337 
338 	if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
339 		return -EINVAL;
340 
341 	settings = zr->jpg_settings;
342 
343 	/* we actually need to set 'real' parameters now */
344 	if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT)
345 		settings.tmp_dcm = 1;
346 	else
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;
351 	else
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;
357 	else
358 		settings.hor_dcm = 1;
359 	if (settings.tmp_dcm == 1)
360 		settings.field_per_buff = 2;
361 	else
362 		settings.field_per_buff = 1;
363 
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;
367 	} else {
368 		settings.img_x = 0;
369 		settings.img_width = BUZ_MAX_WIDTH;
370 	}
371 
372 	/* check */
373 	res = zoran_check_jpg_settings(zr, &settings, 1);
374 	if (res)
375 		return res;
376 
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);
384 	else
385 		fmt->fmt.pix.field = (zr->jpg_settings.odd_even ?
386 				V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
387 
388 	fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&settings);
389 	fmt->fmt.pix.bytesperline = 0;
390 	fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
391 	return res;
392 }
393 
394 static int zoran_try_fmt_vid_cap(struct file *file, void *__fh,
395 				 struct v4l2_format *fmt)
396 {
397 	struct zoran *zr = video_drvdata(file);
398 	int bpp;
399 	int i;
400 
401 	if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
402 		return zoran_try_fmt_vid_out(file, __fh, fmt);
403 
404 	for (i = 0; i < NUM_FORMATS; i++)
405 		if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat)
406 			break;
407 
408 	if (i == NUM_FORMATS) {
409 		/* TODO do not return here to fix the TRY_FMT cannot handle an invalid pixelformat*/
410 		return -EINVAL;
411 	}
412 
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;
417 	else
418 		fmt->fmt.pix.field = V4L2_FIELD_TOP;
419 
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,
422 			      bpp == 2 ? 1 : 2,
423 			      &fmt->fmt.pix.height, BUZ_MIN_HEIGHT, BUZ_MAX_HEIGHT,
424 			      0, 0);
425 	fmt->fmt.pix.bytesperline = fmt->fmt.pix.width * bpp;
426 	fmt->fmt.pix.sizeimage = fmt->fmt.pix.bytesperline * fmt->fmt.pix.height;
427 	return 0;
428 }
429 
430 static int zoran_s_fmt_vid_out(struct file *file, void *__fh,
431 			       struct v4l2_format *fmt)
432 {
433 	struct zoran *zr = video_drvdata(file);
434 	__le32 printformat = __cpu_to_le32(fmt->fmt.pix.pixelformat);
435 	struct zoran_jpg_settings settings;
436 	int res = 0;
437 
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)
443 		return -EINVAL;
444 
445 	if (!fmt->fmt.pix.height || !fmt->fmt.pix.width)
446 		return -EINVAL;
447 
448 	settings = zr->jpg_settings;
449 
450 	/* we actually need to set 'real' parameters now */
451 	if (fmt->fmt.pix.height * 2 > BUZ_MAX_HEIGHT)
452 		settings.tmp_dcm = 1;
453 	else
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;
458 	else
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;
464 	else
465 		settings.hor_dcm = 1;
466 	if (settings.tmp_dcm == 1)
467 		settings.field_per_buff = 2;
468 	else
469 		settings.field_per_buff = 1;
470 
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;
474 	} else {
475 		settings.img_x = 0;
476 		settings.img_width = BUZ_MAX_WIDTH;
477 	}
478 
479 	/* check */
480 	res = zoran_check_jpg_settings(zr, &settings, 0);
481 	if (res)
482 		return res;
483 
484 	/* it's ok, so set them */
485 	zr->jpg_settings = settings;
486 
487 	if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
488 		zr->map_mode = ZORAN_MAP_MODE_JPG_REC;
489 	else
490 		zr->map_mode = ZORAN_MAP_MODE_JPG_PLAY;
491 
492 	zr->buffer_size = zoran_v4l2_calc_bufsize(&zr->jpg_settings);
493 
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);
501 	else
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;
507 	return res;
508 }
509 
510 static int zoran_s_fmt_vid_cap(struct file *file, void *__fh,
511 			       struct v4l2_format *fmt)
512 {
513 	struct zoran *zr = video_drvdata(file);
514 	struct zoran_fh *fh = __fh;
515 	int i;
516 	int res = 0;
517 
518 	if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
519 		return zoran_s_fmt_vid_out(file, fh, fmt);
520 
521 	for (i = 0; i < NUM_FORMATS; i++)
522 		if (fmt->fmt.pix.pixelformat == zoran_formats[i].fourcc)
523 			break;
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*/
528 		return -EINVAL;
529 	}
530 
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;
540 
541 	zr->map_mode = ZORAN_MAP_MODE_RAW;
542 
543 	res = zoran_v4l_set_format(zr, fmt->fmt.pix.width, fmt->fmt.pix.height,
544 				   &zoran_formats[i]);
545 	if (res)
546 		return res;
547 
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;
554 	else
555 		fmt->fmt.pix.field = V4L2_FIELD_TOP;
556 	return res;
557 }
558 
559 static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std)
560 {
561 	struct zoran *zr = video_drvdata(file);
562 
563 	*std = zr->norm;
564 	return 0;
565 }
566 
567 static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id std)
568 {
569 	struct zoran *zr = video_drvdata(file);
570 	int res = 0;
571 
572 	if (zr->norm == std)
573 		return 0;
574 
575 	if (zr->running != ZORAN_MAP_MODE_NONE)
576 		return -EBUSY;
577 
578 	res = zoran_set_norm(zr, std);
579 	return res;
580 }
581 
582 static int zoran_enum_input(struct file *file, void *__fh,
583 			    struct v4l2_input *inp)
584 {
585 	struct zoran *zr = video_drvdata(file);
586 
587 	if (inp->index >= zr->card.inputs)
588 		return -EINVAL;
589 
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;
593 
594 	/* Get status of video decoder */
595 	decoder_call(zr, video, g_input_status, &inp->status);
596 	return 0;
597 }
598 
599 static int zoran_g_input(struct file *file, void *__fh, unsigned int *input)
600 {
601 	struct zoran *zr = video_drvdata(file);
602 
603 	*input = zr->input;
604 
605 	return 0;
606 }
607 
608 static int zoran_s_input(struct file *file, void *__fh, unsigned int input)
609 {
610 	struct zoran *zr = video_drvdata(file);
611 	int res;
612 
613 	if (zr->running != ZORAN_MAP_MODE_NONE)
614 		return -EBUSY;
615 
616 	res = zoran_set_input(zr, input);
617 	return res;
618 }
619 
620 /* cropping (sub-frame capture) */
621 static int zoran_g_selection(struct file *file, void *__fh, struct v4l2_selection *sel)
622 {
623 	struct zoran *zr = video_drvdata(file);
624 
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__);
628 		return -EINVAL;
629 	}
630 
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;
637 		break;
638 	case V4L2_SEL_TGT_CROP_DEFAULT:
639 		sel->r.top = 0;
640 		sel->r.left = 0;
641 		sel->r.width = BUZ_MIN_WIDTH;
642 		sel->r.height = BUZ_MIN_HEIGHT;
643 		break;
644 	case V4L2_SEL_TGT_CROP_BOUNDS:
645 		sel->r.top = 0;
646 		sel->r.left = 0;
647 		sel->r.width = BUZ_MAX_WIDTH;
648 		sel->r.height = BUZ_MAX_HEIGHT;
649 		break;
650 	default:
651 		return -EINVAL;
652 	}
653 	return 0;
654 }
655 
656 static int zoran_s_selection(struct file *file, void *__fh, struct v4l2_selection *sel)
657 {
658 	struct zoran *zr = video_drvdata(file);
659 	struct zoran_jpg_settings settings;
660 	int res;
661 
662 	if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
663 	    sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
664 		return -EINVAL;
665 
666 	if (!sel->r.width || !sel->r.height)
667 		return -EINVAL;
668 
669 	if (sel->target != V4L2_SEL_TGT_CROP)
670 		return -EINVAL;
671 
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");
674 		return -EINVAL;
675 	}
676 
677 	settings = zr->jpg_settings;
678 
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;
684 
685 	/* check validity */
686 	res = zoran_check_jpg_settings(zr, &settings, 0);
687 	if (res)
688 		return res;
689 
690 	/* accept */
691 	zr->jpg_settings = settings;
692 	return res;
693 }
694 
695 /*
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.
699  */
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,
723 };
724 
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,
732 };
733 
734 const struct video_device zoran_template = {
735 	.name = ZORAN_NAME,
736 	.fops = &zoran_fops,
737 	.ioctl_ops = &zoran_ioctl_ops,
738 	.release = &zoran_vdev_release,
739 	.tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
740 };
741 
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[])
744 {
745 	struct zoran *zr = vb2_get_drv_priv(vq);
746 	unsigned int size = zr->buffer_size;
747 
748 	pci_dbg(zr->pci_dev, "%s nbuf=%u nplanes=%u", __func__, *nbuffers, *nplanes);
749 
750 	zr->buf_in_reserve = 0;
751 
752 	if (*nbuffers < vq->min_buffers_needed)
753 		*nbuffers = vq->min_buffers_needed;
754 
755 	if (*nplanes) {
756 		if (sizes[0] < size)
757 			return -EINVAL;
758 		else
759 			return 0;
760 	}
761 
762 	*nplanes = 1;
763 	sizes[0] = size;
764 
765 	return 0;
766 }
767 
768 static void zr_vb2_queue(struct vb2_buffer *vb)
769 {
770 	struct zoran *zr = vb2_get_drv_priv(vb->vb2_queue);
771 	struct zr_buffer *buf = vb2_to_zr_buffer(vb);
772 	unsigned long flags;
773 
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);
780 	zr->queued++;
781 }
782 
783 static int zr_vb2_prepare(struct vb2_buffer *vb)
784 {
785 	struct zoran *zr = vb2_get_drv_priv(vb->vb2_queue);
786 
787 	if (vb2_plane_size(vb, 0) < zr->buffer_size)
788 		return -EINVAL;
789 	zr->prepared++;
790 
791 	return 0;
792 }
793 
794 int zr_set_buf(struct zoran *zr)
795 {
796 	struct zr_buffer *buf;
797 	struct vb2_v4l2_buffer *vbuf;
798 	dma_addr_t phys_addr;
799 	unsigned long flags;
800 	u32 reg;
801 
802 	if (zr->running == ZORAN_MAP_MODE_NONE)
803 		return 0;
804 
805 	if (zr->inuse[0]) {
806 		buf = zr->inuse[0];
807 		buf->vbuf.vb2_buf.timestamp = ktime_get_ns();
808 		buf->vbuf.sequence = zr->vbseq++;
809 		vbuf = &buf->vbuf;
810 
811 		buf->vbuf.field = V4L2_FIELD_INTERLACED;
812 		if (BUZ_MAX_HEIGHT < (zr->v4l_settings.height * 2))
813 			buf->vbuf.field = V4L2_FIELD_INTERLACED;
814 		else
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);
818 		zr->inuse[0] = NULL;
819 	}
820 
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);
826 		return -EINVAL;
827 	}
828 	buf = list_first_entry_or_null(&zr->queued_bufs, struct zr_buffer, queue);
829 	if (!buf) {
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);
833 		return -EINVAL;
834 	}
835 	list_del(&buf->queue);
836 	zr->buf_in_reserve--;
837 	spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
838 
839 	vbuf = &buf->vbuf;
840 	vbuf->vb2_buf.state = VB2_BUF_STATE_ACTIVE;
841 	phys_addr = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);
842 
843 	if (!phys_addr)
844 		return -EINVAL;
845 
846 	zr->inuse[0] = buf;
847 
848 	reg = phys_addr;
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);
853 
854 	reg = 0;
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);
862 
863 	btor(ZR36057_VDCR_VID_EN, ZR36057_VDCR);
864 	return 0;
865 }
866 
867 static int zr_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
868 {
869 	struct zoran *zr = vq->drv_priv;
870 	int j;
871 
872 	for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
873 		zr->stat_com[j] = cpu_to_le32(1);
874 		zr->inuse[j] = NULL;
875 	}
876 	zr->vbseq = 0;
877 
878 	if (zr->map_mode != ZORAN_MAP_MODE_RAW) {
879 		pci_dbg(zr->pci_dev, "START JPG\n");
880 		zr36057_restart(zr);
881 		zoran_init_hardware(zr);
882 		if (zr->map_mode == ZORAN_MAP_MODE_JPG_REC)
883 			zr36057_enable_jpg(zr, BUZ_MODE_MOTION_DECOMPRESS);
884 		else
885 			zr36057_enable_jpg(zr, BUZ_MODE_MOTION_COMPRESS);
886 		zoran_feed_stat_com(zr);
887 		jpeg_start(zr);
888 		zr->running = zr->map_mode;
889 		btor(ZR36057_ICR_INT_PIN_EN, ZR36057_ICR);
890 		return 0;
891 	}
892 
893 	pci_dbg(zr->pci_dev, "START RAW\n");
894 	zr36057_restart(zr);
895 	zoran_init_hardware(zr);
896 
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);
901 	return 0;
902 }
903 
904 static void zr_vb2_stop_streaming(struct vb2_queue *vq)
905 {
906 	struct zoran *zr = vq->drv_priv;
907 	struct zr_buffer *buf;
908 	unsigned long flags;
909 	int j;
910 
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;
916 
917 	zoran_set_pci_master(zr, 0);
918 
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);
922 	}
923 
924 	for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
925 		zr->stat_com[j] = cpu_to_le32(1);
926 		if (!zr->inuse[j])
927 			continue;
928 		buf = zr->inuse[j];
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);
931 		zr->inuse[j] = NULL;
932 	}
933 
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--;
940 	}
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;
945 }
946 
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,
955 };
956 
957 int zoran_queue_init(struct zoran *zr, struct vb2_queue *vq, int dir)
958 {
959 	int err;
960 
961 	spin_lock_init(&zr->queued_bufs_lock);
962 	INIT_LIST_HEAD(&zr->queued_bufs);
963 
964 	vq->dev = &zr->pci_dev->dev;
965 	vq->type = dir;
966 
967 	vq->io_modes = VB2_DMABUF | VB2_MMAP;
968 	vq->drv_priv = zr;
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_buffers_needed = 9;
975 	vq->lock = &zr->lock;
976 	err = vb2_queue_init(vq);
977 	if (err)
978 		return err;
979 	zr->video_dev->queue = vq;
980 	return 0;
981 }
982 
983 void zoran_queue_exit(struct zoran *zr)
984 {
985 	vb2_queue_release(zr->video_dev->queue);
986 }
987