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 	 */
zoran_v4l2_calc_bufsize(struct zoran_jpg_settings * settings)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 > jpg_bufsize)
157 		return jpg_bufsize;
158 	if (result < 8192)
159 		return 8192;
160 
161 	return result;
162 }
163 
164 /*
165  *   V4L Buffer grabbing
166  */
zoran_v4l_set_format(struct zoran * zr,int width,int height,const struct zoran_format * format)167 static int zoran_v4l_set_format(struct zoran *zr, int width, int height,
168 				const struct zoran_format *format)
169 {
170 	int bpp;
171 
172 	/* Check size and format of the grab wanted */
173 
174 	if (height < BUZ_MIN_HEIGHT || width < BUZ_MIN_WIDTH ||
175 	    height > BUZ_MAX_HEIGHT || width > BUZ_MAX_WIDTH) {
176 		pci_err(zr->pci_dev, "%s - wrong frame size (%dx%d)\n", __func__, width, height);
177 		return -EINVAL;
178 	}
179 
180 	bpp = (format->depth + 7) / 8;
181 
182 	zr->buffer_size = height * width * bpp;
183 
184 	/* Check against available buffer size */
185 	if (height * width * bpp > zr->buffer_size) {
186 		pci_err(zr->pci_dev, "%s - video buffer size (%d kB) is too small\n",
187 			__func__, zr->buffer_size >> 10);
188 		return -EINVAL;
189 	}
190 
191 	/* The video front end needs 4-byte alinged line sizes */
192 
193 	if ((bpp == 2 && (width & 1)) || (bpp == 3 && (width & 3))) {
194 		pci_err(zr->pci_dev, "%s - wrong frame alignment\n", __func__);
195 		return -EINVAL;
196 	}
197 
198 	zr->v4l_settings.width = width;
199 	zr->v4l_settings.height = height;
200 	zr->v4l_settings.format = format;
201 	zr->v4l_settings.bytesperline = bpp * zr->v4l_settings.width;
202 
203 	return 0;
204 }
205 
zoran_set_norm(struct zoran * zr,v4l2_std_id norm)206 static int zoran_set_norm(struct zoran *zr, v4l2_std_id norm)
207 {
208 
209 	if (!(norm & zr->card.norms)) {
210 		pci_err(zr->pci_dev, "%s - unsupported norm %llx\n", __func__, norm);
211 		return -EINVAL;
212 	}
213 
214 	if (norm & V4L2_STD_SECAM)
215 		zr->timing = zr->card.tvn[ZR_NORM_SECAM];
216 	else if (norm & V4L2_STD_NTSC)
217 		zr->timing = zr->card.tvn[ZR_NORM_NTSC];
218 	else
219 		zr->timing = zr->card.tvn[ZR_NORM_PAL];
220 
221 	decoder_call(zr, video, s_std, norm);
222 	encoder_call(zr, video, s_std_output, norm);
223 
224 	/* Make sure the changes come into effect */
225 	zr->norm = norm;
226 
227 	return 0;
228 }
229 
zoran_set_input(struct zoran * zr,int input)230 static int zoran_set_input(struct zoran *zr, int input)
231 {
232 	if (input == zr->input)
233 		return 0;
234 
235 	if (input < 0 || input >= zr->card.inputs) {
236 		pci_err(zr->pci_dev, "%s - unsupported input %d\n", __func__, input);
237 		return -EINVAL;
238 	}
239 
240 	zr->input = input;
241 
242 	decoder_call(zr, video, s_routing, zr->card.input[input].muxsel, 0, 0);
243 
244 	return 0;
245 }
246 
247 /*
248  *   ioctl routine
249  */
250 
zoran_querycap(struct file * file,void * __fh,struct v4l2_capability * cap)251 static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap)
252 {
253 	struct zoran *zr = video_drvdata(file);
254 
255 	strscpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card));
256 	strscpy(cap->driver, "zoran", sizeof(cap->driver));
257 	snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", pci_name(zr->pci_dev));
258 	cap->device_caps = zr->video_dev->device_caps;
259 	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
260 	return 0;
261 }
262 
zoran_enum_fmt(struct zoran * zr,struct v4l2_fmtdesc * fmt,int flag)263 static int zoran_enum_fmt(struct zoran *zr, struct v4l2_fmtdesc *fmt, int flag)
264 {
265 	unsigned int num, i;
266 
267 	if (fmt->index >= ARRAY_SIZE(zoran_formats))
268 		return -EINVAL;
269 	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
270 		return -EINVAL;
271 
272 	for (num = i = 0; i < NUM_FORMATS; i++) {
273 		if (zoran_formats[i].flags & flag && num++ == fmt->index) {
274 			strscpy(fmt->description, zoran_formats[i].name,
275 				sizeof(fmt->description));
276 			/* fmt struct pre-zeroed, so adding '\0' not needed */
277 			fmt->pixelformat = zoran_formats[i].fourcc;
278 			if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)
279 				fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
280 			return 0;
281 		}
282 	}
283 	return -EINVAL;
284 }
285 
zoran_enum_fmt_vid_cap(struct file * file,void * __fh,struct v4l2_fmtdesc * f)286 static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh,
287 				  struct v4l2_fmtdesc *f)
288 {
289 	struct zoran *zr = video_drvdata(file);
290 
291 	return zoran_enum_fmt(zr, f, ZORAN_FORMAT_CAPTURE);
292 }
293 
294 #if 0
295 /* TODO: output does not work yet */
296 static int zoran_enum_fmt_vid_out(struct file *file, void *__fh,
297 				  struct v4l2_fmtdesc *f)
298 {
299 	struct zoran *zr = video_drvdata(file);
300 
301 	return zoran_enum_fmt(zr, f, ZORAN_FORMAT_PLAYBACK);
302 }
303 #endif
304 
zoran_g_fmt_vid_out(struct file * file,void * __fh,struct v4l2_format * fmt)305 static int zoran_g_fmt_vid_out(struct file *file, void *__fh,
306 			       struct v4l2_format *fmt)
307 {
308 	struct zoran *zr = video_drvdata(file);
309 
310 	fmt->fmt.pix.width = zr->jpg_settings.img_width / zr->jpg_settings.hor_dcm;
311 	fmt->fmt.pix.height = zr->jpg_settings.img_height * 2 /
312 		(zr->jpg_settings.ver_dcm * zr->jpg_settings.tmp_dcm);
313 	fmt->fmt.pix.sizeimage = zr->buffer_size;
314 	fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
315 	if (zr->jpg_settings.tmp_dcm == 1)
316 		fmt->fmt.pix.field = (zr->jpg_settings.odd_even ?
317 				V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
318 	else
319 		fmt->fmt.pix.field = (zr->jpg_settings.odd_even ?
320 				V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
321 	fmt->fmt.pix.bytesperline = 0;
322 	fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
323 
324 	return 0;
325 }
326 
zoran_g_fmt_vid_cap(struct file * file,void * __fh,struct v4l2_format * fmt)327 static int zoran_g_fmt_vid_cap(struct file *file, void *__fh,
328 			       struct v4l2_format *fmt)
329 {
330 	struct zoran *zr = video_drvdata(file);
331 
332 	if (zr->map_mode != ZORAN_MAP_MODE_RAW)
333 		return zoran_g_fmt_vid_out(file, __fh, fmt);
334 	fmt->fmt.pix.width = zr->v4l_settings.width;
335 	fmt->fmt.pix.height = zr->v4l_settings.height;
336 	fmt->fmt.pix.sizeimage = zr->buffer_size;
337 	fmt->fmt.pix.pixelformat = zr->v4l_settings.format->fourcc;
338 	fmt->fmt.pix.colorspace = zr->v4l_settings.format->colorspace;
339 	fmt->fmt.pix.bytesperline = zr->v4l_settings.bytesperline;
340 	if (BUZ_MAX_HEIGHT < (zr->v4l_settings.height * 2))
341 		fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
342 	else
343 		fmt->fmt.pix.field = V4L2_FIELD_TOP;
344 	return 0;
345 }
346 
zoran_try_fmt_vid_out(struct file * file,void * __fh,struct v4l2_format * fmt)347 static int zoran_try_fmt_vid_out(struct file *file, void *__fh,
348 				 struct v4l2_format *fmt)
349 {
350 	struct zoran *zr = video_drvdata(file);
351 	struct zoran_jpg_settings settings;
352 	int res = 0;
353 
354 	if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
355 		return -EINVAL;
356 
357 	settings = zr->jpg_settings;
358 
359 	/* we actually need to set 'real' parameters now */
360 	if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT)
361 		settings.tmp_dcm = 1;
362 	else
363 		settings.tmp_dcm = 2;
364 	settings.decimation = 0;
365 	if (fmt->fmt.pix.height <= zr->jpg_settings.img_height / 2)
366 		settings.ver_dcm = 2;
367 	else
368 		settings.ver_dcm = 1;
369 	if (fmt->fmt.pix.width <= zr->jpg_settings.img_width / 4)
370 		settings.hor_dcm = 4;
371 	else if (fmt->fmt.pix.width <= zr->jpg_settings.img_width / 2)
372 		settings.hor_dcm = 2;
373 	else
374 		settings.hor_dcm = 1;
375 	if (settings.tmp_dcm == 1)
376 		settings.field_per_buff = 2;
377 	else
378 		settings.field_per_buff = 1;
379 
380 	if (settings.hor_dcm > 1) {
381 		settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
382 		settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
383 	} else {
384 		settings.img_x = 0;
385 		settings.img_width = BUZ_MAX_WIDTH;
386 	}
387 
388 	/* check */
389 	res = zoran_check_jpg_settings(zr, &settings, 1);
390 	if (res)
391 		return res;
392 
393 	/* tell the user what we actually did */
394 	fmt->fmt.pix.width = settings.img_width / settings.hor_dcm;
395 	fmt->fmt.pix.height = settings.img_height * 2 /
396 		(settings.tmp_dcm * settings.ver_dcm);
397 	if (settings.tmp_dcm == 1)
398 		fmt->fmt.pix.field = (zr->jpg_settings.odd_even ?
399 				V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
400 	else
401 		fmt->fmt.pix.field = (zr->jpg_settings.odd_even ?
402 				V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
403 
404 	fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&settings);
405 	zr->buffer_size = fmt->fmt.pix.sizeimage;
406 	fmt->fmt.pix.bytesperline = 0;
407 	fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
408 	return res;
409 }
410 
zoran_try_fmt_vid_cap(struct file * file,void * __fh,struct v4l2_format * fmt)411 static int zoran_try_fmt_vid_cap(struct file *file, void *__fh,
412 				 struct v4l2_format *fmt)
413 {
414 	struct zoran *zr = video_drvdata(file);
415 	int bpp;
416 	int i;
417 
418 	if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
419 		return zoran_try_fmt_vid_out(file, __fh, fmt);
420 
421 	for (i = 0; i < NUM_FORMATS; i++)
422 		if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat)
423 			break;
424 
425 	if (i == NUM_FORMATS) {
426 		/* TODO do not return here to fix the TRY_FMT cannot handle an invalid pixelformat*/
427 		return -EINVAL;
428 	}
429 
430 	fmt->fmt.pix.pixelformat = zoran_formats[i].fourcc;
431 	fmt->fmt.pix.colorspace = zoran_formats[i].colorspace;
432 	if (BUZ_MAX_HEIGHT < (fmt->fmt.pix.height * 2))
433 		fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
434 	else
435 		fmt->fmt.pix.field = V4L2_FIELD_TOP;
436 
437 	bpp = DIV_ROUND_UP(zoran_formats[i].depth, 8);
438 	v4l_bound_align_image(&fmt->fmt.pix.width, BUZ_MIN_WIDTH, BUZ_MAX_WIDTH, bpp == 2 ? 1 : 2,
439 		&fmt->fmt.pix.height, BUZ_MIN_HEIGHT, BUZ_MAX_HEIGHT, 0, 0);
440 	return 0;
441 }
442 
zoran_s_fmt_vid_out(struct file * file,void * __fh,struct v4l2_format * fmt)443 static int zoran_s_fmt_vid_out(struct file *file, void *__fh,
444 			       struct v4l2_format *fmt)
445 {
446 	struct zoran *zr = video_drvdata(file);
447 	__le32 printformat = __cpu_to_le32(fmt->fmt.pix.pixelformat);
448 	struct zoran_jpg_settings settings;
449 	int res = 0;
450 
451 	pci_dbg(zr->pci_dev, "size=%dx%d, fmt=0x%x (%4.4s)\n",
452 		fmt->fmt.pix.width, fmt->fmt.pix.height,
453 			fmt->fmt.pix.pixelformat,
454 			(char *)&printformat);
455 	if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
456 		return -EINVAL;
457 
458 	if (!fmt->fmt.pix.height || !fmt->fmt.pix.width)
459 		return -EINVAL;
460 
461 	settings = zr->jpg_settings;
462 
463 	/* we actually need to set 'real' parameters now */
464 	if (fmt->fmt.pix.height * 2 > BUZ_MAX_HEIGHT)
465 		settings.tmp_dcm = 1;
466 	else
467 		settings.tmp_dcm = 2;
468 	settings.decimation = 0;
469 	if (fmt->fmt.pix.height <= zr->jpg_settings.img_height / 2)
470 		settings.ver_dcm = 2;
471 	else
472 		settings.ver_dcm = 1;
473 	if (fmt->fmt.pix.width <= zr->jpg_settings.img_width / 4)
474 		settings.hor_dcm = 4;
475 	else if (fmt->fmt.pix.width <= zr->jpg_settings.img_width / 2)
476 		settings.hor_dcm = 2;
477 	else
478 		settings.hor_dcm = 1;
479 	if (settings.tmp_dcm == 1)
480 		settings.field_per_buff = 2;
481 	else
482 		settings.field_per_buff = 1;
483 
484 	if (settings.hor_dcm > 1) {
485 		settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
486 		settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
487 	} else {
488 		settings.img_x = 0;
489 		settings.img_width = BUZ_MAX_WIDTH;
490 	}
491 
492 	/* check */
493 	res = zoran_check_jpg_settings(zr, &settings, 0);
494 	if (res)
495 		return res;
496 
497 	/* it's ok, so set them */
498 	zr->jpg_settings = settings;
499 
500 	if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
501 		zr->map_mode = ZORAN_MAP_MODE_JPG_REC;
502 	else
503 		zr->map_mode = ZORAN_MAP_MODE_JPG_PLAY;
504 
505 	zr->buffer_size = zoran_v4l2_calc_bufsize(&zr->jpg_settings);
506 
507 	/* tell the user what we actually did */
508 	fmt->fmt.pix.width = settings.img_width / settings.hor_dcm;
509 	fmt->fmt.pix.height = settings.img_height * 2 /
510 		(settings.tmp_dcm * settings.ver_dcm);
511 	if (settings.tmp_dcm == 1)
512 		fmt->fmt.pix.field = (zr->jpg_settings.odd_even ?
513 				V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
514 	else
515 		fmt->fmt.pix.field = (zr->jpg_settings.odd_even ?
516 				V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
517 	fmt->fmt.pix.bytesperline = 0;
518 	fmt->fmt.pix.sizeimage = zr->buffer_size;
519 	fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
520 	return res;
521 }
522 
zoran_s_fmt_vid_cap(struct file * file,void * __fh,struct v4l2_format * fmt)523 static int zoran_s_fmt_vid_cap(struct file *file, void *__fh,
524 			       struct v4l2_format *fmt)
525 {
526 	struct zoran *zr = video_drvdata(file);
527 	struct zoran_fh *fh = __fh;
528 	int i;
529 	int res = 0;
530 
531 	if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
532 		return zoran_s_fmt_vid_out(file, fh, fmt);
533 
534 	for (i = 0; i < NUM_FORMATS; i++)
535 		if (fmt->fmt.pix.pixelformat == zoran_formats[i].fourcc)
536 			break;
537 	if (i == NUM_FORMATS) {
538 		pci_err(zr->pci_dev, "VIDIOC_S_FMT - unknown/unsupported format 0x%x\n",
539 			fmt->fmt.pix.pixelformat);
540 		/* TODO do not return here to fix the TRY_FMT cannot handle an invalid pixelformat*/
541 		return -EINVAL;
542 	}
543 
544 	fmt->fmt.pix.pixelformat = zoran_formats[i].fourcc;
545 	if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
546 		fmt->fmt.pix.height = BUZ_MAX_HEIGHT;
547 	if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
548 		fmt->fmt.pix.width = BUZ_MAX_WIDTH;
549 	if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT)
550 		fmt->fmt.pix.height = BUZ_MIN_HEIGHT;
551 	if (fmt->fmt.pix.width < BUZ_MIN_WIDTH)
552 		fmt->fmt.pix.width = BUZ_MIN_WIDTH;
553 
554 	zr->map_mode = ZORAN_MAP_MODE_RAW;
555 
556 	res = zoran_v4l_set_format(zr, fmt->fmt.pix.width, fmt->fmt.pix.height,
557 				   &zoran_formats[i]);
558 	if (res)
559 		return res;
560 
561 	/* tell the user the results/missing stuff */
562 	fmt->fmt.pix.bytesperline = zr->v4l_settings.bytesperline;
563 	fmt->fmt.pix.sizeimage = zr->buffer_size;
564 	fmt->fmt.pix.colorspace = zr->v4l_settings.format->colorspace;
565 	if (BUZ_MAX_HEIGHT < (zr->v4l_settings.height * 2))
566 		fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
567 	else
568 		fmt->fmt.pix.field = V4L2_FIELD_TOP;
569 	return res;
570 }
571 
zoran_g_std(struct file * file,void * __fh,v4l2_std_id * std)572 static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std)
573 {
574 	struct zoran *zr = video_drvdata(file);
575 
576 	*std = zr->norm;
577 	return 0;
578 }
579 
zoran_s_std(struct file * file,void * __fh,v4l2_std_id std)580 static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id std)
581 {
582 	struct zoran *zr = video_drvdata(file);
583 	int res = 0;
584 
585 	if (zr->running != ZORAN_MAP_MODE_NONE)
586 		return -EBUSY;
587 
588 	res = zoran_set_norm(zr, std);
589 	return res;
590 }
591 
zoran_enum_input(struct file * file,void * __fh,struct v4l2_input * inp)592 static int zoran_enum_input(struct file *file, void *__fh,
593 			    struct v4l2_input *inp)
594 {
595 	struct zoran *zr = video_drvdata(file);
596 
597 	if (inp->index >= zr->card.inputs)
598 		return -EINVAL;
599 
600 	strscpy(inp->name, zr->card.input[inp->index].name, sizeof(inp->name));
601 	inp->type = V4L2_INPUT_TYPE_CAMERA;
602 	inp->std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
603 
604 	/* Get status of video decoder */
605 	decoder_call(zr, video, g_input_status, &inp->status);
606 	return 0;
607 }
608 
zoran_g_input(struct file * file,void * __fh,unsigned int * input)609 static int zoran_g_input(struct file *file, void *__fh, unsigned int *input)
610 {
611 	struct zoran *zr = video_drvdata(file);
612 
613 	*input = zr->input;
614 
615 	return 0;
616 }
617 
zoran_s_input(struct file * file,void * __fh,unsigned int input)618 static int zoran_s_input(struct file *file, void *__fh, unsigned int input)
619 {
620 	struct zoran *zr = video_drvdata(file);
621 	int res;
622 
623 	if (zr->running != ZORAN_MAP_MODE_NONE)
624 		return -EBUSY;
625 
626 	res = zoran_set_input(zr, input);
627 	return res;
628 }
629 
630 #if 0
631 /* TODO: output does not work yet */
632 static int zoran_enum_output(struct file *file, void *__fh,
633 			     struct v4l2_output *outp)
634 {
635 	if (outp->index != 0)
636 		return -EINVAL;
637 
638 	outp->index = 0;
639 	outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY;
640 	outp->std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
641 	outp->capabilities = V4L2_OUT_CAP_STD;
642 	strscpy(outp->name, "Autodetect", sizeof(outp->name));
643 
644 	return 0;
645 }
646 static int zoran_g_output(struct file *file, void *__fh, unsigned int *output)
647 {
648 	*output = 0;
649 
650 	return 0;
651 }
652 
653 static int zoran_s_output(struct file *file, void *__fh, unsigned int output)
654 {
655 	if (output != 0)
656 		return -EINVAL;
657 
658 	return 0;
659 }
660 #endif
661 
662 /* cropping (sub-frame capture) */
zoran_g_selection(struct file * file,void * __fh,struct v4l2_selection * sel)663 static int zoran_g_selection(struct file *file, void *__fh, struct v4l2_selection *sel)
664 {
665 	struct zoran *zr = video_drvdata(file);
666 
667 	if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
668 	    sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
669 		pci_err(zr->pci_dev, "%s invalid selection type combination\n", __func__);
670 		return -EINVAL;
671 	}
672 
673 	switch (sel->target) {
674 	case V4L2_SEL_TGT_CROP:
675 		sel->r.top = zr->jpg_settings.img_y;
676 		sel->r.left = zr->jpg_settings.img_x;
677 		sel->r.width = zr->jpg_settings.img_width;
678 		sel->r.height = zr->jpg_settings.img_height;
679 		break;
680 	case V4L2_SEL_TGT_CROP_DEFAULT:
681 		sel->r.top = 0;
682 		sel->r.left = 0;
683 		sel->r.width = BUZ_MIN_WIDTH;
684 		sel->r.height = BUZ_MIN_HEIGHT;
685 		break;
686 	case V4L2_SEL_TGT_CROP_BOUNDS:
687 		sel->r.top = 0;
688 		sel->r.left = 0;
689 		sel->r.width = BUZ_MAX_WIDTH;
690 		sel->r.height = BUZ_MAX_HEIGHT;
691 		break;
692 	default:
693 		return -EINVAL;
694 	}
695 	return 0;
696 }
697 
zoran_s_selection(struct file * file,void * __fh,struct v4l2_selection * sel)698 static int zoran_s_selection(struct file *file, void *__fh, struct v4l2_selection *sel)
699 {
700 	struct zoran *zr = video_drvdata(file);
701 	struct zoran_jpg_settings settings;
702 	int res;
703 
704 	if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
705 	    sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
706 		return -EINVAL;
707 
708 	if (!sel->r.width || !sel->r.height)
709 		return -EINVAL;
710 
711 	if (sel->target != V4L2_SEL_TGT_CROP)
712 		return -EINVAL;
713 
714 	if (zr->map_mode == ZORAN_MAP_MODE_RAW) {
715 		pci_err(zr->pci_dev, "VIDIOC_S_SELECTION - subcapture only supported for compressed capture\n");
716 		return -EINVAL;
717 	}
718 
719 	settings = zr->jpg_settings;
720 
721 	/* move into a form that we understand */
722 	settings.img_x = sel->r.left;
723 	settings.img_y = sel->r.top;
724 	settings.img_width = sel->r.width;
725 	settings.img_height = sel->r.height;
726 
727 	/* check validity */
728 	res = zoran_check_jpg_settings(zr, &settings, 0);
729 	if (res)
730 		return res;
731 
732 	/* accept */
733 	zr->jpg_settings = settings;
734 	return res;
735 }
736 
zoran_g_parm(struct file * file,void * priv,struct v4l2_streamparm * parm)737 static int zoran_g_parm(struct file *file, void *priv, struct v4l2_streamparm *parm)
738 {
739 	if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
740 		return -EINVAL;
741 
742 	return 0;
743 }
744 
745 /*
746  * Output is disabled temporarily
747  * Zoran is picky about jpeg data it accepts. At least it seems to unsupport COM and APPn.
748  * So until a way to filter data will be done, disable output.
749  */
750 static const struct v4l2_ioctl_ops zoran_ioctl_ops = {
751 	.vidioc_querycap		    = zoran_querycap,
752 	.vidioc_g_parm			    = zoran_g_parm,
753 	.vidioc_s_selection		    = zoran_s_selection,
754 	.vidioc_g_selection		    = zoran_g_selection,
755 	.vidioc_enum_input		    = zoran_enum_input,
756 	.vidioc_g_input			    = zoran_g_input,
757 	.vidioc_s_input			    = zoran_s_input,
758 /*	.vidioc_enum_output		    = zoran_enum_output,
759 	.vidioc_g_output		    = zoran_g_output,
760 	.vidioc_s_output		    = zoran_s_output,*/
761 	.vidioc_g_std			    = zoran_g_std,
762 	.vidioc_s_std			    = zoran_s_std,
763 	.vidioc_create_bufs		    = vb2_ioctl_create_bufs,
764 	.vidioc_reqbufs			    = vb2_ioctl_reqbufs,
765 	.vidioc_querybuf		    = vb2_ioctl_querybuf,
766 	.vidioc_qbuf			    = vb2_ioctl_qbuf,
767 	.vidioc_dqbuf			    = vb2_ioctl_dqbuf,
768 	.vidioc_expbuf                      = vb2_ioctl_expbuf,
769 	.vidioc_streamon		    = vb2_ioctl_streamon,
770 	.vidioc_streamoff		    = vb2_ioctl_streamoff,
771 	.vidioc_enum_fmt_vid_cap	    = zoran_enum_fmt_vid_cap,
772 /*	.vidioc_enum_fmt_vid_out	    = zoran_enum_fmt_vid_out,*/
773 	.vidioc_g_fmt_vid_cap		    = zoran_g_fmt_vid_cap,
774 /*	.vidioc_g_fmt_vid_out               = zoran_g_fmt_vid_out,*/
775 	.vidioc_s_fmt_vid_cap		    = zoran_s_fmt_vid_cap,
776 /*	.vidioc_s_fmt_vid_out               = zoran_s_fmt_vid_out,*/
777 	.vidioc_try_fmt_vid_cap		    = zoran_try_fmt_vid_cap,
778 /*	.vidioc_try_fmt_vid_out		    = zoran_try_fmt_vid_out,*/
779 	.vidioc_subscribe_event             = v4l2_ctrl_subscribe_event,
780 	.vidioc_unsubscribe_event           = v4l2_event_unsubscribe,
781 };
782 
783 static const struct v4l2_file_operations zoran_fops = {
784 	.owner = THIS_MODULE,
785 	.unlocked_ioctl = video_ioctl2,
786 	.open		= v4l2_fh_open,
787 	.release	= vb2_fop_release,
788 	.read		= vb2_fop_read,
789 	.write		= vb2_fop_write,
790 	.mmap		= vb2_fop_mmap,
791 	.poll		= vb2_fop_poll,
792 };
793 
794 const struct video_device zoran_template = {
795 	.name = ZORAN_NAME,
796 	.fops = &zoran_fops,
797 	.ioctl_ops = &zoran_ioctl_ops,
798 	.release = &zoran_vdev_release,
799 	.tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
800 };
801 
zr_vb2_queue_setup(struct vb2_queue * vq,unsigned int * nbuffers,unsigned int * nplanes,unsigned int sizes[],struct device * alloc_devs[])802 static int zr_vb2_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, unsigned int *nplanes,
803 			      unsigned int sizes[], struct device *alloc_devs[])
804 {
805 	struct zoran *zr = vb2_get_drv_priv(vq);
806 	unsigned int size = zr->buffer_size;
807 
808 	pci_dbg(zr->pci_dev, "%s nbuf=%u nplanes=%u", __func__, *nbuffers, *nplanes);
809 
810 	zr->buf_in_reserve = 0;
811 
812 	if (*nbuffers < vq->min_buffers_needed)
813 		*nbuffers = vq->min_buffers_needed;
814 
815 	if (*nplanes) {
816 		if (sizes[0] < size)
817 			return -EINVAL;
818 		else
819 			return 0;
820 	}
821 
822 	*nplanes = 1;
823 	sizes[0] = size;
824 
825 	return 0;
826 }
827 
zr_vb2_queue(struct vb2_buffer * vb)828 static void zr_vb2_queue(struct vb2_buffer *vb)
829 {
830 	struct zoran *zr = vb2_get_drv_priv(vb->vb2_queue);
831 	struct zr_buffer *buf = vb2_to_zr_buffer(vb);
832 	unsigned long flags;
833 
834 	spin_lock_irqsave(&zr->queued_bufs_lock, flags);
835 	list_add_tail(&buf->queue, &zr->queued_bufs);
836 	zr->buf_in_reserve++;
837 	spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
838 	if (zr->running == ZORAN_MAP_MODE_JPG_REC)
839 		zoran_feed_stat_com(zr);
840 	zr->queued++;
841 }
842 
zr_vb2_prepare(struct vb2_buffer * vb)843 static int zr_vb2_prepare(struct vb2_buffer *vb)
844 {
845 	struct zoran *zr = vb2_get_drv_priv(vb->vb2_queue);
846 
847 	if (vb2_plane_size(vb, 0) < zr->buffer_size)
848 		return -EINVAL;
849 	zr->prepared++;
850 
851 	return 0;
852 }
853 
zr_set_buf(struct zoran * zr)854 int zr_set_buf(struct zoran *zr)
855 {
856 	struct zr_buffer *buf;
857 	struct vb2_v4l2_buffer *vbuf;
858 	dma_addr_t phys_addr;
859 	unsigned long flags;
860 	u32 reg;
861 
862 	if (zr->running == ZORAN_MAP_MODE_NONE)
863 		return 0;
864 
865 	if (zr->inuse[0]) {
866 		buf = zr->inuse[0];
867 		buf->vbuf.vb2_buf.timestamp = ktime_get_ns();
868 		buf->vbuf.sequence = zr->vbseq++;
869 		vbuf = &buf->vbuf;
870 
871 		buf->vbuf.field = V4L2_FIELD_INTERLACED;
872 		vb2_set_plane_payload(&buf->vbuf.vb2_buf, 0, zr->buffer_size);
873 		vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_DONE);
874 		zr->inuse[0] = NULL;
875 	}
876 
877 	spin_lock_irqsave(&zr->queued_bufs_lock, flags);
878 	if (list_empty(&zr->queued_bufs)) {
879 		btand(~ZR36057_ICR_INT_PIN_EN, ZR36057_ICR);
880 		vb2_queue_error(zr->video_dev->queue);
881 		spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
882 		return -EINVAL;
883 	}
884 	buf = list_first_entry_or_null(&zr->queued_bufs, struct zr_buffer, queue);
885 	if (!buf) {
886 		btand(~ZR36057_ICR_INT_PIN_EN, ZR36057_ICR);
887 		vb2_queue_error(zr->video_dev->queue);
888 		spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
889 		return -EINVAL;
890 	}
891 	list_del(&buf->queue);
892 	spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
893 
894 	vbuf = &buf->vbuf;
895 	vbuf->vb2_buf.state = VB2_BUF_STATE_ACTIVE;
896 	phys_addr = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);
897 
898 	if (!phys_addr)
899 		return -EINVAL;
900 
901 	zr->inuse[0] = buf;
902 
903 	reg = phys_addr;
904 	btwrite(reg, ZR36057_VDTR);
905 	if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2)
906 		reg += zr->v4l_settings.bytesperline;
907 	btwrite(reg, ZR36057_VDBR);
908 
909 	reg = 0;
910 	if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2)
911 		reg += zr->v4l_settings.bytesperline;
912 	reg = (reg << ZR36057_VSSFGR_DISP_STRIDE);
913 	reg |= ZR36057_VSSFGR_VID_OVF;
914 	reg |= ZR36057_VSSFGR_SNAP_SHOT;
915 	reg |= ZR36057_VSSFGR_FRAME_GRAB;
916 	btwrite(reg, ZR36057_VSSFGR);
917 
918 	btor(ZR36057_VDCR_VID_EN, ZR36057_VDCR);
919 	return 0;
920 }
921 
zr_vb2_start_streaming(struct vb2_queue * vq,unsigned int count)922 static int zr_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
923 {
924 	struct zoran *zr = vq->drv_priv;
925 	int j;
926 
927 	for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
928 		zr->stat_com[j] = cpu_to_le32(1);
929 		zr->inuse[j] = NULL;
930 	}
931 
932 	if (zr->map_mode != ZORAN_MAP_MODE_RAW) {
933 		pci_info(zr->pci_dev, "START JPG\n");
934 		zr36057_restart(zr);
935 		zoran_init_hardware(zr);
936 		if (zr->map_mode == ZORAN_MAP_MODE_JPG_REC)
937 			zr36057_enable_jpg(zr, BUZ_MODE_MOTION_DECOMPRESS);
938 		else
939 			zr36057_enable_jpg(zr, BUZ_MODE_MOTION_COMPRESS);
940 		zoran_feed_stat_com(zr);
941 		jpeg_start(zr);
942 		zr->running = zr->map_mode;
943 		btor(ZR36057_ICR_INT_PIN_EN, ZR36057_ICR);
944 		return 0;
945 	}
946 
947 	pci_info(zr->pci_dev, "START RAW\n");
948 	zr36057_restart(zr);
949 	zoran_init_hardware(zr);
950 
951 	zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
952 	zr36057_set_memgrab(zr, 1);
953 	zr->running = zr->map_mode;
954 	btor(ZR36057_ICR_INT_PIN_EN, ZR36057_ICR);
955 	return 0;
956 }
957 
zr_vb2_stop_streaming(struct vb2_queue * vq)958 static void zr_vb2_stop_streaming(struct vb2_queue *vq)
959 {
960 	struct zoran *zr = vq->drv_priv;
961 	struct zr_buffer *buf;
962 	unsigned long flags;
963 	int j;
964 
965 	btand(~ZR36057_ICR_INT_PIN_EN, ZR36057_ICR);
966 	if (zr->map_mode != ZORAN_MAP_MODE_RAW)
967 		zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
968 	zr36057_set_memgrab(zr, 0);
969 	zr->running = ZORAN_MAP_MODE_NONE;
970 
971 	zoran_set_pci_master(zr, 0);
972 
973 	if (!pass_through) {	/* Switch to color bar */
974 		decoder_call(zr, video, s_stream, 0);
975 		encoder_call(zr, video, s_routing, 2, 0, 0);
976 	}
977 
978 	for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
979 		zr->stat_com[j] = cpu_to_le32(1);
980 		if (!zr->inuse[j])
981 			continue;
982 		buf = zr->inuse[j];
983 		pci_dbg(zr->pci_dev, "%s clean buf %d\n", __func__, j);
984 		vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_ERROR);
985 		zr->inuse[j] = NULL;
986 	}
987 
988 	spin_lock_irqsave(&zr->queued_bufs_lock, flags);
989 	while (!list_empty(&zr->queued_bufs)) {
990 		buf = list_entry(zr->queued_bufs.next, struct zr_buffer, queue);
991 		list_del(&buf->queue);
992 		vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_ERROR);
993 		zr->buf_in_reserve--;
994 	}
995 	spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
996 	if (zr->buf_in_reserve)
997 		pci_err(zr->pci_dev, "Buffer remaining %d\n", zr->buf_in_reserve);
998 	zr->map_mode = ZORAN_MAP_MODE_RAW;
999 }
1000 
1001 static const struct vb2_ops zr_video_qops = {
1002 	.queue_setup            = zr_vb2_queue_setup,
1003 	.buf_queue              = zr_vb2_queue,
1004 	.buf_prepare            = zr_vb2_prepare,
1005 	.start_streaming        = zr_vb2_start_streaming,
1006 	.stop_streaming         = zr_vb2_stop_streaming,
1007 	.wait_prepare           = vb2_ops_wait_prepare,
1008 	.wait_finish            = vb2_ops_wait_finish,
1009 };
1010 
zoran_queue_init(struct zoran * zr,struct vb2_queue * vq)1011 int zoran_queue_init(struct zoran *zr, struct vb2_queue *vq)
1012 {
1013 	int err;
1014 
1015 	spin_lock_init(&zr->queued_bufs_lock);
1016 	INIT_LIST_HEAD(&zr->queued_bufs);
1017 
1018 	vq->dev = &zr->pci_dev->dev;
1019 	vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1020 	vq->io_modes = VB2_USERPTR | VB2_DMABUF | VB2_MMAP | VB2_READ | VB2_WRITE;
1021 	vq->drv_priv = zr;
1022 	vq->buf_struct_size = sizeof(struct zr_buffer);
1023 	vq->ops = &zr_video_qops;
1024 	vq->mem_ops = &vb2_dma_contig_memops;
1025 	vq->gfp_flags = GFP_DMA32;
1026 	vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1027 	vq->min_buffers_needed = 9;
1028 	vq->lock = &zr->lock;
1029 	err = vb2_queue_init(vq);
1030 	if (err)
1031 		return err;
1032 	zr->video_dev->queue = vq;
1033 	return 0;
1034 }
1035 
zoran_queue_exit(struct zoran * zr)1036 void zoran_queue_exit(struct zoran *zr)
1037 {
1038 	vb2_queue_release(zr->video_dev->queue);
1039 }
1040