1 #include <media/saa7146_vv.h>
2 #include <media/v4l2-chip-ident.h>
3 
4 static int max_memory = 32;
5 
6 module_param(max_memory, int, 0644);
7 MODULE_PARM_DESC(max_memory, "maximum memory usage for capture buffers (default: 32Mb)");
8 
9 #define IS_CAPTURE_ACTIVE(fh) \
10 	(((vv->video_status & STATUS_CAPTURE) != 0) && (vv->video_fh == fh))
11 
12 #define IS_OVERLAY_ACTIVE(fh) \
13 	(((vv->video_status & STATUS_OVERLAY) != 0) && (vv->video_fh == fh))
14 
15 /* format descriptions for capture and preview */
16 static struct saa7146_format formats[] = {
17 	{
18 		.name		= "RGB-8 (3-3-2)",
19 		.pixelformat	= V4L2_PIX_FMT_RGB332,
20 		.trans		= RGB08_COMPOSED,
21 		.depth		= 8,
22 		.flags		= 0,
23 	}, {
24 		.name		= "RGB-16 (5/B-6/G-5/R)",
25 		.pixelformat	= V4L2_PIX_FMT_RGB565,
26 		.trans		= RGB16_COMPOSED,
27 		.depth		= 16,
28 		.flags		= 0,
29 	}, {
30 		.name		= "RGB-24 (B-G-R)",
31 		.pixelformat	= V4L2_PIX_FMT_BGR24,
32 		.trans		= RGB24_COMPOSED,
33 		.depth		= 24,
34 		.flags		= 0,
35 	}, {
36 		.name		= "RGB-32 (B-G-R)",
37 		.pixelformat	= V4L2_PIX_FMT_BGR32,
38 		.trans		= RGB32_COMPOSED,
39 		.depth		= 32,
40 		.flags		= 0,
41 	}, {
42 		.name		= "RGB-32 (R-G-B)",
43 		.pixelformat	= V4L2_PIX_FMT_RGB32,
44 		.trans		= RGB32_COMPOSED,
45 		.depth		= 32,
46 		.flags		= 0,
47 		.swap		= 0x2,
48 	}, {
49 		.name		= "Greyscale-8",
50 		.pixelformat	= V4L2_PIX_FMT_GREY,
51 		.trans		= Y8,
52 		.depth		= 8,
53 		.flags		= 0,
54 	}, {
55 		.name		= "YUV 4:2:2 planar (Y-Cb-Cr)",
56 		.pixelformat	= V4L2_PIX_FMT_YUV422P,
57 		.trans		= YUV422_DECOMPOSED,
58 		.depth		= 16,
59 		.flags		= FORMAT_BYTE_SWAP|FORMAT_IS_PLANAR,
60 	}, {
61 		.name		= "YVU 4:2:0 planar (Y-Cb-Cr)",
62 		.pixelformat	= V4L2_PIX_FMT_YVU420,
63 		.trans		= YUV420_DECOMPOSED,
64 		.depth		= 12,
65 		.flags		= FORMAT_BYTE_SWAP|FORMAT_IS_PLANAR,
66 	}, {
67 		.name		= "YUV 4:2:0 planar (Y-Cb-Cr)",
68 		.pixelformat	= V4L2_PIX_FMT_YUV420,
69 		.trans		= YUV420_DECOMPOSED,
70 		.depth		= 12,
71 		.flags		= FORMAT_IS_PLANAR,
72 	}, {
73 		.name		= "YUV 4:2:2 (U-Y-V-Y)",
74 		.pixelformat	= V4L2_PIX_FMT_UYVY,
75 		.trans		= YUV422_COMPOSED,
76 		.depth		= 16,
77 		.flags		= 0,
78 	}
79 };
80 
81 /* unfortunately, the saa7146 contains a bug which prevents it from doing on-the-fly byte swaps.
82    due to this, it's impossible to provide additional *packed* formats, which are simply byte swapped
83    (like V4L2_PIX_FMT_YUYV) ... 8-( */
84 
85 static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format);
86 
saa7146_format_by_fourcc(struct saa7146_dev * dev,int fourcc)87 struct saa7146_format* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fourcc)
88 {
89 	int i, j = NUM_FORMATS;
90 
91 	for (i = 0; i < j; i++) {
92 		if (formats[i].pixelformat == fourcc) {
93 			return formats+i;
94 		}
95 	}
96 
97 	DEB_D(("unknown pixelformat:'%4.4s'\n",(char *)&fourcc));
98 	return NULL;
99 }
100 
101 static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f);
102 
saa7146_start_preview(struct saa7146_fh * fh)103 int saa7146_start_preview(struct saa7146_fh *fh)
104 {
105 	struct saa7146_dev *dev = fh->dev;
106 	struct saa7146_vv *vv = dev->vv_data;
107 	struct v4l2_format fmt;
108 	int ret = 0, err = 0;
109 
110 	DEB_EE(("dev:%p, fh:%p\n",dev,fh));
111 
112 	/* check if we have overlay informations */
113 	if( NULL == fh->ov.fh ) {
114 		DEB_D(("no overlay data available. try S_FMT first.\n"));
115 		return -EAGAIN;
116 	}
117 
118 	/* check if streaming capture is running */
119 	if (IS_CAPTURE_ACTIVE(fh) != 0) {
120 		DEB_D(("streaming capture is active.\n"));
121 		return -EBUSY;
122 	}
123 
124 	/* check if overlay is running */
125 	if (IS_OVERLAY_ACTIVE(fh) != 0) {
126 		if (vv->video_fh == fh) {
127 			DEB_D(("overlay is already active.\n"));
128 			return 0;
129 		}
130 		DEB_D(("overlay is already active in another open.\n"));
131 		return -EBUSY;
132 	}
133 
134 	if (0 == saa7146_res_get(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP)) {
135 		DEB_D(("cannot get necessary overlay resources\n"));
136 		return -EBUSY;
137 	}
138 
139 	fmt.fmt.win = fh->ov.win;
140 	err = vidioc_try_fmt_vid_overlay(NULL, fh, &fmt);
141 	if (0 != err) {
142 		saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
143 		return -EBUSY;
144 	}
145 	fh->ov.win = fmt.fmt.win;
146 	vv->ov_data = &fh->ov;
147 
148 	DEB_D(("%dx%d+%d+%d %s field=%s\n",
149 		fh->ov.win.w.width,fh->ov.win.w.height,
150 		fh->ov.win.w.left,fh->ov.win.w.top,
151 		vv->ov_fmt->name,v4l2_field_names[fh->ov.win.field]));
152 
153 	if (0 != (ret = saa7146_enable_overlay(fh))) {
154 		DEB_D(("enabling overlay failed: %d\n",ret));
155 		saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
156 		return ret;
157 	}
158 
159 	vv->video_status = STATUS_OVERLAY;
160 	vv->video_fh = fh;
161 
162 	return 0;
163 }
164 EXPORT_SYMBOL_GPL(saa7146_start_preview);
165 
saa7146_stop_preview(struct saa7146_fh * fh)166 int saa7146_stop_preview(struct saa7146_fh *fh)
167 {
168 	struct saa7146_dev *dev = fh->dev;
169 	struct saa7146_vv *vv = dev->vv_data;
170 
171 	DEB_EE(("dev:%p, fh:%p\n",dev,fh));
172 
173 	/* check if streaming capture is running */
174 	if (IS_CAPTURE_ACTIVE(fh) != 0) {
175 		DEB_D(("streaming capture is active.\n"));
176 		return -EBUSY;
177 	}
178 
179 	/* check if overlay is running at all */
180 	if ((vv->video_status & STATUS_OVERLAY) == 0) {
181 		DEB_D(("no active overlay.\n"));
182 		return 0;
183 	}
184 
185 	if (vv->video_fh != fh) {
186 		DEB_D(("overlay is active, but in another open.\n"));
187 		return -EBUSY;
188 	}
189 
190 	vv->video_status = 0;
191 	vv->video_fh = NULL;
192 
193 	saa7146_disable_overlay(fh);
194 
195 	saa7146_res_free(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
196 
197 	return 0;
198 }
199 EXPORT_SYMBOL_GPL(saa7146_stop_preview);
200 
201 /********************************************************************************/
202 /* device controls */
203 
204 static struct v4l2_queryctrl controls[] = {
205 	{
206 		.id		= V4L2_CID_BRIGHTNESS,
207 		.name		= "Brightness",
208 		.minimum	= 0,
209 		.maximum	= 255,
210 		.step		= 1,
211 		.default_value	= 128,
212 		.type		= V4L2_CTRL_TYPE_INTEGER,
213 		.flags 		= V4L2_CTRL_FLAG_SLIDER,
214 	},{
215 		.id		= V4L2_CID_CONTRAST,
216 		.name		= "Contrast",
217 		.minimum	= 0,
218 		.maximum	= 127,
219 		.step		= 1,
220 		.default_value	= 64,
221 		.type		= V4L2_CTRL_TYPE_INTEGER,
222 		.flags 		= V4L2_CTRL_FLAG_SLIDER,
223 	},{
224 		.id		= V4L2_CID_SATURATION,
225 		.name		= "Saturation",
226 		.minimum	= 0,
227 		.maximum	= 127,
228 		.step		= 1,
229 		.default_value	= 64,
230 		.type		= V4L2_CTRL_TYPE_INTEGER,
231 		.flags 		= V4L2_CTRL_FLAG_SLIDER,
232 	},{
233 		.id		= V4L2_CID_VFLIP,
234 		.name		= "Vertical Flip",
235 		.minimum	= 0,
236 		.maximum	= 1,
237 		.type		= V4L2_CTRL_TYPE_BOOLEAN,
238 	},{
239 		.id		= V4L2_CID_HFLIP,
240 		.name		= "Horizontal Flip",
241 		.minimum	= 0,
242 		.maximum	= 1,
243 		.type		= V4L2_CTRL_TYPE_BOOLEAN,
244 	},
245 };
246 static int NUM_CONTROLS = sizeof(controls)/sizeof(struct v4l2_queryctrl);
247 
248 #define V4L2_CID_PRIVATE_LASTP1      (V4L2_CID_PRIVATE_BASE + 0)
249 
ctrl_by_id(int id)250 static struct v4l2_queryctrl* ctrl_by_id(int id)
251 {
252 	int i;
253 
254 	for (i = 0; i < NUM_CONTROLS; i++)
255 		if (controls[i].id == id)
256 			return controls+i;
257 	return NULL;
258 }
259 
260 /********************************************************************************/
261 /* common pagetable functions */
262 
saa7146_pgtable_build(struct saa7146_dev * dev,struct saa7146_buf * buf)263 static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf)
264 {
265 	struct pci_dev *pci = dev->pci;
266 	struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
267 	struct scatterlist *list = dma->sglist;
268 	int length = dma->sglen;
269 	struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
270 
271 	DEB_EE(("dev:%p, buf:%p, sg_len:%d\n",dev,buf,length));
272 
273 	if( 0 != IS_PLANAR(sfmt->trans)) {
274 		struct saa7146_pgtable *pt1 = &buf->pt[0];
275 		struct saa7146_pgtable *pt2 = &buf->pt[1];
276 		struct saa7146_pgtable *pt3 = &buf->pt[2];
277 		__le32  *ptr1, *ptr2, *ptr3;
278 		__le32 fill;
279 
280 		int size = buf->fmt->width*buf->fmt->height;
281 		int i,p,m1,m2,m3,o1,o2;
282 
283 		switch( sfmt->depth ) {
284 			case 12: {
285 				/* create some offsets inside the page table */
286 				m1 = ((size+PAGE_SIZE)/PAGE_SIZE)-1;
287 				m2 = ((size+(size/4)+PAGE_SIZE)/PAGE_SIZE)-1;
288 				m3 = ((size+(size/2)+PAGE_SIZE)/PAGE_SIZE)-1;
289 				o1 = size%PAGE_SIZE;
290 				o2 = (size+(size/4))%PAGE_SIZE;
291 				DEB_CAP(("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",size,m1,m2,m3,o1,o2));
292 				break;
293 			}
294 			case 16: {
295 				/* create some offsets inside the page table */
296 				m1 = ((size+PAGE_SIZE)/PAGE_SIZE)-1;
297 				m2 = ((size+(size/2)+PAGE_SIZE)/PAGE_SIZE)-1;
298 				m3 = ((2*size+PAGE_SIZE)/PAGE_SIZE)-1;
299 				o1 = size%PAGE_SIZE;
300 				o2 = (size+(size/2))%PAGE_SIZE;
301 				DEB_CAP(("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",size,m1,m2,m3,o1,o2));
302 				break;
303 			}
304 			default: {
305 				return -1;
306 			}
307 		}
308 
309 		ptr1 = pt1->cpu;
310 		ptr2 = pt2->cpu;
311 		ptr3 = pt3->cpu;
312 
313 		/* walk all pages, copy all page addresses to ptr1 */
314 		for (i = 0; i < length; i++, list++) {
315 			for (p = 0; p * 4096 < list->length; p++, ptr1++) {
316 				*ptr1 = cpu_to_le32(sg_dma_address(list) - list->offset);
317 			}
318 		}
319 /*
320 		ptr1 = pt1->cpu;
321 		for(j=0;j<40;j++) {
322 			printk("ptr1 %d: 0x%08x\n",j,ptr1[j]);
323 		}
324 */
325 
326 		/* if we have a user buffer, the first page may not be
327 		   aligned to a page boundary. */
328 		pt1->offset = dma->sglist->offset;
329 		pt2->offset = pt1->offset+o1;
330 		pt3->offset = pt1->offset+o2;
331 
332 		/* create video-dma2 page table */
333 		ptr1 = pt1->cpu;
334 		for(i = m1; i <= m2 ; i++, ptr2++) {
335 			*ptr2 = ptr1[i];
336 		}
337 		fill = *(ptr2-1);
338 		for(;i<1024;i++,ptr2++) {
339 			*ptr2 = fill;
340 		}
341 		/* create video-dma3 page table */
342 		ptr1 = pt1->cpu;
343 		for(i = m2; i <= m3; i++,ptr3++) {
344 			*ptr3 = ptr1[i];
345 		}
346 		fill = *(ptr3-1);
347 		for(;i<1024;i++,ptr3++) {
348 			*ptr3 = fill;
349 		}
350 		/* finally: finish up video-dma1 page table */
351 		ptr1 = pt1->cpu+m1;
352 		fill = pt1->cpu[m1];
353 		for(i=m1;i<1024;i++,ptr1++) {
354 			*ptr1 = fill;
355 		}
356 /*
357 		ptr1 = pt1->cpu;
358 		ptr2 = pt2->cpu;
359 		ptr3 = pt3->cpu;
360 		for(j=0;j<40;j++) {
361 			printk("ptr1 %d: 0x%08x\n",j,ptr1[j]);
362 		}
363 		for(j=0;j<40;j++) {
364 			printk("ptr2 %d: 0x%08x\n",j,ptr2[j]);
365 		}
366 		for(j=0;j<40;j++) {
367 			printk("ptr3 %d: 0x%08x\n",j,ptr3[j]);
368 		}
369 */
370 	} else {
371 		struct saa7146_pgtable *pt = &buf->pt[0];
372 		return saa7146_pgtable_build_single(pci, pt, list, length);
373 	}
374 
375 	return 0;
376 }
377 
378 
379 /********************************************************************************/
380 /* file operations */
381 
video_begin(struct saa7146_fh * fh)382 static int video_begin(struct saa7146_fh *fh)
383 {
384 	struct saa7146_dev *dev = fh->dev;
385 	struct saa7146_vv *vv = dev->vv_data;
386 	struct saa7146_format *fmt = NULL;
387 	unsigned int resource;
388 	int ret = 0, err = 0;
389 
390 	DEB_EE(("dev:%p, fh:%p\n",dev,fh));
391 
392 	if ((vv->video_status & STATUS_CAPTURE) != 0) {
393 		if (vv->video_fh == fh) {
394 			DEB_S(("already capturing.\n"));
395 			return 0;
396 		}
397 		DEB_S(("already capturing in another open.\n"));
398 		return -EBUSY;
399 	}
400 
401 	if ((vv->video_status & STATUS_OVERLAY) != 0) {
402 		DEB_S(("warning: suspending overlay video for streaming capture.\n"));
403 		vv->ov_suspend = vv->video_fh;
404 		err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
405 		if (0 != err) {
406 			DEB_D(("suspending video failed. aborting\n"));
407 			return err;
408 		}
409 	}
410 
411 	fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
412 	/* we need to have a valid format set here */
413 	BUG_ON(NULL == fmt);
414 
415 	if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
416 		resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS;
417 	} else {
418 		resource = RESOURCE_DMA1_HPS;
419 	}
420 
421 	ret = saa7146_res_get(fh, resource);
422 	if (0 == ret) {
423 		DEB_S(("cannot get capture resource %d\n",resource));
424 		if (vv->ov_suspend != NULL) {
425 			saa7146_start_preview(vv->ov_suspend);
426 			vv->ov_suspend = NULL;
427 		}
428 		return -EBUSY;
429 	}
430 
431 	/* clear out beginning of streaming bit (rps register 0)*/
432 	saa7146_write(dev, MC2, MASK_27 );
433 
434 	/* enable rps0 irqs */
435 	SAA7146_IER_ENABLE(dev, MASK_27);
436 
437 	vv->video_fh = fh;
438 	vv->video_status = STATUS_CAPTURE;
439 
440 	return 0;
441 }
442 
video_end(struct saa7146_fh * fh,struct file * file)443 static int video_end(struct saa7146_fh *fh, struct file *file)
444 {
445 	struct saa7146_dev *dev = fh->dev;
446 	struct saa7146_vv *vv = dev->vv_data;
447 	struct saa7146_format *fmt = NULL;
448 	unsigned long flags;
449 	unsigned int resource;
450 	u32 dmas = 0;
451 	DEB_EE(("dev:%p, fh:%p\n",dev,fh));
452 
453 	if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
454 		DEB_S(("not capturing.\n"));
455 		return 0;
456 	}
457 
458 	if (vv->video_fh != fh) {
459 		DEB_S(("capturing, but in another open.\n"));
460 		return -EBUSY;
461 	}
462 
463 	fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
464 	/* we need to have a valid format set here */
465 	BUG_ON(NULL == fmt);
466 
467 	if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
468 		resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS;
469 		dmas = MASK_22 | MASK_21 | MASK_20;
470 	} else {
471 		resource = RESOURCE_DMA1_HPS;
472 		dmas = MASK_22;
473 	}
474 	spin_lock_irqsave(&dev->slock,flags);
475 
476 	/* disable rps0  */
477 	saa7146_write(dev, MC1, MASK_28);
478 
479 	/* disable rps0 irqs */
480 	SAA7146_IER_DISABLE(dev, MASK_27);
481 
482 	/* shut down all used video dma transfers */
483 	saa7146_write(dev, MC1, dmas);
484 
485 	spin_unlock_irqrestore(&dev->slock, flags);
486 
487 	vv->video_fh = NULL;
488 	vv->video_status = 0;
489 
490 	saa7146_res_free(fh, resource);
491 
492 	if (vv->ov_suspend != NULL) {
493 		saa7146_start_preview(vv->ov_suspend);
494 		vv->ov_suspend = NULL;
495 	}
496 
497 	return 0;
498 }
499 
vidioc_querycap(struct file * file,void * fh,struct v4l2_capability * cap)500 static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
501 {
502 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
503 
504 	strcpy((char *)cap->driver, "saa7146 v4l2");
505 	strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
506 	sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci));
507 	cap->version = SAA7146_VERSION_CODE;
508 	cap->capabilities =
509 		V4L2_CAP_VIDEO_CAPTURE |
510 		V4L2_CAP_VIDEO_OVERLAY |
511 		V4L2_CAP_READWRITE |
512 		V4L2_CAP_STREAMING;
513 	cap->capabilities |= dev->ext_vv_data->capabilities;
514 	return 0;
515 }
516 
vidioc_g_fbuf(struct file * file,void * fh,struct v4l2_framebuffer * fb)517 static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
518 {
519 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
520 	struct saa7146_vv *vv = dev->vv_data;
521 
522 	*fb = vv->ov_fb;
523 	fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
524 	return 0;
525 }
526 
vidioc_s_fbuf(struct file * file,void * fh,struct v4l2_framebuffer * fb)527 static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
528 {
529 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
530 	struct saa7146_vv *vv = dev->vv_data;
531 	struct saa7146_format *fmt;
532 
533 	DEB_EE(("VIDIOC_S_FBUF\n"));
534 
535 	if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
536 		return -EPERM;
537 
538 	/* check args */
539 	fmt = saa7146_format_by_fourcc(dev, fb->fmt.pixelformat);
540 	if (NULL == fmt)
541 		return -EINVAL;
542 
543 	/* planar formats are not allowed for overlay video, clipping and video dma would clash */
544 	if (fmt->flags & FORMAT_IS_PLANAR)
545 		DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n",
546 					(char *)&fmt->pixelformat));
547 
548 	/* check if overlay is running */
549 	if (IS_OVERLAY_ACTIVE(fh) != 0) {
550 		if (vv->video_fh != fh) {
551 			DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n"));
552 			return -EBUSY;
553 		}
554 	}
555 
556 	/* ok, accept it */
557 	vv->ov_fb = *fb;
558 	vv->ov_fmt = fmt;
559 
560 	if (vv->ov_fb.fmt.bytesperline < vv->ov_fb.fmt.width) {
561 		vv->ov_fb.fmt.bytesperline = vv->ov_fb.fmt.width * fmt->depth / 8;
562 		DEB_D(("setting bytesperline to %d\n", vv->ov_fb.fmt.bytesperline));
563 	}
564 	return 0;
565 }
566 
vidioc_enum_fmt_vid_cap(struct file * file,void * fh,struct v4l2_fmtdesc * f)567 static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
568 {
569 	if (f->index >= NUM_FORMATS)
570 		return -EINVAL;
571 	strlcpy((char *)f->description, formats[f->index].name,
572 			sizeof(f->description));
573 	f->pixelformat = formats[f->index].pixelformat;
574 	return 0;
575 }
576 
vidioc_queryctrl(struct file * file,void * fh,struct v4l2_queryctrl * c)577 static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c)
578 {
579 	const struct v4l2_queryctrl *ctrl;
580 
581 	if ((c->id <  V4L2_CID_BASE ||
582 	     c->id >= V4L2_CID_LASTP1) &&
583 	    (c->id <  V4L2_CID_PRIVATE_BASE ||
584 	     c->id >= V4L2_CID_PRIVATE_LASTP1))
585 		return -EINVAL;
586 
587 	ctrl = ctrl_by_id(c->id);
588 	if (ctrl == NULL)
589 		return -EINVAL;
590 
591 	DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n", c->id));
592 	*c = *ctrl;
593 	return 0;
594 }
595 
vidioc_g_ctrl(struct file * file,void * fh,struct v4l2_control * c)596 static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
597 {
598 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
599 	struct saa7146_vv *vv = dev->vv_data;
600 	const struct v4l2_queryctrl *ctrl;
601 	u32 value = 0;
602 
603 	ctrl = ctrl_by_id(c->id);
604 	if (NULL == ctrl)
605 		return -EINVAL;
606 	switch (c->id) {
607 	case V4L2_CID_BRIGHTNESS:
608 		value = saa7146_read(dev, BCS_CTRL);
609 		c->value = 0xff & (value >> 24);
610 		DEB_D(("V4L2_CID_BRIGHTNESS: %d\n", c->value));
611 		break;
612 	case V4L2_CID_CONTRAST:
613 		value = saa7146_read(dev, BCS_CTRL);
614 		c->value = 0x7f & (value >> 16);
615 		DEB_D(("V4L2_CID_CONTRAST: %d\n", c->value));
616 		break;
617 	case V4L2_CID_SATURATION:
618 		value = saa7146_read(dev, BCS_CTRL);
619 		c->value = 0x7f & (value >> 0);
620 		DEB_D(("V4L2_CID_SATURATION: %d\n", c->value));
621 		break;
622 	case V4L2_CID_VFLIP:
623 		c->value = vv->vflip;
624 		DEB_D(("V4L2_CID_VFLIP: %d\n", c->value));
625 		break;
626 	case V4L2_CID_HFLIP:
627 		c->value = vv->hflip;
628 		DEB_D(("V4L2_CID_HFLIP: %d\n", c->value));
629 		break;
630 	default:
631 		return -EINVAL;
632 	}
633 	return 0;
634 }
635 
vidioc_s_ctrl(struct file * file,void * fh,struct v4l2_control * c)636 static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
637 {
638 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
639 	struct saa7146_vv *vv = dev->vv_data;
640 	const struct v4l2_queryctrl *ctrl;
641 
642 	ctrl = ctrl_by_id(c->id);
643 	if (NULL == ctrl) {
644 		DEB_D(("unknown control %d\n", c->id));
645 		return -EINVAL;
646 	}
647 
648 	switch (ctrl->type) {
649 	case V4L2_CTRL_TYPE_BOOLEAN:
650 	case V4L2_CTRL_TYPE_MENU:
651 	case V4L2_CTRL_TYPE_INTEGER:
652 		if (c->value < ctrl->minimum)
653 			c->value = ctrl->minimum;
654 		if (c->value > ctrl->maximum)
655 			c->value = ctrl->maximum;
656 		break;
657 	default:
658 		/* nothing */;
659 	}
660 
661 	switch (c->id) {
662 	case V4L2_CID_BRIGHTNESS: {
663 		u32 value = saa7146_read(dev, BCS_CTRL);
664 		value &= 0x00ffffff;
665 		value |= (c->value << 24);
666 		saa7146_write(dev, BCS_CTRL, value);
667 		saa7146_write(dev, MC2, MASK_22 | MASK_06);
668 		break;
669 	}
670 	case V4L2_CID_CONTRAST: {
671 		u32 value = saa7146_read(dev, BCS_CTRL);
672 		value &= 0xff00ffff;
673 		value |= (c->value << 16);
674 		saa7146_write(dev, BCS_CTRL, value);
675 		saa7146_write(dev, MC2, MASK_22 | MASK_06);
676 		break;
677 	}
678 	case V4L2_CID_SATURATION: {
679 		u32 value = saa7146_read(dev, BCS_CTRL);
680 		value &= 0xffffff00;
681 		value |= (c->value << 0);
682 		saa7146_write(dev, BCS_CTRL, value);
683 		saa7146_write(dev, MC2, MASK_22 | MASK_06);
684 		break;
685 	}
686 	case V4L2_CID_HFLIP:
687 		/* fixme: we can support changing VFLIP and HFLIP here... */
688 		if (IS_CAPTURE_ACTIVE(fh) != 0) {
689 			DEB_D(("V4L2_CID_HFLIP while active capture.\n"));
690 			return -EBUSY;
691 		}
692 		vv->hflip = c->value;
693 		break;
694 	case V4L2_CID_VFLIP:
695 		if (IS_CAPTURE_ACTIVE(fh) != 0) {
696 			DEB_D(("V4L2_CID_VFLIP while active capture.\n"));
697 			return -EBUSY;
698 		}
699 		vv->vflip = c->value;
700 		break;
701 	default:
702 		return -EINVAL;
703 	}
704 
705 	if (IS_OVERLAY_ACTIVE(fh) != 0) {
706 		saa7146_stop_preview(fh);
707 		saa7146_start_preview(fh);
708 	}
709 	return 0;
710 }
711 
vidioc_g_parm(struct file * file,void * fh,struct v4l2_streamparm * parm)712 static int vidioc_g_parm(struct file *file, void *fh,
713 		struct v4l2_streamparm *parm)
714 {
715 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
716 	struct saa7146_vv *vv = dev->vv_data;
717 
718 	parm->parm.capture.readbuffers = 1;
719 	v4l2_video_std_frame_period(vv->standard->id,
720 				    &parm->parm.capture.timeperframe);
721 	return 0;
722 }
723 
vidioc_g_fmt_vid_cap(struct file * file,void * fh,struct v4l2_format * f)724 static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
725 {
726 	f->fmt.pix = ((struct saa7146_fh *)fh)->video_fmt;
727 	return 0;
728 }
729 
vidioc_g_fmt_vid_overlay(struct file * file,void * fh,struct v4l2_format * f)730 static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
731 {
732 	f->fmt.win = ((struct saa7146_fh *)fh)->ov.win;
733 	return 0;
734 }
735 
vidioc_g_fmt_vbi_cap(struct file * file,void * fh,struct v4l2_format * f)736 static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f)
737 {
738 	f->fmt.vbi = ((struct saa7146_fh *)fh)->vbi_fmt;
739 	return 0;
740 }
741 
vidioc_try_fmt_vid_cap(struct file * file,void * fh,struct v4l2_format * f)742 static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
743 {
744 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
745 	struct saa7146_vv *vv = dev->vv_data;
746 	struct saa7146_format *fmt;
747 	enum v4l2_field field;
748 	int maxw, maxh;
749 	int calc_bpl;
750 
751 	DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh));
752 
753 	fmt = saa7146_format_by_fourcc(dev, f->fmt.pix.pixelformat);
754 	if (NULL == fmt)
755 		return -EINVAL;
756 
757 	field = f->fmt.pix.field;
758 	maxw  = vv->standard->h_max_out;
759 	maxh  = vv->standard->v_max_out;
760 
761 	if (V4L2_FIELD_ANY == field) {
762 		field = (f->fmt.pix.height > maxh / 2)
763 			? V4L2_FIELD_INTERLACED
764 			: V4L2_FIELD_BOTTOM;
765 	}
766 	switch (field) {
767 	case V4L2_FIELD_ALTERNATE:
768 		vv->last_field = V4L2_FIELD_TOP;
769 		maxh = maxh / 2;
770 		break;
771 	case V4L2_FIELD_TOP:
772 	case V4L2_FIELD_BOTTOM:
773 		vv->last_field = V4L2_FIELD_INTERLACED;
774 		maxh = maxh / 2;
775 		break;
776 	case V4L2_FIELD_INTERLACED:
777 		vv->last_field = V4L2_FIELD_INTERLACED;
778 		break;
779 	default:
780 		DEB_D(("no known field mode '%d'.\n", field));
781 		return -EINVAL;
782 	}
783 
784 	f->fmt.pix.field = field;
785 	if (f->fmt.pix.width > maxw)
786 		f->fmt.pix.width = maxw;
787 	if (f->fmt.pix.height > maxh)
788 		f->fmt.pix.height = maxh;
789 
790 	calc_bpl = (f->fmt.pix.width * fmt->depth) / 8;
791 
792 	if (f->fmt.pix.bytesperline < calc_bpl)
793 		f->fmt.pix.bytesperline = calc_bpl;
794 
795 	if (f->fmt.pix.bytesperline > (2 * PAGE_SIZE * fmt->depth) / 8) /* arbitrary constraint */
796 		f->fmt.pix.bytesperline = calc_bpl;
797 
798 	f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height;
799 	DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n", f->fmt.pix.width,
800 			f->fmt.pix.height, f->fmt.pix.bytesperline, f->fmt.pix.sizeimage));
801 
802 	return 0;
803 }
804 
805 
vidioc_try_fmt_vid_overlay(struct file * file,void * fh,struct v4l2_format * f)806 static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
807 {
808 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
809 	struct saa7146_vv *vv = dev->vv_data;
810 	struct v4l2_window *win = &f->fmt.win;
811 	enum v4l2_field field;
812 	int maxw, maxh;
813 
814 	DEB_EE(("dev:%p\n", dev));
815 
816 	if (NULL == vv->ov_fb.base) {
817 		DEB_D(("no fb base set.\n"));
818 		return -EINVAL;
819 	}
820 	if (NULL == vv->ov_fmt) {
821 		DEB_D(("no fb fmt set.\n"));
822 		return -EINVAL;
823 	}
824 	if (win->w.width < 48 || win->w.height < 32) {
825 		DEB_D(("min width/height. (%d,%d)\n", win->w.width, win->w.height));
826 		return -EINVAL;
827 	}
828 	if (win->clipcount > 16) {
829 		DEB_D(("clipcount too big.\n"));
830 		return -EINVAL;
831 	}
832 
833 	field = win->field;
834 	maxw  = vv->standard->h_max_out;
835 	maxh  = vv->standard->v_max_out;
836 
837 	if (V4L2_FIELD_ANY == field) {
838 		field = (win->w.height > maxh / 2)
839 			? V4L2_FIELD_INTERLACED
840 			: V4L2_FIELD_TOP;
841 		}
842 	switch (field) {
843 	case V4L2_FIELD_TOP:
844 	case V4L2_FIELD_BOTTOM:
845 	case V4L2_FIELD_ALTERNATE:
846 		maxh = maxh / 2;
847 		break;
848 	case V4L2_FIELD_INTERLACED:
849 		break;
850 	default:
851 		DEB_D(("no known field mode '%d'.\n", field));
852 		return -EINVAL;
853 	}
854 
855 	win->field = field;
856 	if (win->w.width > maxw)
857 		win->w.width = maxw;
858 	if (win->w.height > maxh)
859 		win->w.height = maxh;
860 
861 	return 0;
862 }
863 
vidioc_s_fmt_vid_cap(struct file * file,void * __fh,struct v4l2_format * f)864 static int vidioc_s_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_format *f)
865 {
866 	struct saa7146_fh *fh = __fh;
867 	struct saa7146_dev *dev = fh->dev;
868 	struct saa7146_vv *vv = dev->vv_data;
869 	int err;
870 
871 	DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh));
872 	if (IS_CAPTURE_ACTIVE(fh) != 0) {
873 		DEB_EE(("streaming capture is active\n"));
874 		return -EBUSY;
875 	}
876 	err = vidioc_try_fmt_vid_cap(file, fh, f);
877 	if (0 != err)
878 		return err;
879 	fh->video_fmt = f->fmt.pix;
880 	DEB_EE(("set to pixelformat '%4.4s'\n", (char *)&fh->video_fmt.pixelformat));
881 	return 0;
882 }
883 
vidioc_s_fmt_vid_overlay(struct file * file,void * __fh,struct v4l2_format * f)884 static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_format *f)
885 {
886 	struct saa7146_fh *fh = __fh;
887 	struct saa7146_dev *dev = fh->dev;
888 	struct saa7146_vv *vv = dev->vv_data;
889 	int err;
890 
891 	DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n", dev, fh));
892 	err = vidioc_try_fmt_vid_overlay(file, fh, f);
893 	if (0 != err)
894 		return err;
895 	fh->ov.win    = f->fmt.win;
896 	fh->ov.nclips = f->fmt.win.clipcount;
897 	if (fh->ov.nclips > 16)
898 		fh->ov.nclips = 16;
899 	if (copy_from_user(fh->ov.clips, f->fmt.win.clips,
900 				sizeof(struct v4l2_clip) * fh->ov.nclips)) {
901 		return -EFAULT;
902 	}
903 
904 	/* fh->ov.fh is used to indicate that we have valid overlay informations, too */
905 	fh->ov.fh = fh;
906 
907 	/* check if our current overlay is active */
908 	if (IS_OVERLAY_ACTIVE(fh) != 0) {
909 		saa7146_stop_preview(fh);
910 		saa7146_start_preview(fh);
911 	}
912 	return 0;
913 }
914 
vidioc_g_std(struct file * file,void * fh,v4l2_std_id * norm)915 static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm)
916 {
917 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
918 	struct saa7146_vv *vv = dev->vv_data;
919 
920 	*norm = vv->standard->id;
921 	return 0;
922 }
923 
924 	/* the saa7146 supfhrts (used in conjunction with the saa7111a for example)
925 	   PAL / NTSC / SECAM. if your hardware does not (or does more)
926 	   -- override this function in your extension */
927 /*
928 	case VIDIOC_ENUMSTD:
929 	{
930 		struct v4l2_standard *e = arg;
931 		if (e->index < 0 )
932 			return -EINVAL;
933 		if( e->index < dev->ext_vv_data->num_stds ) {
934 			DEB_EE(("VIDIOC_ENUMSTD: index:%d\n",e->index));
935 			v4l2_video_std_construct(e, dev->ext_vv_data->stds[e->index].id, dev->ext_vv_data->stds[e->index].name);
936 			return 0;
937 		}
938 		return -EINVAL;
939 	}
940 	*/
941 
vidioc_s_std(struct file * file,void * fh,v4l2_std_id * id)942 static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id)
943 {
944 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
945 	struct saa7146_vv *vv = dev->vv_data;
946 	int found = 0;
947 	int err, i;
948 
949 	DEB_EE(("VIDIOC_S_STD\n"));
950 
951 	if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) {
952 		DEB_D(("cannot change video standard while streaming capture is active\n"));
953 		return -EBUSY;
954 	}
955 
956 	if ((vv->video_status & STATUS_OVERLAY) != 0) {
957 		vv->ov_suspend = vv->video_fh;
958 		err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
959 		if (0 != err) {
960 			DEB_D(("suspending video failed. aborting\n"));
961 			return err;
962 		}
963 	}
964 
965 	for (i = 0; i < dev->ext_vv_data->num_stds; i++)
966 		if (*id & dev->ext_vv_data->stds[i].id)
967 			break;
968 	if (i != dev->ext_vv_data->num_stds) {
969 		vv->standard = &dev->ext_vv_data->stds[i];
970 		if (NULL != dev->ext_vv_data->std_callback)
971 			dev->ext_vv_data->std_callback(dev, vv->standard);
972 		found = 1;
973 	}
974 
975 	if (vv->ov_suspend != NULL) {
976 		saa7146_start_preview(vv->ov_suspend);
977 		vv->ov_suspend = NULL;
978 	}
979 
980 	if (!found) {
981 		DEB_EE(("VIDIOC_S_STD: standard not found.\n"));
982 		return -EINVAL;
983 	}
984 
985 	DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n", vv->standard->name));
986 	return 0;
987 }
988 
vidioc_overlay(struct file * file,void * fh,unsigned int on)989 static int vidioc_overlay(struct file *file, void *fh, unsigned int on)
990 {
991 	int err;
992 
993 	DEB_D(("VIDIOC_OVERLAY on:%d\n", on));
994 	if (on)
995 		err = saa7146_start_preview(fh);
996 	else
997 		err = saa7146_stop_preview(fh);
998 	return err;
999 }
1000 
vidioc_reqbufs(struct file * file,void * __fh,struct v4l2_requestbuffers * b)1001 static int vidioc_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *b)
1002 {
1003 	struct saa7146_fh *fh = __fh;
1004 
1005 	if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1006 		return videobuf_reqbufs(&fh->video_q, b);
1007 	if (b->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1008 		return videobuf_reqbufs(&fh->vbi_q, b);
1009 	return -EINVAL;
1010 }
1011 
vidioc_querybuf(struct file * file,void * __fh,struct v4l2_buffer * buf)1012 static int vidioc_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
1013 {
1014 	struct saa7146_fh *fh = __fh;
1015 
1016 	if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1017 		return videobuf_querybuf(&fh->video_q, buf);
1018 	if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1019 		return videobuf_querybuf(&fh->vbi_q, buf);
1020 	return -EINVAL;
1021 }
1022 
vidioc_qbuf(struct file * file,void * __fh,struct v4l2_buffer * buf)1023 static int vidioc_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
1024 {
1025 	struct saa7146_fh *fh = __fh;
1026 
1027 	if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1028 		return videobuf_qbuf(&fh->video_q, buf);
1029 	if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1030 		return videobuf_qbuf(&fh->vbi_q, buf);
1031 	return -EINVAL;
1032 }
1033 
vidioc_dqbuf(struct file * file,void * __fh,struct v4l2_buffer * buf)1034 static int vidioc_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
1035 {
1036 	struct saa7146_fh *fh = __fh;
1037 
1038 	if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1039 		return videobuf_dqbuf(&fh->video_q, buf, file->f_flags & O_NONBLOCK);
1040 	if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1041 		return videobuf_dqbuf(&fh->vbi_q, buf, file->f_flags & O_NONBLOCK);
1042 	return -EINVAL;
1043 }
1044 
vidioc_streamon(struct file * file,void * __fh,enum v4l2_buf_type type)1045 static int vidioc_streamon(struct file *file, void *__fh, enum v4l2_buf_type type)
1046 {
1047 	struct saa7146_fh *fh = __fh;
1048 	int err;
1049 
1050 	DEB_D(("VIDIOC_STREAMON, type:%d\n", type));
1051 
1052 	err = video_begin(fh);
1053 	if (err)
1054 		return err;
1055 	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1056 		return videobuf_streamon(&fh->video_q);
1057 	if (type == V4L2_BUF_TYPE_VBI_CAPTURE)
1058 		return videobuf_streamon(&fh->vbi_q);
1059 	return -EINVAL;
1060 }
1061 
vidioc_streamoff(struct file * file,void * __fh,enum v4l2_buf_type type)1062 static int vidioc_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type)
1063 {
1064 	struct saa7146_fh *fh = __fh;
1065 	struct saa7146_dev *dev = fh->dev;
1066 	struct saa7146_vv *vv = dev->vv_data;
1067 	int err;
1068 
1069 	DEB_D(("VIDIOC_STREAMOFF, type:%d\n", type));
1070 
1071 	/* ugly: we need to copy some checks from video_end(),
1072 	   because videobuf_streamoff() relies on the capture running.
1073 	   check and fix this */
1074 	if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
1075 		DEB_S(("not capturing.\n"));
1076 		return 0;
1077 	}
1078 
1079 	if (vv->video_fh != fh) {
1080 		DEB_S(("capturing, but in another open.\n"));
1081 		return -EBUSY;
1082 	}
1083 
1084 	err = -EINVAL;
1085 	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1086 		err = videobuf_streamoff(&fh->video_q);
1087 	else if (type == V4L2_BUF_TYPE_VBI_CAPTURE)
1088 		err = videobuf_streamoff(&fh->vbi_q);
1089 	if (0 != err) {
1090 		DEB_D(("warning: videobuf_streamoff() failed.\n"));
1091 		video_end(fh, file);
1092 	} else {
1093 		err = video_end(fh, file);
1094 	}
1095 	return err;
1096 }
1097 
vidioc_g_chip_ident(struct file * file,void * __fh,struct v4l2_dbg_chip_ident * chip)1098 static int vidioc_g_chip_ident(struct file *file, void *__fh,
1099 		struct v4l2_dbg_chip_ident *chip)
1100 {
1101 	struct saa7146_fh *fh = __fh;
1102 	struct saa7146_dev *dev = fh->dev;
1103 
1104 	chip->ident = V4L2_IDENT_NONE;
1105 	chip->revision = 0;
1106 	if (chip->match.type == V4L2_CHIP_MATCH_HOST && !chip->match.addr) {
1107 		chip->ident = V4L2_IDENT_SAA7146;
1108 		return 0;
1109 	}
1110 	return v4l2_device_call_until_err(&dev->v4l2_dev, 0,
1111 			core, g_chip_ident, chip);
1112 }
1113 
1114 const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
1115 	.vidioc_querycap             = vidioc_querycap,
1116 	.vidioc_enum_fmt_vid_cap     = vidioc_enum_fmt_vid_cap,
1117 	.vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_cap,
1118 	.vidioc_g_fmt_vid_cap        = vidioc_g_fmt_vid_cap,
1119 	.vidioc_try_fmt_vid_cap      = vidioc_try_fmt_vid_cap,
1120 	.vidioc_s_fmt_vid_cap        = vidioc_s_fmt_vid_cap,
1121 	.vidioc_g_fmt_vid_overlay    = vidioc_g_fmt_vid_overlay,
1122 	.vidioc_try_fmt_vid_overlay  = vidioc_try_fmt_vid_overlay,
1123 	.vidioc_s_fmt_vid_overlay    = vidioc_s_fmt_vid_overlay,
1124 	.vidioc_g_fmt_vbi_cap        = vidioc_g_fmt_vbi_cap,
1125 	.vidioc_g_chip_ident         = vidioc_g_chip_ident,
1126 
1127 	.vidioc_overlay 	     = vidioc_overlay,
1128 	.vidioc_g_fbuf  	     = vidioc_g_fbuf,
1129 	.vidioc_s_fbuf  	     = vidioc_s_fbuf,
1130 	.vidioc_reqbufs              = vidioc_reqbufs,
1131 	.vidioc_querybuf             = vidioc_querybuf,
1132 	.vidioc_qbuf                 = vidioc_qbuf,
1133 	.vidioc_dqbuf                = vidioc_dqbuf,
1134 	.vidioc_g_std                = vidioc_g_std,
1135 	.vidioc_s_std                = vidioc_s_std,
1136 	.vidioc_queryctrl            = vidioc_queryctrl,
1137 	.vidioc_g_ctrl               = vidioc_g_ctrl,
1138 	.vidioc_s_ctrl               = vidioc_s_ctrl,
1139 	.vidioc_streamon             = vidioc_streamon,
1140 	.vidioc_streamoff            = vidioc_streamoff,
1141 	.vidioc_g_parm 		     = vidioc_g_parm,
1142 };
1143 
1144 /*********************************************************************************/
1145 /* buffer handling functions                                                  */
1146 
buffer_activate(struct saa7146_dev * dev,struct saa7146_buf * buf,struct saa7146_buf * next)1147 static int buffer_activate (struct saa7146_dev *dev,
1148 		     struct saa7146_buf *buf,
1149 		     struct saa7146_buf *next)
1150 {
1151 	struct saa7146_vv *vv = dev->vv_data;
1152 
1153 	buf->vb.state = VIDEOBUF_ACTIVE;
1154 	saa7146_set_capture(dev,buf,next);
1155 
1156 	mod_timer(&vv->video_q.timeout, jiffies+BUFFER_TIMEOUT);
1157 	return 0;
1158 }
1159 
release_all_pagetables(struct saa7146_dev * dev,struct saa7146_buf * buf)1160 static void release_all_pagetables(struct saa7146_dev *dev, struct saa7146_buf *buf)
1161 {
1162 	saa7146_pgtable_free(dev->pci, &buf->pt[0]);
1163 	saa7146_pgtable_free(dev->pci, &buf->pt[1]);
1164 	saa7146_pgtable_free(dev->pci, &buf->pt[2]);
1165 }
1166 
buffer_prepare(struct videobuf_queue * q,struct videobuf_buffer * vb,enum v4l2_field field)1167 static int buffer_prepare(struct videobuf_queue *q,
1168 			  struct videobuf_buffer *vb, enum v4l2_field field)
1169 {
1170 	struct file *file = q->priv_data;
1171 	struct saa7146_fh *fh = file->private_data;
1172 	struct saa7146_dev *dev = fh->dev;
1173 	struct saa7146_vv *vv = dev->vv_data;
1174 	struct saa7146_buf *buf = (struct saa7146_buf *)vb;
1175 	int size,err = 0;
1176 
1177 	DEB_CAP(("vbuf:%p\n",vb));
1178 
1179 	/* sanity checks */
1180 	if (fh->video_fmt.width  < 48 ||
1181 	    fh->video_fmt.height < 32 ||
1182 	    fh->video_fmt.width  > vv->standard->h_max_out ||
1183 	    fh->video_fmt.height > vv->standard->v_max_out) {
1184 		DEB_D(("w (%d) / h (%d) out of bounds.\n",fh->video_fmt.width,fh->video_fmt.height));
1185 		return -EINVAL;
1186 	}
1187 
1188 	size = fh->video_fmt.sizeimage;
1189 	if (0 != buf->vb.baddr && buf->vb.bsize < size) {
1190 		DEB_D(("size mismatch.\n"));
1191 		return -EINVAL;
1192 	}
1193 
1194 	DEB_CAP(("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n",
1195 		fh->video_fmt.width,fh->video_fmt.height,size,v4l2_field_names[fh->video_fmt.field]));
1196 	if (buf->vb.width  != fh->video_fmt.width  ||
1197 	    buf->vb.bytesperline != fh->video_fmt.bytesperline ||
1198 	    buf->vb.height != fh->video_fmt.height ||
1199 	    buf->vb.size   != size ||
1200 	    buf->vb.field  != field      ||
1201 	    buf->vb.field  != fh->video_fmt.field  ||
1202 	    buf->fmt       != &fh->video_fmt) {
1203 		saa7146_dma_free(dev,q,buf);
1204 	}
1205 
1206 	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
1207 		struct saa7146_format *sfmt;
1208 
1209 		buf->vb.bytesperline  = fh->video_fmt.bytesperline;
1210 		buf->vb.width  = fh->video_fmt.width;
1211 		buf->vb.height = fh->video_fmt.height;
1212 		buf->vb.size   = size;
1213 		buf->vb.field  = field;
1214 		buf->fmt       = &fh->video_fmt;
1215 		buf->vb.field  = fh->video_fmt.field;
1216 
1217 		sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
1218 
1219 		release_all_pagetables(dev, buf);
1220 		if( 0 != IS_PLANAR(sfmt->trans)) {
1221 			saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
1222 			saa7146_pgtable_alloc(dev->pci, &buf->pt[1]);
1223 			saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
1224 		} else {
1225 			saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
1226 		}
1227 
1228 		err = videobuf_iolock(q,&buf->vb, &vv->ov_fb);
1229 		if (err)
1230 			goto oops;
1231 		err = saa7146_pgtable_build(dev,buf);
1232 		if (err)
1233 			goto oops;
1234 	}
1235 	buf->vb.state = VIDEOBUF_PREPARED;
1236 	buf->activate = buffer_activate;
1237 
1238 	return 0;
1239 
1240  oops:
1241 	DEB_D(("error out.\n"));
1242 	saa7146_dma_free(dev,q,buf);
1243 
1244 	return err;
1245 }
1246 
buffer_setup(struct videobuf_queue * q,unsigned int * count,unsigned int * size)1247 static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
1248 {
1249 	struct file *file = q->priv_data;
1250 	struct saa7146_fh *fh = file->private_data;
1251 
1252 	if (0 == *count || *count > MAX_SAA7146_CAPTURE_BUFFERS)
1253 		*count = MAX_SAA7146_CAPTURE_BUFFERS;
1254 
1255 	*size = fh->video_fmt.sizeimage;
1256 
1257 	/* check if we exceed the "max_memory" parameter */
1258 	if( (*count * *size) > (max_memory*1048576) ) {
1259 		*count = (max_memory*1048576) / *size;
1260 	}
1261 
1262 	DEB_CAP(("%d buffers, %d bytes each.\n",*count,*size));
1263 
1264 	return 0;
1265 }
1266 
buffer_queue(struct videobuf_queue * q,struct videobuf_buffer * vb)1267 static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
1268 {
1269 	struct file *file = q->priv_data;
1270 	struct saa7146_fh *fh = file->private_data;
1271 	struct saa7146_dev *dev = fh->dev;
1272 	struct saa7146_vv *vv = dev->vv_data;
1273 	struct saa7146_buf *buf = (struct saa7146_buf *)vb;
1274 
1275 	DEB_CAP(("vbuf:%p\n",vb));
1276 	saa7146_buffer_queue(fh->dev,&vv->video_q,buf);
1277 }
1278 
buffer_release(struct videobuf_queue * q,struct videobuf_buffer * vb)1279 static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
1280 {
1281 	struct file *file = q->priv_data;
1282 	struct saa7146_fh *fh = file->private_data;
1283 	struct saa7146_dev *dev = fh->dev;
1284 	struct saa7146_buf *buf = (struct saa7146_buf *)vb;
1285 
1286 	DEB_CAP(("vbuf:%p\n",vb));
1287 
1288 	saa7146_dma_free(dev,q,buf);
1289 
1290 	release_all_pagetables(dev, buf);
1291 }
1292 
1293 static struct videobuf_queue_ops video_qops = {
1294 	.buf_setup    = buffer_setup,
1295 	.buf_prepare  = buffer_prepare,
1296 	.buf_queue    = buffer_queue,
1297 	.buf_release  = buffer_release,
1298 };
1299 
1300 /********************************************************************************/
1301 /* file operations */
1302 
video_init(struct saa7146_dev * dev,struct saa7146_vv * vv)1303 static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
1304 {
1305 	INIT_LIST_HEAD(&vv->video_q.queue);
1306 
1307 	init_timer(&vv->video_q.timeout);
1308 	vv->video_q.timeout.function = saa7146_buffer_timeout;
1309 	vv->video_q.timeout.data     = (unsigned long)(&vv->video_q);
1310 	vv->video_q.dev              = dev;
1311 
1312 	/* set some default values */
1313 	vv->standard = &dev->ext_vv_data->stds[0];
1314 
1315 	/* FIXME: what's this? */
1316 	vv->current_hps_source = SAA7146_HPS_SOURCE_PORT_A;
1317 	vv->current_hps_sync = SAA7146_HPS_SYNC_PORT_A;
1318 }
1319 
1320 
video_open(struct saa7146_dev * dev,struct file * file)1321 static int video_open(struct saa7146_dev *dev, struct file *file)
1322 {
1323 	struct saa7146_fh *fh = file->private_data;
1324 	struct saa7146_format *sfmt;
1325 
1326 	fh->video_fmt.width = 384;
1327 	fh->video_fmt.height = 288;
1328 	fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24;
1329 	fh->video_fmt.bytesperline = 0;
1330 	fh->video_fmt.field = V4L2_FIELD_ANY;
1331 	sfmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
1332 	fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8;
1333 
1334 	videobuf_queue_sg_init(&fh->video_q, &video_qops,
1335 			    &dev->pci->dev, &dev->slock,
1336 			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
1337 			    V4L2_FIELD_INTERLACED,
1338 			    sizeof(struct saa7146_buf),
1339 			    file, &dev->v4l2_lock);
1340 
1341 	return 0;
1342 }
1343 
1344 
video_close(struct saa7146_dev * dev,struct file * file)1345 static void video_close(struct saa7146_dev *dev, struct file *file)
1346 {
1347 	struct saa7146_fh *fh = file->private_data;
1348 	struct saa7146_vv *vv = dev->vv_data;
1349 	struct videobuf_queue *q = &fh->video_q;
1350 	int err;
1351 
1352 	if (IS_CAPTURE_ACTIVE(fh) != 0) {
1353 		err = video_end(fh, file);
1354 	} else if (IS_OVERLAY_ACTIVE(fh) != 0) {
1355 		err = saa7146_stop_preview(fh);
1356 	}
1357 
1358 	videobuf_stop(q);
1359 
1360 	/* hmm, why is this function declared void? */
1361 	/* return err */
1362 }
1363 
1364 
video_irq_done(struct saa7146_dev * dev,unsigned long st)1365 static void video_irq_done(struct saa7146_dev *dev, unsigned long st)
1366 {
1367 	struct saa7146_vv *vv = dev->vv_data;
1368 	struct saa7146_dmaqueue *q = &vv->video_q;
1369 
1370 	spin_lock(&dev->slock);
1371 	DEB_CAP(("called.\n"));
1372 
1373 	/* only finish the buffer if we have one... */
1374 	if( NULL != q->curr ) {
1375 		saa7146_buffer_finish(dev,q,VIDEOBUF_DONE);
1376 	}
1377 	saa7146_buffer_next(dev,q,0);
1378 
1379 	spin_unlock(&dev->slock);
1380 }
1381 
video_read(struct file * file,char __user * data,size_t count,loff_t * ppos)1382 static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1383 {
1384 	struct saa7146_fh *fh = file->private_data;
1385 	struct saa7146_dev *dev = fh->dev;
1386 	struct saa7146_vv *vv = dev->vv_data;
1387 	ssize_t ret = 0;
1388 
1389 	DEB_EE(("called.\n"));
1390 
1391 	if ((vv->video_status & STATUS_CAPTURE) != 0) {
1392 		/* fixme: should we allow read() captures while streaming capture? */
1393 		if (vv->video_fh == fh) {
1394 			DEB_S(("already capturing.\n"));
1395 			return -EBUSY;
1396 		}
1397 		DEB_S(("already capturing in another open.\n"));
1398 		return -EBUSY;
1399 	}
1400 
1401 	ret = video_begin(fh);
1402 	if( 0 != ret) {
1403 		goto out;
1404 	}
1405 
1406 	ret = videobuf_read_one(&fh->video_q , data, count, ppos,
1407 				file->f_flags & O_NONBLOCK);
1408 	if (ret != 0) {
1409 		video_end(fh, file);
1410 	} else {
1411 		ret = video_end(fh, file);
1412 	}
1413 out:
1414 	/* restart overlay if it was active before */
1415 	if (vv->ov_suspend != NULL) {
1416 		saa7146_start_preview(vv->ov_suspend);
1417 		vv->ov_suspend = NULL;
1418 	}
1419 
1420 	return ret;
1421 }
1422 
1423 struct saa7146_use_ops saa7146_video_uops = {
1424 	.init = video_init,
1425 	.open = video_open,
1426 	.release = video_close,
1427 	.irq_done = video_irq_done,
1428 	.read = video_read,
1429 };
1430