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