diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2009-01-18 17:59:11 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:42:24 -0400 |
commit | b960074fec573fb1b226d9e2686ce51be807cdf1 (patch) | |
tree | da58b7afa37b0ccd1c06948ad6497cb801553335 /drivers/media/common | |
parent | c9b8b04b267f9a7e472daa06cdf6d4963d503d1f (diff) |
V4L/DVB (10271): saa7146: convert to video_ioctl2.
The conversion to video_ioctl2 is the first phase to converting this driver
to the latest v4l2 framework.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/common')
-rw-r--r-- | drivers/media/common/saa7146_fops.c | 36 | ||||
-rw-r--r-- | drivers/media/common/saa7146_video.c | 1250 |
2 files changed, 614 insertions, 672 deletions
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index cf06f4d10ad4..4a27d4eda628 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c | |||
@@ -308,14 +308,6 @@ static int fops_release(struct file *file) | |||
308 | return 0; | 308 | return 0; |
309 | } | 309 | } |
310 | 310 | ||
311 | static long fops_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
312 | { | ||
313 | /* | ||
314 | DEB_EE(("file:%p, cmd:%d, arg:%li\n", file, cmd, arg)); | ||
315 | */ | ||
316 | return video_usercopy(file, cmd, arg, saa7146_video_do_ioctl); | ||
317 | } | ||
318 | |||
319 | static int fops_mmap(struct file *file, struct vm_area_struct * vma) | 311 | static int fops_mmap(struct file *file, struct vm_area_struct * vma) |
320 | { | 312 | { |
321 | struct saa7146_fh *fh = file->private_data; | 313 | struct saa7146_fh *fh = file->private_data; |
@@ -425,7 +417,7 @@ static const struct v4l2_file_operations video_fops = | |||
425 | .write = fops_write, | 417 | .write = fops_write, |
426 | .poll = fops_poll, | 418 | .poll = fops_poll, |
427 | .mmap = fops_mmap, | 419 | .mmap = fops_mmap, |
428 | .ioctl = fops_ioctl, | 420 | .ioctl = video_ioctl2, |
429 | }; | 421 | }; |
430 | 422 | ||
431 | static void vv_callback(struct saa7146_dev *dev, unsigned long status) | 423 | static void vv_callback(struct saa7146_dev *dev, unsigned long status) |
@@ -452,19 +444,16 @@ static void vv_callback(struct saa7146_dev *dev, unsigned long status) | |||
452 | } | 444 | } |
453 | } | 445 | } |
454 | 446 | ||
455 | static struct video_device device_template = | ||
456 | { | ||
457 | .fops = &video_fops, | ||
458 | .minor = -1, | ||
459 | }; | ||
460 | |||
461 | int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) | 447 | int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) |
462 | { | 448 | { |
463 | struct saa7146_vv *vv = kzalloc (sizeof(struct saa7146_vv),GFP_KERNEL); | 449 | struct saa7146_vv *vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL); |
464 | if( NULL == vv ) { | 450 | |
451 | if (vv == NULL) { | ||
465 | ERR(("out of memory. aborting.\n")); | 452 | ERR(("out of memory. aborting.\n")); |
466 | return -1; | 453 | return -1; |
467 | } | 454 | } |
455 | ext_vv->ops = saa7146_video_ioctl_ops; | ||
456 | ext_vv->core_ops = &saa7146_video_ioctl_ops; | ||
468 | 457 | ||
469 | DEB_EE(("dev:%p\n",dev)); | 458 | DEB_EE(("dev:%p\n",dev)); |
470 | 459 | ||
@@ -521,6 +510,7 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, | |||
521 | { | 510 | { |
522 | struct saa7146_vv *vv = dev->vv_data; | 511 | struct saa7146_vv *vv = dev->vv_data; |
523 | struct video_device *vfd; | 512 | struct video_device *vfd; |
513 | int err; | ||
524 | 514 | ||
525 | DEB_EE(("dev:%p, name:'%s', type:%d\n",dev,name,type)); | 515 | DEB_EE(("dev:%p, name:'%s', type:%d\n",dev,name,type)); |
526 | 516 | ||
@@ -529,16 +519,18 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, | |||
529 | if (vfd == NULL) | 519 | if (vfd == NULL) |
530 | return -ENOMEM; | 520 | return -ENOMEM; |
531 | 521 | ||
532 | memcpy(vfd, &device_template, sizeof(struct video_device)); | 522 | vfd->fops = &video_fops; |
533 | strlcpy(vfd->name, name, sizeof(vfd->name)); | 523 | vfd->ioctl_ops = dev->ext_vv_data ? &dev->ext_vv_data->ops : |
524 | &saa7146_video_ioctl_ops; | ||
534 | vfd->release = video_device_release; | 525 | vfd->release = video_device_release; |
526 | strlcpy(vfd->name, name, sizeof(vfd->name)); | ||
535 | video_set_drvdata(vfd, dev); | 527 | video_set_drvdata(vfd, dev); |
536 | 528 | ||
537 | // fixme: -1 should be an insmod parameter *for the extension* (like "video_nr"); | 529 | err = video_register_device(vfd, type, -1); |
538 | if (video_register_device(vfd, type, -1) < 0) { | 530 | if (err < 0) { |
539 | ERR(("cannot register v4l2 device. skipping.\n")); | 531 | ERR(("cannot register v4l2 device. skipping.\n")); |
540 | video_device_release(vfd); | 532 | video_device_release(vfd); |
541 | return -1; | 533 | return err; |
542 | } | 534 | } |
543 | 535 | ||
544 | if( VFL_TYPE_GRABBER == type ) { | 536 | if( VFL_TYPE_GRABBER == type ) { |
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index 47fee05eaefb..91b7a4def46c 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c | |||
@@ -97,172 +97,13 @@ struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc) | |||
97 | return NULL; | 97 | return NULL; |
98 | } | 98 | } |
99 | 99 | ||
100 | static int g_fmt(struct saa7146_fh *fh, struct v4l2_format *f) | 100 | static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f); |
101 | { | ||
102 | struct saa7146_dev *dev = fh->dev; | ||
103 | DEB_EE(("dev:%p, fh:%p\n",dev,fh)); | ||
104 | |||
105 | switch (f->type) { | ||
106 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
107 | f->fmt.pix = fh->video_fmt; | ||
108 | return 0; | ||
109 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
110 | f->fmt.win = fh->ov.win; | ||
111 | return 0; | ||
112 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
113 | { | ||
114 | f->fmt.vbi = fh->vbi_fmt; | ||
115 | return 0; | ||
116 | } | ||
117 | default: | ||
118 | DEB_D(("invalid format type '%d'.\n",f->type)); | ||
119 | return -EINVAL; | ||
120 | } | ||
121 | } | ||
122 | |||
123 | static int try_win(struct saa7146_dev *dev, struct v4l2_window *win) | ||
124 | { | ||
125 | struct saa7146_vv *vv = dev->vv_data; | ||
126 | enum v4l2_field field; | ||
127 | int maxw, maxh; | ||
128 | |||
129 | DEB_EE(("dev:%p\n",dev)); | ||
130 | |||
131 | if (NULL == vv->ov_fb.base) { | ||
132 | DEB_D(("no fb base set.\n")); | ||
133 | return -EINVAL; | ||
134 | } | ||
135 | if (NULL == vv->ov_fmt) { | ||
136 | DEB_D(("no fb fmt set.\n")); | ||
137 | return -EINVAL; | ||
138 | } | ||
139 | if (win->w.width < 48 || win->w.height < 32) { | ||
140 | DEB_D(("min width/height. (%d,%d)\n",win->w.width,win->w.height)); | ||
141 | return -EINVAL; | ||
142 | } | ||
143 | if (win->clipcount > 16) { | ||
144 | DEB_D(("clipcount too big.\n")); | ||
145 | return -EINVAL; | ||
146 | } | ||
147 | |||
148 | field = win->field; | ||
149 | maxw = vv->standard->h_max_out; | ||
150 | maxh = vv->standard->v_max_out; | ||
151 | |||
152 | if (V4L2_FIELD_ANY == field) { | ||
153 | field = (win->w.height > maxh/2) | ||
154 | ? V4L2_FIELD_INTERLACED | ||
155 | : V4L2_FIELD_TOP; | ||
156 | } | ||
157 | switch (field) { | ||
158 | case V4L2_FIELD_TOP: | ||
159 | case V4L2_FIELD_BOTTOM: | ||
160 | case V4L2_FIELD_ALTERNATE: | ||
161 | maxh = maxh / 2; | ||
162 | break; | ||
163 | case V4L2_FIELD_INTERLACED: | ||
164 | break; | ||
165 | default: { | ||
166 | DEB_D(("no known field mode '%d'.\n",field)); | ||
167 | return -EINVAL; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | win->field = field; | ||
172 | if (win->w.width > maxw) | ||
173 | win->w.width = maxw; | ||
174 | if (win->w.height > maxh) | ||
175 | win->w.height = maxh; | ||
176 | |||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | static int try_fmt(struct saa7146_fh *fh, struct v4l2_format *f) | ||
181 | { | ||
182 | struct saa7146_dev *dev = fh->dev; | ||
183 | struct saa7146_vv *vv = dev->vv_data; | ||
184 | int err; | ||
185 | |||
186 | switch (f->type) { | ||
187 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
188 | { | ||
189 | struct saa7146_format *fmt; | ||
190 | enum v4l2_field field; | ||
191 | int maxw, maxh; | ||
192 | int calc_bpl; | ||
193 | |||
194 | DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh)); | ||
195 | |||
196 | fmt = format_by_fourcc(dev,f->fmt.pix.pixelformat); | ||
197 | if (NULL == fmt) { | ||
198 | return -EINVAL; | ||
199 | } | ||
200 | |||
201 | field = f->fmt.pix.field; | ||
202 | maxw = vv->standard->h_max_out; | ||
203 | maxh = vv->standard->v_max_out; | ||
204 | |||
205 | if (V4L2_FIELD_ANY == field) { | ||
206 | field = (f->fmt.pix.height > maxh/2) | ||
207 | ? V4L2_FIELD_INTERLACED | ||
208 | : V4L2_FIELD_BOTTOM; | ||
209 | } | ||
210 | switch (field) { | ||
211 | case V4L2_FIELD_ALTERNATE: { | ||
212 | vv->last_field = V4L2_FIELD_TOP; | ||
213 | maxh = maxh / 2; | ||
214 | break; | ||
215 | } | ||
216 | case V4L2_FIELD_TOP: | ||
217 | case V4L2_FIELD_BOTTOM: | ||
218 | vv->last_field = V4L2_FIELD_INTERLACED; | ||
219 | maxh = maxh / 2; | ||
220 | break; | ||
221 | case V4L2_FIELD_INTERLACED: | ||
222 | vv->last_field = V4L2_FIELD_INTERLACED; | ||
223 | break; | ||
224 | default: { | ||
225 | DEB_D(("no known field mode '%d'.\n",field)); | ||
226 | return -EINVAL; | ||
227 | } | ||
228 | } | ||
229 | |||
230 | f->fmt.pix.field = field; | ||
231 | if (f->fmt.pix.width > maxw) | ||
232 | f->fmt.pix.width = maxw; | ||
233 | if (f->fmt.pix.height > maxh) | ||
234 | f->fmt.pix.height = maxh; | ||
235 | |||
236 | calc_bpl = (f->fmt.pix.width * fmt->depth)/8; | ||
237 | |||
238 | if (f->fmt.pix.bytesperline < calc_bpl) | ||
239 | f->fmt.pix.bytesperline = calc_bpl; | ||
240 | |||
241 | if (f->fmt.pix.bytesperline > (2*PAGE_SIZE * fmt->depth)/8) /* arbitrary constraint */ | ||
242 | f->fmt.pix.bytesperline = calc_bpl; | ||
243 | |||
244 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; | ||
245 | DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n",f->fmt.pix.width,f->fmt.pix.height,f->fmt.pix.bytesperline,f->fmt.pix.sizeimage)); | ||
246 | |||
247 | return 0; | ||
248 | } | ||
249 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
250 | DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n",dev,fh)); | ||
251 | err = try_win(dev,&f->fmt.win); | ||
252 | if (0 != err) { | ||
253 | return err; | ||
254 | } | ||
255 | return 0; | ||
256 | default: | ||
257 | DEB_EE(("unknown format type '%d'\n",f->type)); | ||
258 | return -EINVAL; | ||
259 | } | ||
260 | } | ||
261 | 101 | ||
262 | int saa7146_start_preview(struct saa7146_fh *fh) | 102 | int saa7146_start_preview(struct saa7146_fh *fh) |
263 | { | 103 | { |
264 | struct saa7146_dev *dev = fh->dev; | 104 | struct saa7146_dev *dev = fh->dev; |
265 | struct saa7146_vv *vv = dev->vv_data; | 105 | struct saa7146_vv *vv = dev->vv_data; |
106 | struct v4l2_format fmt; | ||
266 | int ret = 0, err = 0; | 107 | int ret = 0, err = 0; |
267 | 108 | ||
268 | DEB_EE(("dev:%p, fh:%p\n",dev,fh)); | 109 | DEB_EE(("dev:%p, fh:%p\n",dev,fh)); |
@@ -294,12 +135,13 @@ int saa7146_start_preview(struct saa7146_fh *fh) | |||
294 | return -EBUSY; | 135 | return -EBUSY; |
295 | } | 136 | } |
296 | 137 | ||
297 | err = try_win(dev,&fh->ov.win); | 138 | fmt.fmt.win = fh->ov.win; |
139 | err = vidioc_try_fmt_vid_overlay(NULL, fh, &fmt); | ||
298 | if (0 != err) { | 140 | if (0 != err) { |
299 | saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP); | 141 | saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP); |
300 | return -EBUSY; | 142 | return -EBUSY; |
301 | } | 143 | } |
302 | 144 | fh->ov.win = fmt.fmt.win; | |
303 | vv->ov_data = &fh->ov; | 145 | vv->ov_data = &fh->ov; |
304 | 146 | ||
305 | DEB_D(("%dx%d+%d+%d %s field=%s\n", | 147 | DEB_D(("%dx%d+%d+%d %s field=%s\n", |
@@ -355,58 +197,6 @@ int saa7146_stop_preview(struct saa7146_fh *fh) | |||
355 | } | 197 | } |
356 | EXPORT_SYMBOL_GPL(saa7146_stop_preview); | 198 | EXPORT_SYMBOL_GPL(saa7146_stop_preview); |
357 | 199 | ||
358 | static int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f) | ||
359 | { | ||
360 | struct saa7146_dev *dev = fh->dev; | ||
361 | struct saa7146_vv *vv = dev->vv_data; | ||
362 | |||
363 | int err; | ||
364 | |||
365 | switch (f->type) { | ||
366 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
367 | DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh)); | ||
368 | if (IS_CAPTURE_ACTIVE(fh) != 0) { | ||
369 | DEB_EE(("streaming capture is active\n")); | ||
370 | return -EBUSY; | ||
371 | } | ||
372 | err = try_fmt(fh,f); | ||
373 | if (0 != err) | ||
374 | return err; | ||
375 | fh->video_fmt = f->fmt.pix; | ||
376 | DEB_EE(("set to pixelformat '%4.4s'\n",(char *)&fh->video_fmt.pixelformat)); | ||
377 | return 0; | ||
378 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
379 | DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n",dev,fh)); | ||
380 | err = try_win(dev,&f->fmt.win); | ||
381 | if (0 != err) | ||
382 | return err; | ||
383 | mutex_lock(&dev->lock); | ||
384 | fh->ov.win = f->fmt.win; | ||
385 | fh->ov.nclips = f->fmt.win.clipcount; | ||
386 | if (fh->ov.nclips > 16) | ||
387 | fh->ov.nclips = 16; | ||
388 | if (copy_from_user(fh->ov.clips,f->fmt.win.clips,sizeof(struct v4l2_clip)*fh->ov.nclips)) { | ||
389 | mutex_unlock(&dev->lock); | ||
390 | return -EFAULT; | ||
391 | } | ||
392 | |||
393 | /* fh->ov.fh is used to indicate that we have valid overlay informations, too */ | ||
394 | fh->ov.fh = fh; | ||
395 | |||
396 | mutex_unlock(&dev->lock); | ||
397 | |||
398 | /* check if our current overlay is active */ | ||
399 | if (IS_OVERLAY_ACTIVE(fh) != 0) { | ||
400 | saa7146_stop_preview(fh); | ||
401 | saa7146_start_preview(fh); | ||
402 | } | ||
403 | return 0; | ||
404 | default: | ||
405 | DEB_D(("unknown format type '%d'\n",f->type)); | ||
406 | return -EINVAL; | ||
407 | } | ||
408 | } | ||
409 | |||
410 | /********************************************************************************/ | 200 | /********************************************************************************/ |
411 | /* device controls */ | 201 | /* device controls */ |
412 | 202 | ||
@@ -463,132 +253,6 @@ static struct v4l2_queryctrl* ctrl_by_id(int id) | |||
463 | return NULL; | 253 | return NULL; |
464 | } | 254 | } |
465 | 255 | ||
466 | static int get_control(struct saa7146_fh *fh, struct v4l2_control *c) | ||
467 | { | ||
468 | struct saa7146_dev *dev = fh->dev; | ||
469 | struct saa7146_vv *vv = dev->vv_data; | ||
470 | |||
471 | const struct v4l2_queryctrl* ctrl; | ||
472 | u32 value = 0; | ||
473 | |||
474 | ctrl = ctrl_by_id(c->id); | ||
475 | if (NULL == ctrl) | ||
476 | return -EINVAL; | ||
477 | switch (c->id) { | ||
478 | case V4L2_CID_BRIGHTNESS: | ||
479 | value = saa7146_read(dev, BCS_CTRL); | ||
480 | c->value = 0xff & (value >> 24); | ||
481 | DEB_D(("V4L2_CID_BRIGHTNESS: %d\n",c->value)); | ||
482 | break; | ||
483 | case V4L2_CID_CONTRAST: | ||
484 | value = saa7146_read(dev, BCS_CTRL); | ||
485 | c->value = 0x7f & (value >> 16); | ||
486 | DEB_D(("V4L2_CID_CONTRAST: %d\n",c->value)); | ||
487 | break; | ||
488 | case V4L2_CID_SATURATION: | ||
489 | value = saa7146_read(dev, BCS_CTRL); | ||
490 | c->value = 0x7f & (value >> 0); | ||
491 | DEB_D(("V4L2_CID_SATURATION: %d\n",c->value)); | ||
492 | break; | ||
493 | case V4L2_CID_VFLIP: | ||
494 | c->value = vv->vflip; | ||
495 | DEB_D(("V4L2_CID_VFLIP: %d\n",c->value)); | ||
496 | break; | ||
497 | case V4L2_CID_HFLIP: | ||
498 | c->value = vv->hflip; | ||
499 | DEB_D(("V4L2_CID_HFLIP: %d\n",c->value)); | ||
500 | break; | ||
501 | default: | ||
502 | return -EINVAL; | ||
503 | } | ||
504 | |||
505 | return 0; | ||
506 | } | ||
507 | |||
508 | static int set_control(struct saa7146_fh *fh, struct v4l2_control *c) | ||
509 | { | ||
510 | struct saa7146_dev *dev = fh->dev; | ||
511 | struct saa7146_vv *vv = dev->vv_data; | ||
512 | |||
513 | const struct v4l2_queryctrl* ctrl; | ||
514 | |||
515 | ctrl = ctrl_by_id(c->id); | ||
516 | if (NULL == ctrl) { | ||
517 | DEB_D(("unknown control %d\n",c->id)); | ||
518 | return -EINVAL; | ||
519 | } | ||
520 | |||
521 | mutex_lock(&dev->lock); | ||
522 | |||
523 | switch (ctrl->type) { | ||
524 | case V4L2_CTRL_TYPE_BOOLEAN: | ||
525 | case V4L2_CTRL_TYPE_MENU: | ||
526 | case V4L2_CTRL_TYPE_INTEGER: | ||
527 | if (c->value < ctrl->minimum) | ||
528 | c->value = ctrl->minimum; | ||
529 | if (c->value > ctrl->maximum) | ||
530 | c->value = ctrl->maximum; | ||
531 | break; | ||
532 | default: | ||
533 | /* nothing */; | ||
534 | }; | ||
535 | |||
536 | switch (c->id) { | ||
537 | case V4L2_CID_BRIGHTNESS: { | ||
538 | u32 value = saa7146_read(dev, BCS_CTRL); | ||
539 | value &= 0x00ffffff; | ||
540 | value |= (c->value << 24); | ||
541 | saa7146_write(dev, BCS_CTRL, value); | ||
542 | saa7146_write(dev, MC2, MASK_22 | MASK_06 ); | ||
543 | break; | ||
544 | } | ||
545 | case V4L2_CID_CONTRAST: { | ||
546 | u32 value = saa7146_read(dev, BCS_CTRL); | ||
547 | value &= 0xff00ffff; | ||
548 | value |= (c->value << 16); | ||
549 | saa7146_write(dev, BCS_CTRL, value); | ||
550 | saa7146_write(dev, MC2, MASK_22 | MASK_06 ); | ||
551 | break; | ||
552 | } | ||
553 | case V4L2_CID_SATURATION: { | ||
554 | u32 value = saa7146_read(dev, BCS_CTRL); | ||
555 | value &= 0xffffff00; | ||
556 | value |= (c->value << 0); | ||
557 | saa7146_write(dev, BCS_CTRL, value); | ||
558 | saa7146_write(dev, MC2, MASK_22 | MASK_06 ); | ||
559 | break; | ||
560 | } | ||
561 | case V4L2_CID_HFLIP: | ||
562 | /* fixme: we can support changing VFLIP and HFLIP here... */ | ||
563 | if (IS_CAPTURE_ACTIVE(fh) != 0) { | ||
564 | DEB_D(("V4L2_CID_HFLIP while active capture.\n")); | ||
565 | mutex_unlock(&dev->lock); | ||
566 | return -EINVAL; | ||
567 | } | ||
568 | vv->hflip = c->value; | ||
569 | break; | ||
570 | case V4L2_CID_VFLIP: | ||
571 | if (IS_CAPTURE_ACTIVE(fh) != 0) { | ||
572 | DEB_D(("V4L2_CID_VFLIP while active capture.\n")); | ||
573 | mutex_unlock(&dev->lock); | ||
574 | return -EINVAL; | ||
575 | } | ||
576 | vv->vflip = c->value; | ||
577 | break; | ||
578 | default: { | ||
579 | mutex_unlock(&dev->lock); | ||
580 | return -EINVAL; | ||
581 | } | ||
582 | } | ||
583 | mutex_unlock(&dev->lock); | ||
584 | |||
585 | if (IS_OVERLAY_ACTIVE(fh) != 0) { | ||
586 | saa7146_stop_preview(fh); | ||
587 | saa7146_start_preview(fh); | ||
588 | } | ||
589 | return 0; | ||
590 | } | ||
591 | |||
592 | /********************************************************************************/ | 256 | /********************************************************************************/ |
593 | /* common pagetable functions */ | 257 | /* common pagetable functions */ |
594 | 258 | ||
@@ -829,231 +493,451 @@ static int video_end(struct saa7146_fh *fh, struct file *file) | |||
829 | return 0; | 493 | return 0; |
830 | } | 494 | } |
831 | 495 | ||
832 | /* | 496 | static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) |
833 | * This function is _not_ called directly, but from | 497 | { |
834 | * video_generic_ioctl (and maybe others). userspace | 498 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; |
835 | * copying is done already, arg is a kernel pointer. | 499 | |
836 | */ | 500 | strcpy((char *)cap->driver, "saa7146 v4l2"); |
501 | strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card)); | ||
502 | sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci)); | ||
503 | cap->version = SAA7146_VERSION_CODE; | ||
504 | cap->capabilities = | ||
505 | V4L2_CAP_VIDEO_CAPTURE | | ||
506 | V4L2_CAP_VIDEO_OVERLAY | | ||
507 | V4L2_CAP_READWRITE | | ||
508 | V4L2_CAP_STREAMING; | ||
509 | cap->capabilities |= dev->ext_vv_data->capabilities; | ||
510 | return 0; | ||
511 | } | ||
837 | 512 | ||
838 | long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 513 | static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) |
839 | { | 514 | { |
840 | struct saa7146_fh *fh = file->private_data; | 515 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; |
841 | struct saa7146_dev *dev = fh->dev; | ||
842 | struct saa7146_vv *vv = dev->vv_data; | 516 | struct saa7146_vv *vv = dev->vv_data; |
843 | 517 | ||
844 | long err = 0; | 518 | *fb = vv->ov_fb; |
845 | int result = 0, ee = 0; | 519 | fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; |
520 | return 0; | ||
521 | } | ||
522 | |||
523 | static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) | ||
524 | { | ||
525 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
526 | struct saa7146_vv *vv = dev->vv_data; | ||
527 | struct saa7146_format *fmt; | ||
846 | 528 | ||
847 | struct saa7146_use_ops *ops; | 529 | DEB_EE(("VIDIOC_S_FBUF\n")); |
848 | struct videobuf_queue *q; | ||
849 | 530 | ||
850 | /* check if extension handles the command */ | 531 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO)) |
851 | for(ee = 0; dev->ext_vv_data->ioctls[ee].flags != 0; ee++) { | 532 | return -EPERM; |
852 | if( cmd == dev->ext_vv_data->ioctls[ee].cmd ) | 533 | |
853 | break; | 534 | /* check args */ |
535 | fmt = format_by_fourcc(dev, fb->fmt.pixelformat); | ||
536 | if (NULL == fmt) | ||
537 | return -EINVAL; | ||
538 | |||
539 | /* planar formats are not allowed for overlay video, clipping and video dma would clash */ | ||
540 | if (fmt->flags & FORMAT_IS_PLANAR) | ||
541 | DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n", | ||
542 | (char *)&fmt->pixelformat)); | ||
543 | |||
544 | /* check if overlay is running */ | ||
545 | if (IS_OVERLAY_ACTIVE(fh) != 0) { | ||
546 | if (vv->video_fh != fh) { | ||
547 | DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n")); | ||
548 | return -EBUSY; | ||
549 | } | ||
854 | } | 550 | } |
855 | 551 | ||
856 | if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_EXCLUSIVE) ) { | 552 | mutex_lock(&dev->lock); |
857 | DEB_D(("extension handles ioctl exclusive.\n")); | 553 | |
858 | result = dev->ext_vv_data->ioctl(fh, cmd, arg); | 554 | /* ok, accept it */ |
859 | return result; | 555 | vv->ov_fb = *fb; |
556 | vv->ov_fmt = fmt; | ||
557 | if (0 == vv->ov_fb.fmt.bytesperline) | ||
558 | vv->ov_fb.fmt.bytesperline = | ||
559 | vv->ov_fb.fmt.width * fmt->depth / 8; | ||
560 | |||
561 | mutex_unlock(&dev->lock); | ||
562 | return 0; | ||
563 | } | ||
564 | |||
565 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f) | ||
566 | { | ||
567 | if (f->index >= NUM_FORMATS) | ||
568 | return -EINVAL; | ||
569 | strlcpy((char *)f->description, formats[f->index].name, | ||
570 | sizeof(f->description)); | ||
571 | f->pixelformat = formats[f->index].pixelformat; | ||
572 | return 0; | ||
573 | } | ||
574 | |||
575 | static int vidioc_enum_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_fmtdesc *f) | ||
576 | { | ||
577 | return vidioc_enum_fmt_vid_cap(file, fh, f); | ||
578 | } | ||
579 | |||
580 | static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c) | ||
581 | { | ||
582 | const struct v4l2_queryctrl *ctrl; | ||
583 | |||
584 | if ((c->id < V4L2_CID_BASE || | ||
585 | c->id >= V4L2_CID_LASTP1) && | ||
586 | (c->id < V4L2_CID_PRIVATE_BASE || | ||
587 | c->id >= V4L2_CID_PRIVATE_LASTP1)) | ||
588 | return -EINVAL; | ||
589 | |||
590 | ctrl = ctrl_by_id(c->id); | ||
591 | if (ctrl == NULL) | ||
592 | return -EINVAL; | ||
593 | |||
594 | DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n", c->id)); | ||
595 | *c = *ctrl; | ||
596 | return 0; | ||
597 | } | ||
598 | |||
599 | static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c) | ||
600 | { | ||
601 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
602 | struct saa7146_vv *vv = dev->vv_data; | ||
603 | const struct v4l2_queryctrl *ctrl; | ||
604 | u32 value = 0; | ||
605 | |||
606 | ctrl = ctrl_by_id(c->id); | ||
607 | if (NULL == ctrl) | ||
608 | return -EINVAL; | ||
609 | switch (c->id) { | ||
610 | case V4L2_CID_BRIGHTNESS: | ||
611 | value = saa7146_read(dev, BCS_CTRL); | ||
612 | c->value = 0xff & (value >> 24); | ||
613 | DEB_D(("V4L2_CID_BRIGHTNESS: %d\n", c->value)); | ||
614 | break; | ||
615 | case V4L2_CID_CONTRAST: | ||
616 | value = saa7146_read(dev, BCS_CTRL); | ||
617 | c->value = 0x7f & (value >> 16); | ||
618 | DEB_D(("V4L2_CID_CONTRAST: %d\n", c->value)); | ||
619 | break; | ||
620 | case V4L2_CID_SATURATION: | ||
621 | value = saa7146_read(dev, BCS_CTRL); | ||
622 | c->value = 0x7f & (value >> 0); | ||
623 | DEB_D(("V4L2_CID_SATURATION: %d\n", c->value)); | ||
624 | break; | ||
625 | case V4L2_CID_VFLIP: | ||
626 | c->value = vv->vflip; | ||
627 | DEB_D(("V4L2_CID_VFLIP: %d\n", c->value)); | ||
628 | break; | ||
629 | case V4L2_CID_HFLIP: | ||
630 | c->value = vv->hflip; | ||
631 | DEB_D(("V4L2_CID_HFLIP: %d\n", c->value)); | ||
632 | break; | ||
633 | default: | ||
634 | return -EINVAL; | ||
860 | } | 635 | } |
861 | if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_BEFORE) ) { | 636 | return 0; |
862 | DEB_D(("extension handles ioctl before.\n")); | 637 | } |
863 | result = dev->ext_vv_data->ioctl(fh, cmd, arg); | 638 | |
864 | if( -EAGAIN != result ) { | 639 | static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) |
865 | return result; | 640 | { |
866 | } | 641 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; |
642 | struct saa7146_vv *vv = dev->vv_data; | ||
643 | const struct v4l2_queryctrl *ctrl; | ||
644 | |||
645 | ctrl = ctrl_by_id(c->id); | ||
646 | if (NULL == ctrl) { | ||
647 | DEB_D(("unknown control %d\n", c->id)); | ||
648 | return -EINVAL; | ||
867 | } | 649 | } |
868 | 650 | ||
869 | /* fixme: add handle "after" case (is it still needed?) */ | 651 | mutex_lock(&dev->lock); |
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 | } | ||
870 | 665 | ||
871 | switch (fh->type) { | 666 | switch (c->id) { |
872 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: { | 667 | case V4L2_CID_BRIGHTNESS: { |
873 | ops = &saa7146_video_uops; | 668 | u32 value = saa7146_read(dev, BCS_CTRL); |
874 | q = &fh->video_q; | 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); | ||
875 | break; | 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 | mutex_unlock(&dev->lock); | ||
696 | return -EINVAL; | ||
876 | } | 697 | } |
877 | case V4L2_BUF_TYPE_VBI_CAPTURE: { | 698 | vv->hflip = c->value; |
878 | ops = &saa7146_vbi_uops; | ||
879 | q = &fh->vbi_q; | ||
880 | break; | 699 | break; |
700 | case V4L2_CID_VFLIP: | ||
701 | if (IS_CAPTURE_ACTIVE(fh) != 0) { | ||
702 | DEB_D(("V4L2_CID_VFLIP while active capture.\n")); | ||
703 | mutex_unlock(&dev->lock); | ||
704 | return -EINVAL; | ||
881 | } | 705 | } |
706 | vv->vflip = c->value; | ||
707 | break; | ||
882 | default: | 708 | default: |
883 | BUG(); | 709 | mutex_unlock(&dev->lock); |
884 | return 0; | 710 | return -EINVAL; |
885 | } | 711 | } |
712 | mutex_unlock(&dev->lock); | ||
886 | 713 | ||
887 | switch (cmd) { | 714 | if (IS_OVERLAY_ACTIVE(fh) != 0) { |
888 | case VIDIOC_QUERYCAP: | 715 | saa7146_stop_preview(fh); |
889 | { | 716 | saa7146_start_preview(fh); |
890 | struct v4l2_capability *cap = arg; | ||
891 | memset(cap,0,sizeof(*cap)); | ||
892 | |||
893 | DEB_EE(("VIDIOC_QUERYCAP\n")); | ||
894 | |||
895 | strcpy((char *)cap->driver, "saa7146 v4l2"); | ||
896 | strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card)); | ||
897 | sprintf((char *)cap->bus_info,"PCI:%s", pci_name(dev->pci)); | ||
898 | cap->version = SAA7146_VERSION_CODE; | ||
899 | cap->capabilities = | ||
900 | V4L2_CAP_VIDEO_CAPTURE | | ||
901 | V4L2_CAP_VIDEO_OVERLAY | | ||
902 | V4L2_CAP_READWRITE | | ||
903 | V4L2_CAP_STREAMING; | ||
904 | cap->capabilities |= dev->ext_vv_data->capabilities; | ||
905 | return 0; | ||
906 | } | 717 | } |
907 | case VIDIOC_G_FBUF: | 718 | return 0; |
908 | { | 719 | } |
909 | struct v4l2_framebuffer *fb = arg; | ||
910 | 720 | ||
911 | DEB_EE(("VIDIOC_G_FBUF\n")); | 721 | static int vidioc_g_parm(struct file *file, void *fh, |
722 | struct v4l2_streamparm *parm) | ||
723 | { | ||
724 | if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
725 | return -EINVAL; | ||
726 | parm->parm.capture.readbuffers = 1; | ||
727 | /* fixme: only for PAL! */ | ||
728 | parm->parm.capture.timeperframe.numerator = 1; | ||
729 | parm->parm.capture.timeperframe.denominator = 25; | ||
730 | return 0; | ||
731 | } | ||
912 | 732 | ||
913 | *fb = vv->ov_fb; | 733 | static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) |
914 | fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; | 734 | { |
915 | return 0; | 735 | f->fmt.pix = ((struct saa7146_fh *)fh)->video_fmt; |
916 | } | 736 | return 0; |
917 | case VIDIOC_S_FBUF: | 737 | } |
918 | { | ||
919 | struct v4l2_framebuffer *fb = arg; | ||
920 | struct saa7146_format *fmt; | ||
921 | 738 | ||
922 | DEB_EE(("VIDIOC_S_FBUF\n")); | 739 | static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f) |
740 | { | ||
741 | f->fmt.win = ((struct saa7146_fh *)fh)->ov.win; | ||
742 | return 0; | ||
743 | } | ||
923 | 744 | ||
924 | if(!capable(CAP_SYS_ADMIN) && | 745 | static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f) |
925 | !capable(CAP_SYS_RAWIO)) | 746 | { |
926 | return -EPERM; | 747 | f->fmt.vbi = ((struct saa7146_fh *)fh)->vbi_fmt; |
748 | return 0; | ||
749 | } | ||
927 | 750 | ||
928 | /* check args */ | 751 | static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) |
929 | fmt = format_by_fourcc(dev,fb->fmt.pixelformat); | 752 | { |
930 | if (NULL == fmt) { | 753 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; |
931 | return -EINVAL; | 754 | struct saa7146_vv *vv = dev->vv_data; |
932 | } | 755 | struct saa7146_format *fmt; |
756 | enum v4l2_field field; | ||
757 | int maxw, maxh; | ||
758 | int calc_bpl; | ||
933 | 759 | ||
934 | /* planar formats are not allowed for overlay video, clipping and video dma would clash */ | 760 | DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh)); |
935 | if (0 != (fmt->flags & FORMAT_IS_PLANAR)) { | ||
936 | DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n",(char *)&fmt->pixelformat)); | ||
937 | } | ||
938 | 761 | ||
939 | /* check if overlay is running */ | 762 | fmt = format_by_fourcc(dev, f->fmt.pix.pixelformat); |
940 | if (IS_OVERLAY_ACTIVE(fh) != 0) { | 763 | if (NULL == fmt) |
941 | if (vv->video_fh != fh) { | 764 | return -EINVAL; |
942 | DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n")); | ||
943 | return -EBUSY; | ||
944 | } | ||
945 | } | ||
946 | 765 | ||
947 | mutex_lock(&dev->lock); | 766 | field = f->fmt.pix.field; |
767 | maxw = vv->standard->h_max_out; | ||
768 | maxh = vv->standard->v_max_out; | ||
948 | 769 | ||
949 | /* ok, accept it */ | 770 | if (V4L2_FIELD_ANY == field) { |
950 | vv->ov_fb = *fb; | 771 | field = (f->fmt.pix.height > maxh / 2) |
951 | vv->ov_fmt = fmt; | 772 | ? V4L2_FIELD_INTERLACED |
952 | if (0 == vv->ov_fb.fmt.bytesperline) | 773 | : V4L2_FIELD_BOTTOM; |
953 | vv->ov_fb.fmt.bytesperline = | 774 | } |
954 | vv->ov_fb.fmt.width*fmt->depth/8; | 775 | switch (field) { |
776 | case V4L2_FIELD_ALTERNATE: | ||
777 | vv->last_field = V4L2_FIELD_TOP; | ||
778 | maxh = maxh / 2; | ||
779 | break; | ||
780 | case V4L2_FIELD_TOP: | ||
781 | case V4L2_FIELD_BOTTOM: | ||
782 | vv->last_field = V4L2_FIELD_INTERLACED; | ||
783 | maxh = maxh / 2; | ||
784 | break; | ||
785 | case V4L2_FIELD_INTERLACED: | ||
786 | vv->last_field = V4L2_FIELD_INTERLACED; | ||
787 | break; | ||
788 | default: | ||
789 | DEB_D(("no known field mode '%d'.\n", field)); | ||
790 | return -EINVAL; | ||
791 | } | ||
955 | 792 | ||
956 | mutex_unlock(&dev->lock); | 793 | f->fmt.pix.field = field; |
794 | if (f->fmt.pix.width > maxw) | ||
795 | f->fmt.pix.width = maxw; | ||
796 | if (f->fmt.pix.height > maxh) | ||
797 | f->fmt.pix.height = maxh; | ||
957 | 798 | ||
958 | return 0; | 799 | calc_bpl = (f->fmt.pix.width * fmt->depth) / 8; |
959 | } | ||
960 | case VIDIOC_ENUM_FMT: | ||
961 | { | ||
962 | struct v4l2_fmtdesc *f = arg; | ||
963 | |||
964 | switch (f->type) { | ||
965 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
966 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
967 | if (f->index >= NUM_FORMATS) | ||
968 | return -EINVAL; | ||
969 | strlcpy((char *)f->description, formats[f->index].name, | ||
970 | sizeof(f->description)); | ||
971 | f->pixelformat = formats[f->index].pixelformat; | ||
972 | f->flags = 0; | ||
973 | memset(f->reserved, 0, sizeof(f->reserved)); | ||
974 | break; | ||
975 | default: | ||
976 | return -EINVAL; | ||
977 | } | ||
978 | 800 | ||
979 | DEB_EE(("VIDIOC_ENUM_FMT: type:%d, index:%d\n",f->type,f->index)); | 801 | if (f->fmt.pix.bytesperline < calc_bpl) |
980 | return 0; | 802 | f->fmt.pix.bytesperline = calc_bpl; |
981 | } | ||
982 | case VIDIOC_QUERYCTRL: | ||
983 | { | ||
984 | const struct v4l2_queryctrl *ctrl; | ||
985 | struct v4l2_queryctrl *c = arg; | ||
986 | 803 | ||
987 | if ((c->id < V4L2_CID_BASE || | 804 | if (f->fmt.pix.bytesperline > (2 * PAGE_SIZE * fmt->depth) / 8) /* arbitrary constraint */ |
988 | c->id >= V4L2_CID_LASTP1) && | 805 | f->fmt.pix.bytesperline = calc_bpl; |
989 | (c->id < V4L2_CID_PRIVATE_BASE || | ||
990 | c->id >= V4L2_CID_PRIVATE_LASTP1)) | ||
991 | return -EINVAL; | ||
992 | 806 | ||
993 | ctrl = ctrl_by_id(c->id); | 807 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; |
994 | if( NULL == ctrl ) { | 808 | DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n", f->fmt.pix.width, |
995 | return -EINVAL; | 809 | f->fmt.pix.height, f->fmt.pix.bytesperline, f->fmt.pix.sizeimage)); |
996 | /* | ||
997 | c->flags = V4L2_CTRL_FLAG_DISABLED; | ||
998 | return 0; | ||
999 | */ | ||
1000 | } | ||
1001 | 810 | ||
1002 | DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n",c->id)); | 811 | return 0; |
1003 | *c = *ctrl; | 812 | } |
1004 | return 0; | 813 | |
814 | |||
815 | static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f) | ||
816 | { | ||
817 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
818 | struct saa7146_vv *vv = dev->vv_data; | ||
819 | struct v4l2_window *win = &f->fmt.win; | ||
820 | enum v4l2_field field; | ||
821 | int maxw, maxh; | ||
822 | |||
823 | DEB_EE(("dev:%p\n", dev)); | ||
824 | |||
825 | if (NULL == vv->ov_fb.base) { | ||
826 | DEB_D(("no fb base set.\n")); | ||
827 | return -EINVAL; | ||
1005 | } | 828 | } |
1006 | case VIDIOC_G_CTRL: { | 829 | if (NULL == vv->ov_fmt) { |
1007 | DEB_EE(("VIDIOC_G_CTRL\n")); | 830 | DEB_D(("no fb fmt set.\n")); |
1008 | return get_control(fh,arg); | 831 | return -EINVAL; |
1009 | } | 832 | } |
1010 | case VIDIOC_S_CTRL: | 833 | if (win->w.width < 48 || win->w.height < 32) { |
1011 | { | 834 | DEB_D(("min width/height. (%d,%d)\n", win->w.width, win->w.height)); |
1012 | DEB_EE(("VIDIOC_S_CTRL\n")); | 835 | return -EINVAL; |
1013 | err = set_control(fh,arg); | ||
1014 | return err; | ||
1015 | } | 836 | } |
1016 | case VIDIOC_G_PARM: | 837 | if (win->clipcount > 16) { |
1017 | { | 838 | DEB_D(("clipcount too big.\n")); |
1018 | struct v4l2_streamparm *parm = arg; | 839 | return -EINVAL; |
1019 | if( parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ) { | ||
1020 | return -EINVAL; | ||
1021 | } | ||
1022 | memset(&parm->parm.capture,0,sizeof(struct v4l2_captureparm)); | ||
1023 | parm->parm.capture.readbuffers = 1; | ||
1024 | // fixme: only for PAL! | ||
1025 | parm->parm.capture.timeperframe.numerator = 1; | ||
1026 | parm->parm.capture.timeperframe.denominator = 25; | ||
1027 | return 0; | ||
1028 | } | 840 | } |
1029 | case VIDIOC_G_FMT: | 841 | |
1030 | { | 842 | field = win->field; |
1031 | struct v4l2_format *f = arg; | 843 | maxw = vv->standard->h_max_out; |
1032 | DEB_EE(("VIDIOC_G_FMT\n")); | 844 | maxh = vv->standard->v_max_out; |
1033 | return g_fmt(fh,f); | 845 | |
846 | if (V4L2_FIELD_ANY == field) { | ||
847 | field = (win->w.height > maxh / 2) | ||
848 | ? V4L2_FIELD_INTERLACED | ||
849 | : V4L2_FIELD_TOP; | ||
850 | } | ||
851 | switch (field) { | ||
852 | case V4L2_FIELD_TOP: | ||
853 | case V4L2_FIELD_BOTTOM: | ||
854 | case V4L2_FIELD_ALTERNATE: | ||
855 | maxh = maxh / 2; | ||
856 | break; | ||
857 | case V4L2_FIELD_INTERLACED: | ||
858 | break; | ||
859 | default: | ||
860 | DEB_D(("no known field mode '%d'.\n", field)); | ||
861 | return -EINVAL; | ||
1034 | } | 862 | } |
1035 | case VIDIOC_S_FMT: | 863 | |
1036 | { | 864 | win->field = field; |
1037 | struct v4l2_format *f = arg; | 865 | if (win->w.width > maxw) |
1038 | DEB_EE(("VIDIOC_S_FMT\n")); | 866 | win->w.width = maxw; |
1039 | return s_fmt(fh,f); | 867 | if (win->w.height > maxh) |
868 | win->w.height = maxh; | ||
869 | |||
870 | return 0; | ||
871 | } | ||
872 | |||
873 | static int vidioc_s_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_format *f) | ||
874 | { | ||
875 | struct saa7146_fh *fh = __fh; | ||
876 | struct saa7146_dev *dev = fh->dev; | ||
877 | struct saa7146_vv *vv = dev->vv_data; | ||
878 | int err; | ||
879 | |||
880 | DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh)); | ||
881 | if (IS_CAPTURE_ACTIVE(fh) != 0) { | ||
882 | DEB_EE(("streaming capture is active\n")); | ||
883 | return -EBUSY; | ||
1040 | } | 884 | } |
1041 | case VIDIOC_TRY_FMT: | 885 | err = vidioc_try_fmt_vid_cap(file, fh, f); |
1042 | { | 886 | if (0 != err) |
1043 | struct v4l2_format *f = arg; | 887 | return err; |
1044 | DEB_EE(("VIDIOC_TRY_FMT\n")); | 888 | fh->video_fmt = f->fmt.pix; |
1045 | return try_fmt(fh,f); | 889 | DEB_EE(("set to pixelformat '%4.4s'\n", (char *)&fh->video_fmt.pixelformat)); |
890 | return 0; | ||
891 | } | ||
892 | |||
893 | static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_format *f) | ||
894 | { | ||
895 | struct saa7146_fh *fh = __fh; | ||
896 | struct saa7146_dev *dev = fh->dev; | ||
897 | struct saa7146_vv *vv = dev->vv_data; | ||
898 | int err; | ||
899 | |||
900 | DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n", dev, fh)); | ||
901 | err = vidioc_try_fmt_vid_overlay(file, fh, f); | ||
902 | if (0 != err) | ||
903 | return err; | ||
904 | mutex_lock(&dev->lock); | ||
905 | fh->ov.win = f->fmt.win; | ||
906 | fh->ov.nclips = f->fmt.win.clipcount; | ||
907 | if (fh->ov.nclips > 16) | ||
908 | fh->ov.nclips = 16; | ||
909 | if (copy_from_user(fh->ov.clips, f->fmt.win.clips, | ||
910 | sizeof(struct v4l2_clip) * fh->ov.nclips)) { | ||
911 | mutex_unlock(&dev->lock); | ||
912 | return -EFAULT; | ||
1046 | } | 913 | } |
1047 | case VIDIOC_G_STD: | 914 | |
1048 | { | 915 | /* fh->ov.fh is used to indicate that we have valid overlay informations, too */ |
1049 | v4l2_std_id *id = arg; | 916 | fh->ov.fh = fh; |
1050 | DEB_EE(("VIDIOC_G_STD\n")); | 917 | |
1051 | *id = vv->standard->id; | 918 | mutex_unlock(&dev->lock); |
1052 | return 0; | 919 | |
920 | /* check if our current overlay is active */ | ||
921 | if (IS_OVERLAY_ACTIVE(fh) != 0) { | ||
922 | saa7146_stop_preview(fh); | ||
923 | saa7146_start_preview(fh); | ||
1053 | } | 924 | } |
925 | return 0; | ||
926 | } | ||
927 | |||
928 | static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm) | ||
929 | { | ||
930 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
931 | struct saa7146_vv *vv = dev->vv_data; | ||
932 | |||
933 | *norm = vv->standard->id; | ||
934 | return 0; | ||
935 | } | ||
936 | |||
1054 | /* the saa7146 supfhrts (used in conjunction with the saa7111a for example) | 937 | /* the saa7146 supfhrts (used in conjunction with the saa7111a for example) |
1055 | PAL / NTSC / SECAM. if your hardware does not (or does more) | 938 | PAL / NTSC / SECAM. if your hardware does not (or does more) |
1056 | -- override this function in your extension */ | 939 | -- override this function in your extension */ |
940 | /* | ||
1057 | case VIDIOC_ENUMSTD: | 941 | case VIDIOC_ENUMSTD: |
1058 | { | 942 | { |
1059 | struct v4l2_standard *e = arg; | 943 | struct v4l2_standard *e = arg; |
@@ -1066,162 +950,228 @@ long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1066 | } | 950 | } |
1067 | return -EINVAL; | 951 | return -EINVAL; |
1068 | } | 952 | } |
1069 | case VIDIOC_S_STD: | 953 | */ |
1070 | { | ||
1071 | v4l2_std_id *id = arg; | ||
1072 | int found = 0; | ||
1073 | int i; | ||
1074 | |||
1075 | DEB_EE(("VIDIOC_S_STD\n")); | ||
1076 | 954 | ||
1077 | if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) { | 955 | static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id) |
1078 | DEB_D(("cannot change video standard while streaming capture is active\n")); | 956 | { |
1079 | return -EBUSY; | 957 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; |
1080 | } | 958 | struct saa7146_vv *vv = dev->vv_data; |
959 | int found = 0; | ||
960 | int err, i; | ||
1081 | 961 | ||
1082 | if ((vv->video_status & STATUS_OVERLAY) != 0) { | 962 | DEB_EE(("VIDIOC_S_STD\n")); |
1083 | vv->ov_suspend = vv->video_fh; | ||
1084 | err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */ | ||
1085 | if (0 != err) { | ||
1086 | DEB_D(("suspending video failed. aborting\n")); | ||
1087 | return err; | ||
1088 | } | ||
1089 | } | ||
1090 | 963 | ||
1091 | mutex_lock(&dev->lock); | 964 | if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) { |
965 | DEB_D(("cannot change video standard while streaming capture is active\n")); | ||
966 | return -EBUSY; | ||
967 | } | ||
1092 | 968 | ||
1093 | for(i = 0; i < dev->ext_vv_data->num_stds; i++) | 969 | if ((vv->video_status & STATUS_OVERLAY) != 0) { |
1094 | if (*id & dev->ext_vv_data->stds[i].id) | 970 | vv->ov_suspend = vv->video_fh; |
1095 | break; | 971 | err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */ |
1096 | if (i != dev->ext_vv_data->num_stds) { | 972 | if (0 != err) { |
1097 | vv->standard = &dev->ext_vv_data->stds[i]; | 973 | DEB_D(("suspending video failed. aborting\n")); |
1098 | if( NULL != dev->ext_vv_data->std_callback ) | 974 | return err; |
1099 | dev->ext_vv_data->std_callback(dev, vv->standard); | ||
1100 | found = 1; | ||
1101 | } | 975 | } |
976 | } | ||
1102 | 977 | ||
1103 | mutex_unlock(&dev->lock); | 978 | mutex_lock(&dev->lock); |
1104 | 979 | ||
1105 | if (vv->ov_suspend != NULL) { | 980 | for (i = 0; i < dev->ext_vv_data->num_stds; i++) |
1106 | saa7146_start_preview(vv->ov_suspend); | 981 | if (*id & dev->ext_vv_data->stds[i].id) |
1107 | vv->ov_suspend = NULL; | 982 | break; |
1108 | } | 983 | if (i != dev->ext_vv_data->num_stds) { |
984 | vv->standard = &dev->ext_vv_data->stds[i]; | ||
985 | if (NULL != dev->ext_vv_data->std_callback) | ||
986 | dev->ext_vv_data->std_callback(dev, vv->standard); | ||
987 | found = 1; | ||
988 | } | ||
1109 | 989 | ||
1110 | if( 0 == found ) { | 990 | mutex_unlock(&dev->lock); |
1111 | DEB_EE(("VIDIOC_S_STD: standard not found.\n")); | ||
1112 | return -EINVAL; | ||
1113 | } | ||
1114 | 991 | ||
1115 | DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n",vv->standard->name)); | 992 | if (vv->ov_suspend != NULL) { |
1116 | return 0; | 993 | saa7146_start_preview(vv->ov_suspend); |
994 | vv->ov_suspend = NULL; | ||
1117 | } | 995 | } |
1118 | case VIDIOC_OVERLAY: | ||
1119 | { | ||
1120 | int on = *(int *)arg; | ||
1121 | 996 | ||
1122 | DEB_D(("VIDIOC_OVERLAY on:%d\n",on)); | 997 | if (!found) { |
1123 | if (on != 0) { | 998 | DEB_EE(("VIDIOC_S_STD: standard not found.\n")); |
1124 | err = saa7146_start_preview(fh); | 999 | return -EINVAL; |
1125 | } else { | ||
1126 | err = saa7146_stop_preview(fh); | ||
1127 | } | ||
1128 | return err; | ||
1129 | } | ||
1130 | case VIDIOC_REQBUFS: { | ||
1131 | struct v4l2_requestbuffers *req = arg; | ||
1132 | DEB_D(("VIDIOC_REQBUFS, type:%d\n",req->type)); | ||
1133 | return videobuf_reqbufs(q,req); | ||
1134 | } | ||
1135 | case VIDIOC_QUERYBUF: { | ||
1136 | struct v4l2_buffer *buf = arg; | ||
1137 | DEB_D(("VIDIOC_QUERYBUF, type:%d, offset:%d\n",buf->type,buf->m.offset)); | ||
1138 | return videobuf_querybuf(q,buf); | ||
1139 | } | ||
1140 | case VIDIOC_QBUF: { | ||
1141 | struct v4l2_buffer *buf = arg; | ||
1142 | int ret = 0; | ||
1143 | ret = videobuf_qbuf(q,buf); | ||
1144 | DEB_D(("VIDIOC_QBUF: ret:%d, index:%d\n",ret,buf->index)); | ||
1145 | return ret; | ||
1146 | } | ||
1147 | case VIDIOC_DQBUF: { | ||
1148 | struct v4l2_buffer *buf = arg; | ||
1149 | int ret = 0; | ||
1150 | ret = videobuf_dqbuf(q,buf,file->f_flags & O_NONBLOCK); | ||
1151 | DEB_D(("VIDIOC_DQBUF: ret:%d, index:%d\n",ret,buf->index)); | ||
1152 | return ret; | ||
1153 | } | 1000 | } |
1154 | case VIDIOC_STREAMON: { | ||
1155 | int *type = arg; | ||
1156 | DEB_D(("VIDIOC_STREAMON, type:%d\n",*type)); | ||
1157 | 1001 | ||
1158 | err = video_begin(fh); | 1002 | DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n", vv->standard->name)); |
1159 | if( 0 != err) { | 1003 | return 0; |
1160 | return err; | 1004 | } |
1161 | } | ||
1162 | err = videobuf_streamon(q); | ||
1163 | return err; | ||
1164 | } | ||
1165 | case VIDIOC_STREAMOFF: { | ||
1166 | int *type = arg; | ||
1167 | 1005 | ||
1168 | DEB_D(("VIDIOC_STREAMOFF, type:%d\n",*type)); | 1006 | static int vidioc_overlay(struct file *file, void *fh, unsigned int on) |
1007 | { | ||
1008 | int err; | ||
1169 | 1009 | ||
1170 | /* ugly: we need to copy some checks from video_end(), | 1010 | DEB_D(("VIDIOC_OVERLAY on:%d\n", on)); |
1171 | because videobuf_streamoff() relies on the capture running. | 1011 | if (on) |
1172 | check and fix this */ | 1012 | err = saa7146_start_preview(fh); |
1173 | if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) { | 1013 | else |
1174 | DEB_S(("not capturing.\n")); | 1014 | err = saa7146_stop_preview(fh); |
1175 | return 0; | 1015 | return err; |
1176 | } | 1016 | } |
1177 | 1017 | ||
1178 | if (vv->video_fh != fh) { | 1018 | static int vidioc_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *b) |
1179 | DEB_S(("capturing, but in another open.\n")); | 1019 | { |
1180 | return -EBUSY; | 1020 | struct saa7146_fh *fh = __fh; |
1181 | } | ||
1182 | 1021 | ||
1183 | err = videobuf_streamoff(q); | 1022 | if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1184 | if (0 != err) { | 1023 | return videobuf_reqbufs(&fh->video_q, b); |
1185 | DEB_D(("warning: videobuf_streamoff() failed.\n")); | 1024 | if (b->type == V4L2_BUF_TYPE_VBI_CAPTURE) |
1186 | video_end(fh, file); | 1025 | return videobuf_reqbufs(&fh->vbi_q, b); |
1187 | } else { | 1026 | return -EINVAL; |
1188 | err = video_end(fh, file); | 1027 | } |
1189 | } | 1028 | |
1190 | return err; | 1029 | static int vidioc_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf) |
1191 | } | 1030 | { |
1192 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 1031 | struct saa7146_fh *fh = __fh; |
1193 | case VIDIOCGMBUF: | ||
1194 | { | ||
1195 | struct video_mbuf *mbuf = arg; | ||
1196 | int i; | ||
1197 | 1032 | ||
1198 | /* fixme: number of capture buffers and sizes for v4l apps */ | 1033 | if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1199 | int gbuffers = 2; | 1034 | return videobuf_querybuf(&fh->video_q, buf); |
1200 | int gbufsize = 768*576*4; | 1035 | if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE) |
1036 | return videobuf_querybuf(&fh->vbi_q, buf); | ||
1037 | return -EINVAL; | ||
1038 | } | ||
1201 | 1039 | ||
1202 | DEB_D(("VIDIOCGMBUF \n")); | 1040 | static int vidioc_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) |
1041 | { | ||
1042 | struct saa7146_fh *fh = __fh; | ||
1203 | 1043 | ||
1204 | q = &fh->video_q; | 1044 | if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1205 | err = videobuf_mmap_setup(q,gbuffers,gbufsize, | 1045 | return videobuf_qbuf(&fh->video_q, buf); |
1206 | V4L2_MEMORY_MMAP); | 1046 | if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE) |
1207 | if (err < 0) | 1047 | return videobuf_qbuf(&fh->vbi_q, buf); |
1208 | return err; | 1048 | return -EINVAL; |
1049 | } | ||
1050 | |||
1051 | static int vidioc_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) | ||
1052 | { | ||
1053 | struct saa7146_fh *fh = __fh; | ||
1054 | |||
1055 | if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1056 | return videobuf_dqbuf(&fh->video_q, buf, file->f_flags & O_NONBLOCK); | ||
1057 | if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE) | ||
1058 | return videobuf_dqbuf(&fh->vbi_q, buf, file->f_flags & O_NONBLOCK); | ||
1059 | return -EINVAL; | ||
1060 | } | ||
1061 | |||
1062 | static int vidioc_streamon(struct file *file, void *__fh, enum v4l2_buf_type type) | ||
1063 | { | ||
1064 | struct saa7146_fh *fh = __fh; | ||
1065 | int err; | ||
1066 | |||
1067 | DEB_D(("VIDIOC_STREAMON, type:%d\n", type)); | ||
1068 | |||
1069 | err = video_begin(fh); | ||
1070 | if (err) | ||
1071 | return err; | ||
1072 | if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1073 | return videobuf_streamon(&fh->video_q); | ||
1074 | if (type == V4L2_BUF_TYPE_VBI_CAPTURE) | ||
1075 | return videobuf_streamon(&fh->vbi_q); | ||
1076 | return -EINVAL; | ||
1077 | } | ||
1078 | |||
1079 | static int vidioc_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type) | ||
1080 | { | ||
1081 | struct saa7146_fh *fh = __fh; | ||
1082 | struct saa7146_dev *dev = fh->dev; | ||
1083 | struct saa7146_vv *vv = dev->vv_data; | ||
1084 | int err; | ||
1085 | |||
1086 | DEB_D(("VIDIOC_STREAMOFF, type:%d\n", type)); | ||
1209 | 1087 | ||
1210 | gbuffers = err; | 1088 | /* ugly: we need to copy some checks from video_end(), |
1211 | memset(mbuf,0,sizeof(*mbuf)); | 1089 | because videobuf_streamoff() relies on the capture running. |
1212 | mbuf->frames = gbuffers; | 1090 | check and fix this */ |
1213 | mbuf->size = gbuffers * gbufsize; | 1091 | if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) { |
1214 | for (i = 0; i < gbuffers; i++) | 1092 | DEB_S(("not capturing.\n")); |
1215 | mbuf->offsets[i] = i * gbufsize; | ||
1216 | return 0; | 1093 | return 0; |
1217 | } | 1094 | } |
1218 | #endif | 1095 | |
1219 | default: | 1096 | if (vv->video_fh != fh) { |
1220 | return v4l_compat_translate_ioctl(file, cmd, arg, | 1097 | DEB_S(("capturing, but in another open.\n")); |
1221 | saa7146_video_do_ioctl); | 1098 | return -EBUSY; |
1222 | } | 1099 | } |
1100 | |||
1101 | err = -EINVAL; | ||
1102 | if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1103 | err = videobuf_streamoff(&fh->video_q); | ||
1104 | else if (type == V4L2_BUF_TYPE_VBI_CAPTURE) | ||
1105 | err = videobuf_streamoff(&fh->vbi_q); | ||
1106 | if (0 != err) { | ||
1107 | DEB_D(("warning: videobuf_streamoff() failed.\n")); | ||
1108 | video_end(fh, file); | ||
1109 | } else { | ||
1110 | err = video_end(fh, file); | ||
1111 | } | ||
1112 | return err; | ||
1113 | } | ||
1114 | |||
1115 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1116 | static int vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *mbuf) | ||
1117 | { | ||
1118 | struct saa7146_fh *fh = __fh; | ||
1119 | struct videobuf_queue *q = &fh->video_q; | ||
1120 | int err, i; | ||
1121 | |||
1122 | /* fixme: number of capture buffers and sizes for v4l apps */ | ||
1123 | int gbuffers = 2; | ||
1124 | int gbufsize = 768 * 576 * 4; | ||
1125 | |||
1126 | DEB_D(("VIDIOCGMBUF \n")); | ||
1127 | |||
1128 | q = &fh->video_q; | ||
1129 | err = videobuf_mmap_setup(q, gbuffers, gbufsize, | ||
1130 | V4L2_MEMORY_MMAP); | ||
1131 | if (err < 0) | ||
1132 | return err; | ||
1133 | |||
1134 | gbuffers = err; | ||
1135 | memset(mbuf, 0, sizeof(*mbuf)); | ||
1136 | mbuf->frames = gbuffers; | ||
1137 | mbuf->size = gbuffers * gbufsize; | ||
1138 | for (i = 0; i < gbuffers; i++) | ||
1139 | mbuf->offsets[i] = i * gbufsize; | ||
1223 | return 0; | 1140 | return 0; |
1224 | } | 1141 | } |
1142 | #endif | ||
1143 | |||
1144 | const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = { | ||
1145 | .vidioc_querycap = vidioc_querycap, | ||
1146 | .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, | ||
1147 | .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_overlay, | ||
1148 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, | ||
1149 | .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, | ||
1150 | .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, | ||
1151 | .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay, | ||
1152 | .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay, | ||
1153 | .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay, | ||
1154 | .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, | ||
1155 | |||
1156 | .vidioc_overlay = vidioc_overlay, | ||
1157 | .vidioc_g_fbuf = vidioc_g_fbuf, | ||
1158 | .vidioc_s_fbuf = vidioc_s_fbuf, | ||
1159 | .vidioc_reqbufs = vidioc_reqbufs, | ||
1160 | .vidioc_querybuf = vidioc_querybuf, | ||
1161 | .vidioc_qbuf = vidioc_qbuf, | ||
1162 | .vidioc_dqbuf = vidioc_dqbuf, | ||
1163 | .vidioc_g_std = vidioc_g_std, | ||
1164 | .vidioc_s_std = vidioc_s_std, | ||
1165 | .vidioc_queryctrl = vidioc_queryctrl, | ||
1166 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
1167 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
1168 | .vidioc_streamon = vidioc_streamon, | ||
1169 | .vidioc_streamoff = vidioc_streamoff, | ||
1170 | .vidioc_g_parm = vidioc_g_parm, | ||
1171 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1172 | .vidiocgmbuf = vidiocgmbuf, | ||
1173 | #endif | ||
1174 | }; | ||
1225 | 1175 | ||
1226 | /*********************************************************************************/ | 1176 | /*********************************************************************************/ |
1227 | /* buffer handling functions */ | 1177 | /* buffer handling functions */ |