aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2009-01-18 17:59:11 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:42:24 -0400
commitb960074fec573fb1b226d9e2686ce51be807cdf1 (patch)
treeda58b7afa37b0ccd1c06948ad6497cb801553335 /drivers/media
parentc9b8b04b267f9a7e472daa06cdf6d4963d503d1f (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')
-rw-r--r--drivers/media/common/saa7146_fops.c36
-rw-r--r--drivers/media/common/saa7146_video.c1250
-rw-r--r--drivers/media/dvb/ttpci/av7110_v4l.c479
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c88
-rw-r--r--drivers/media/video/hexium_gemini.c292
-rw-r--r--drivers/media/video/hexium_orion.c103
-rw-r--r--drivers/media/video/mxb.c641
7 files changed, 1395 insertions, 1494 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
311static 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
319static int fops_mmap(struct file *file, struct vm_area_struct * vma) 311static 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
431static void vv_callback(struct saa7146_dev *dev, unsigned long status) 423static 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
455static struct video_device device_template =
456{
457 .fops = &video_fops,
458 .minor = -1,
459};
460
461int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) 447int 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
100static int g_fmt(struct saa7146_fh *fh, struct v4l2_format *f) 100static 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
123static 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
180static 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
262int saa7146_start_preview(struct saa7146_fh *fh) 102int 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}
356EXPORT_SYMBOL_GPL(saa7146_stop_preview); 198EXPORT_SYMBOL_GPL(saa7146_stop_preview);
357 199
358static 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
466static 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
508static 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/* 496static 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
838long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) 513static 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
523static 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
565static 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
575static 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
580static 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
599static 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 ) { 639static 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")); 721static 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; 733static 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")); 739static 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) && 745static 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 */ 751static 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
815static 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
873static 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
893static 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
928static 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) { 955static 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)); 1006static 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) { 1018static 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; 1029static 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")); 1040static 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
1051static 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
1062static 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
1079static 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
1116static 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
1144const 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 */
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index c5b9c70563dc..04334058f8f8 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -316,253 +316,260 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh)
316 return 0; 316 return 0;
317} 317}
318 318
319static long av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) 319static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
320{ 320{
321 struct saa7146_dev *dev = fh->dev; 321 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
322 struct av7110 *av7110 = (struct av7110*) dev->ext_priv; 322 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
323 dprintk(4, "saa7146_dev: %p\n", dev); 323 u16 stereo_det;
324 s8 stereo;
324 325
325 switch (cmd) { 326 dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);
326 case VIDIOC_G_TUNER:
327 {
328 struct v4l2_tuner *t = arg;
329 u16 stereo_det;
330 s8 stereo;
331 327
332 dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index); 328 if (!av7110->analog_tuner_flags || t->index != 0)
329 return -EINVAL;
333 330
334 if (!av7110->analog_tuner_flags || t->index != 0) 331 memset(t, 0, sizeof(*t));
335 return -EINVAL; 332 strcpy((char *)t->name, "Television");
333
334 t->type = V4L2_TUNER_ANALOG_TV;
335 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
336 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
337 t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
338 t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
339 /* FIXME: add the real signal strength here */
340 t->signal = 0xffff;
341 t->afc = 0;
342
343 /* FIXME: standard / stereo detection is still broken */
344 msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
345 dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
346 msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
347 dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
348 stereo = (s8)(stereo_det >> 8);
349 if (stereo > 0x10) {
350 /* stereo */
351 t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
352 t->audmode = V4L2_TUNER_MODE_STEREO;
353 } else if (stereo < -0x10) {
354 /* bilingual */
355 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
356 t->audmode = V4L2_TUNER_MODE_LANG1;
357 } else /* mono */
358 t->rxsubchans = V4L2_TUNER_SUB_MONO;
336 359
337 memset(t, 0, sizeof(*t)); 360 return 0;
338 strcpy((char *)t->name, "Television"); 361}
339
340 t->type = V4L2_TUNER_ANALOG_TV;
341 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
342 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
343 t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
344 t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
345 /* FIXME: add the real signal strength here */
346 t->signal = 0xffff;
347 t->afc = 0;
348
349 // FIXME: standard / stereo detection is still broken
350 msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
351 dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
352 msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
353 dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
354 stereo = (s8)(stereo_det >> 8);
355 if (stereo > 0x10) {
356 /* stereo */
357 t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
358 t->audmode = V4L2_TUNER_MODE_STEREO;
359 }
360 else if (stereo < -0x10) {
361 /* bilingual */
362 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
363 t->audmode = V4L2_TUNER_MODE_LANG1;
364 }
365 else /* mono */
366 t->rxsubchans = V4L2_TUNER_SUB_MONO;
367 362
368 return 0; 363static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
369 } 364{
370 case VIDIOC_S_TUNER: 365 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
371 { 366 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
372 struct v4l2_tuner *t = arg; 367 u16 fm_matrix, src;
373 u16 fm_matrix, src; 368 dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
374 dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
375 369
376 if (!av7110->analog_tuner_flags || av7110->current_input != 1) 370 if (!av7110->analog_tuner_flags || av7110->current_input != 1)
377 return -EINVAL; 371 return -EINVAL;
378 372
379 switch (t->audmode) { 373 switch (t->audmode) {
380 case V4L2_TUNER_MODE_STEREO: 374 case V4L2_TUNER_MODE_STEREO:
381 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"); 375 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n");
382 fm_matrix = 0x3001; // stereo 376 fm_matrix = 0x3001; /* stereo */
383 src = 0x0020; 377 src = 0x0020;
384 break; 378 break;
385 case V4L2_TUNER_MODE_LANG1_LANG2: 379 case V4L2_TUNER_MODE_LANG1_LANG2:
386 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n"); 380 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n");
387 fm_matrix = 0x3000; // bilingual 381 fm_matrix = 0x3000; /* bilingual */
388 src = 0x0020; 382 src = 0x0020;
389 break; 383 break;
390 case V4L2_TUNER_MODE_LANG1: 384 case V4L2_TUNER_MODE_LANG1:
391 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"); 385 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");
392 fm_matrix = 0x3000; // mono 386 fm_matrix = 0x3000; /* mono */
393 src = 0x0000; 387 src = 0x0000;
394 break; 388 break;
395 case V4L2_TUNER_MODE_LANG2: 389 case V4L2_TUNER_MODE_LANG2:
396 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"); 390 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n");
397 fm_matrix = 0x3000; // mono 391 fm_matrix = 0x3000; /* mono */
398 src = 0x0010; 392 src = 0x0010;
399 break; 393 break;
400 default: /* case V4L2_TUNER_MODE_MONO: */ 394 default: /* case V4L2_TUNER_MODE_MONO: */
401 dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n"); 395 dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
402 fm_matrix = 0x3000; // mono 396 fm_matrix = 0x3000; /* mono */
403 src = 0x0030; 397 src = 0x0030;
404 break; 398 break;
405 }
406 msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);
407 msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);
408 msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);
409 msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);
410 return 0;
411 } 399 }
412 case VIDIOC_G_FREQUENCY: 400 msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);
413 { 401 msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);
414 struct v4l2_frequency *f = arg; 402 msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);
403 msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);
404 return 0;
405}
406
407static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
408{
409 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
410 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
415 411
416 dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency); 412 dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency);
417 413
418 if (!av7110->analog_tuner_flags || av7110->current_input != 1) 414 if (!av7110->analog_tuner_flags || av7110->current_input != 1)
419 return -EINVAL; 415 return -EINVAL;
420 416
421 memset(f, 0, sizeof(*f)); 417 memset(f, 0, sizeof(*f));
422 f->type = V4L2_TUNER_ANALOG_TV; 418 f->type = V4L2_TUNER_ANALOG_TV;
423 f->frequency = av7110->current_freq; 419 f->frequency = av7110->current_freq;
424 return 0; 420 return 0;
425 } 421}
426 case VIDIOC_S_FREQUENCY:
427 {
428 struct v4l2_frequency *f = arg;
429 422
430 dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency); 423static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
424{
425 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
426 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
431 427
432 if (!av7110->analog_tuner_flags || av7110->current_input != 1) 428 dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency);
433 return -EINVAL;
434 429
435 if (V4L2_TUNER_ANALOG_TV != f->type) 430 if (!av7110->analog_tuner_flags || av7110->current_input != 1)
436 return -EINVAL; 431 return -EINVAL;
437 432
438 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); // fast mute 433 if (V4L2_TUNER_ANALOG_TV != f->type)
439 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0); 434 return -EINVAL;
440 435
441 /* tune in desired frequency */ 436 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); /* fast mute */
442 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) { 437 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
443 ves1820_set_tv_freq(dev, f->frequency);
444 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
445 stv0297_set_tv_freq(dev, f->frequency);
446 }
447 av7110->current_freq = f->frequency;
448 438
449 msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); // start stereo detection 439 /* tune in desired frequency */
450 msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000); 440 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820)
451 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone 441 ves1820_set_tv_freq(dev, f->frequency);
452 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume 442 else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297)
453 return 0; 443 stv0297_set_tv_freq(dev, f->frequency);
454 } 444 av7110->current_freq = f->frequency;
455 case VIDIOC_ENUMINPUT:
456 {
457 struct v4l2_input *i = arg;
458 445
459 dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index); 446 msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); /* start stereo detection */
447 msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000);
448 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); /* loudspeaker + headphone */
449 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); /* SCART 1 volume */
450 return 0;
451}
460 452
461 if (av7110->analog_tuner_flags) { 453static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
462 if (i->index < 0 || i->index >= 4) 454{
463 return -EINVAL; 455 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
464 } else { 456 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
465 if (i->index != 0)
466 return -EINVAL;
467 }
468 457
469 memcpy(i, &inputs[i->index], sizeof(struct v4l2_input)); 458 dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
470 459
471 return 0; 460 if (av7110->analog_tuner_flags) {
461 if (i->index < 0 || i->index >= 4)
462 return -EINVAL;
463 } else {
464 if (i->index != 0)
465 return -EINVAL;
472 } 466 }
473 case VIDIOC_G_INPUT: 467
474 { 468 memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
475 int *input = (int *)arg; 469
476 *input = av7110->current_input; 470 return 0;
477 dprintk(2, "VIDIOC_G_INPUT: %d\n", *input); 471}
472
473static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
474{
475 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
476 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
477
478 *input = av7110->current_input;
479 dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);
480 return 0;
481}
482
483static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
484{
485 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
486 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
487
488 dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
489
490 if (!av7110->analog_tuner_flags)
478 return 0; 491 return 0;
479 }
480 case VIDIOC_S_INPUT:
481 {
482 int input = *(int *)arg;
483 492
484 dprintk(2, "VIDIOC_S_INPUT: %d\n", input); 493 if (input < 0 || input >= 4)
494 return -EINVAL;
485 495
486 if (!av7110->analog_tuner_flags) 496 av7110->current_input = input;
487 return 0; 497 return av7110_dvb_c_switch(fh);
498}
488 499
489 if (input < 0 || input >= 4) 500static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
490 return -EINVAL; 501{
502 dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
503 if (a->index != 0)
504 return -EINVAL;
505 memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio));
506 return 0;
507}
491 508
492 av7110->current_input = input; 509static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
493 return av7110_dvb_c_switch(fh); 510{
494 } 511 dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
495 case VIDIOC_G_AUDIO: 512 return 0;
496 { 513}
497 struct v4l2_audio *a = arg;
498 514
499 dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index); 515static int vidioc_g_sliced_vbi_cap(struct file *file, void *fh,
500 if (a->index != 0) 516 struct v4l2_sliced_vbi_cap *cap)
501 return -EINVAL; 517{
502 memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio)); 518 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
503 break; 519 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
504 } 520
505 case VIDIOC_S_AUDIO: 521 dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n");
506 { 522 memset(cap, 0, sizeof(*cap));
507 struct v4l2_audio *a = arg; 523 if (FW_VERSION(av7110->arm_app) >= 0x2623) {
508 dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index); 524 cap->service_set = V4L2_SLICED_WSS_625;
509 break; 525 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
510 }
511 case VIDIOC_G_SLICED_VBI_CAP:
512 {
513 struct v4l2_sliced_vbi_cap *cap = arg;
514 dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n");
515 memset(cap, 0, sizeof *cap);
516 if (FW_VERSION(av7110->arm_app) >= 0x2623) {
517 cap->service_set = V4L2_SLICED_WSS_625;
518 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
519 }
520 break;
521 }
522 case VIDIOC_G_FMT:
523 {
524 struct v4l2_format *f = arg;
525 dprintk(2, "VIDIOC_G_FMT:\n");
526 if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ||
527 FW_VERSION(av7110->arm_app) < 0x2623)
528 return -EAGAIN; /* handled by core driver */
529 memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
530 if (av7110->wssMode) {
531 f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
532 f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
533 f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data);
534 }
535 break;
536 } 526 }
537 case VIDIOC_S_FMT: 527 return 0;
538 { 528}
539 struct v4l2_format *f = arg; 529
540 dprintk(2, "VIDIOC_S_FMT\n"); 530static int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh,
541 if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT || 531 struct v4l2_format *f)
542 FW_VERSION(av7110->arm_app) < 0x2623) 532{
543 return -EAGAIN; /* handled by core driver */ 533 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
544 if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 && 534 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
545 f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) { 535
546 memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced); 536 dprintk(2, "VIDIOC_G_FMT:\n");
547 /* WSS controlled by firmware */ 537 if (FW_VERSION(av7110->arm_app) < 0x2623)
548 av7110->wssMode = 0; 538 return -EINVAL;
549 av7110->wssData = 0; 539 memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
550 return av7110_fw_cmd(av7110, COMTYPE_ENCODER, 540 if (av7110->wssMode) {
551 SetWSSConfig, 1, 0); 541 f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
552 } else { 542 f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
553 memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced); 543 f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data);
554 f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
555 f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
556 f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data);
557 /* WSS controlled by userspace */
558 av7110->wssMode = 1;
559 av7110->wssData = 0;
560 }
561 break;
562 } 544 }
563 default: 545 return 0;
564 printk("no such ioctl\n"); 546}
565 return -ENOIOCTLCMD; 547
548static int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh,
549 struct v4l2_format *f)
550{
551 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
552 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
553
554 dprintk(2, "VIDIOC_S_FMT\n");
555 if (FW_VERSION(av7110->arm_app) < 0x2623)
556 return -EINVAL;
557 if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 &&
558 f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) {
559 memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced));
560 /* WSS controlled by firmware */
561 av7110->wssMode = 0;
562 av7110->wssData = 0;
563 return av7110_fw_cmd(av7110, COMTYPE_ENCODER,
564 SetWSSConfig, 1, 0);
565 } else {
566 memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced));
567 f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
568 f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
569 f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data);
570 /* WSS controlled by userspace */
571 av7110->wssMode = 1;
572 av7110->wssData = 0;
566 } 573 }
567 return 0; 574 return 0;
568} 575}
@@ -609,22 +616,6 @@ static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size
609 * INITIALIZATION 616 * INITIALIZATION
610 ****************************************************************************/ 617 ****************************************************************************/
611 618
612static struct saa7146_extension_ioctls ioctls[] = {
613 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
614 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
615 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
616 { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE },
617 { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE },
618 { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE },
619 { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
620 { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
621 { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
622 { VIDIOC_G_SLICED_VBI_CAP, SAA7146_EXCLUSIVE },
623 { VIDIOC_G_FMT, SAA7146_BEFORE },
624 { VIDIOC_S_FMT, SAA7146_BEFORE },
625 { 0, 0 }
626};
627
628static u8 saa7113_init_regs[] = { 619static u8 saa7113_init_regs[] = {
629 0x02, 0xd0, 620 0x02, 0xd0,
630 0x03, 0x23, 621 0x03, 0x23,
@@ -788,20 +779,34 @@ int av7110_init_analog_module(struct av7110 *av7110)
788int av7110_init_v4l(struct av7110 *av7110) 779int av7110_init_v4l(struct av7110 *av7110)
789{ 780{
790 struct saa7146_dev* dev = av7110->dev; 781 struct saa7146_dev* dev = av7110->dev;
782 struct saa7146_ext_vv *vv_data;
791 int ret; 783 int ret;
792 784
793 /* special case DVB-C: these cards have an analog tuner 785 /* special case DVB-C: these cards have an analog tuner
794 plus need some special handling, so we have separate 786 plus need some special handling, so we have separate
795 saa7146_ext_vv data for these... */ 787 saa7146_ext_vv data for these... */
796 if (av7110->analog_tuner_flags) 788 if (av7110->analog_tuner_flags)
797 ret = saa7146_vv_init(dev, &av7110_vv_data_c); 789 vv_data = &av7110_vv_data_c;
798 else 790 else
799 ret = saa7146_vv_init(dev, &av7110_vv_data_st); 791 vv_data = &av7110_vv_data_st;
792 ret = saa7146_vv_init(dev, vv_data);
800 793
801 if (ret) { 794 if (ret) {
802 ERR(("cannot init capture device. skipping.\n")); 795 ERR(("cannot init capture device. skipping.\n"));
803 return -ENODEV; 796 return -ENODEV;
804 } 797 }
798 vv_data->ops.vidioc_enum_input = vidioc_enum_input;
799 vv_data->ops.vidioc_g_input = vidioc_g_input;
800 vv_data->ops.vidioc_s_input = vidioc_s_input;
801 vv_data->ops.vidioc_g_tuner = vidioc_g_tuner;
802 vv_data->ops.vidioc_s_tuner = vidioc_s_tuner;
803 vv_data->ops.vidioc_g_frequency = vidioc_g_frequency;
804 vv_data->ops.vidioc_s_frequency = vidioc_s_frequency;
805 vv_data->ops.vidioc_g_audio = vidioc_g_audio;
806 vv_data->ops.vidioc_s_audio = vidioc_s_audio;
807 vv_data->ops.vidioc_g_sliced_vbi_cap = vidioc_g_sliced_vbi_cap;
808 vv_data->ops.vidioc_g_fmt_sliced_vbi_out = vidioc_g_fmt_sliced_vbi_out;
809 vv_data->ops.vidioc_s_fmt_sliced_vbi_out = vidioc_s_fmt_sliced_vbi_out;
805 810
806 if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) { 811 if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) {
807 ERR(("cannot register capture device. skipping.\n")); 812 ERR(("cannot register capture device. skipping.\n"));
@@ -900,9 +905,6 @@ static struct saa7146_ext_vv av7110_vv_data_st = {
900 .num_stds = ARRAY_SIZE(standard), 905 .num_stds = ARRAY_SIZE(standard),
901 .std_callback = &std_callback, 906 .std_callback = &std_callback,
902 907
903 .ioctls = &ioctls[0],
904 .ioctl = av7110_ioctl,
905
906 .vbi_fops.open = av7110_vbi_reset, 908 .vbi_fops.open = av7110_vbi_reset,
907 .vbi_fops.release = av7110_vbi_reset, 909 .vbi_fops.release = av7110_vbi_reset,
908 .vbi_fops.write = av7110_vbi_write, 910 .vbi_fops.write = av7110_vbi_write,
@@ -918,9 +920,6 @@ static struct saa7146_ext_vv av7110_vv_data_c = {
918 .num_stds = ARRAY_SIZE(standard), 920 .num_stds = ARRAY_SIZE(standard),
919 .std_callback = &std_callback, 921 .std_callback = &std_callback,
920 922
921 .ioctls = &ioctls[0],
922 .ioctl = av7110_ioctl,
923
924 .vbi_fops.open = av7110_vbi_reset, 923 .vbi_fops.open = av7110_vbi_reset,
925 .vbi_fops.release = av7110_vbi_reset, 924 .vbi_fops.release = av7110_vbi_reset,
926 .vbi_fops.write = av7110_vbi_write, 925 .vbi_fops.write = av7110_vbi_write,
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 4182121d7e5d..855fe74b640b 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -1404,6 +1404,41 @@ static int budget_av_detach(struct saa7146_dev *dev)
1404 return err; 1404 return err;
1405} 1405}
1406 1406
1407#define KNC1_INPUTS 2
1408static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
1409 {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
1410 {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
1411};
1412
1413static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
1414{
1415 dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
1416 if (i->index < 0 || i->index >= KNC1_INPUTS)
1417 return -EINVAL;
1418 memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
1419 return 0;
1420}
1421
1422static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
1423{
1424 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
1425 struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
1426
1427 *i = budget_av->cur_input;
1428
1429 dprintk(1, "VIDIOC_G_INPUT %d.\n", *i);
1430 return 0;
1431}
1432
1433static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
1434{
1435 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
1436 struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
1437
1438 dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
1439 return saa7113_setinput(budget_av, input);
1440}
1441
1407static struct saa7146_ext_vv vv_data; 1442static struct saa7146_ext_vv vv_data;
1408 1443
1409static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) 1444static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
@@ -1442,6 +1477,9 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
1442 ERR(("cannot init vv subsystem.\n")); 1477 ERR(("cannot init vv subsystem.\n"));
1443 return err; 1478 return err;
1444 } 1479 }
1480 vv_data.ops.vidioc_enum_input = vidioc_enum_input;
1481 vv_data.ops.vidioc_g_input = vidioc_g_input;
1482 vv_data.ops.vidioc_s_input = vidioc_s_input;
1445 1483
1446 if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) { 1484 if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
1447 /* fixme: proper cleanup here */ 1485 /* fixme: proper cleanup here */
@@ -1480,54 +1518,6 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
1480 return 0; 1518 return 0;
1481} 1519}
1482 1520
1483#define KNC1_INPUTS 2
1484static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
1485 {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
1486 {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
1487};
1488
1489static struct saa7146_extension_ioctls ioctls[] = {
1490 {VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE},
1491 {VIDIOC_G_INPUT, SAA7146_EXCLUSIVE},
1492 {VIDIOC_S_INPUT, SAA7146_EXCLUSIVE},
1493 {0, 0}
1494};
1495
1496static long av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
1497{
1498 struct saa7146_dev *dev = fh->dev;
1499 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1500
1501 switch (cmd) {
1502 case VIDIOC_ENUMINPUT:{
1503 struct v4l2_input *i = arg;
1504
1505 dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
1506 if (i->index < 0 || i->index >= KNC1_INPUTS) {
1507 return -EINVAL;
1508 }
1509 memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
1510 return 0;
1511 }
1512 case VIDIOC_G_INPUT:{
1513 int *input = (int *) arg;
1514
1515 *input = budget_av->cur_input;
1516
1517 dprintk(1, "VIDIOC_G_INPUT %d.\n", *input);
1518 return 0;
1519 }
1520 case VIDIOC_S_INPUT:{
1521 int input = *(int *) arg;
1522 dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
1523 return saa7113_setinput(budget_av, input);
1524 }
1525 default:
1526 return -ENOIOCTLCMD;
1527 }
1528 return 0;
1529}
1530
1531static struct saa7146_standard standard[] = { 1521static struct saa7146_standard standard[] = {
1532 {.name = "PAL",.id = V4L2_STD_PAL, 1522 {.name = "PAL",.id = V4L2_STD_PAL,
1533 .v_offset = 0x17,.v_field = 288, 1523 .v_offset = 0x17,.v_field = 288,
@@ -1546,8 +1536,6 @@ static struct saa7146_ext_vv vv_data = {
1546 .flags = 0, 1536 .flags = 0,
1547 .stds = &standard[0], 1537 .stds = &standard[0],
1548 .num_stds = ARRAY_SIZE(standard), 1538 .num_stds = ARRAY_SIZE(standard),
1549 .ioctls = &ioctls[0],
1550 .ioctl = av_ioctl,
1551}; 1539};
1552 1540
1553static struct saa7146_extension budget_extension; 1541static struct saa7146_extension budget_extension;
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c
index 79393d1772e4..8e1463ee1b64 100644
--- a/drivers/media/video/hexium_gemini.c
+++ b/drivers/media/video/hexium_gemini.c
@@ -56,17 +56,6 @@ struct hexium_data
56 u8 byte; 56 u8 byte;
57}; 57};
58 58
59static struct saa7146_extension_ioctls ioctls[] = {
60 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
61 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
62 { VIDIOC_QUERYCTRL, SAA7146_BEFORE },
63 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
64 { VIDIOC_S_STD, SAA7146_AFTER },
65 { VIDIOC_G_CTRL, SAA7146_BEFORE },
66 { VIDIOC_S_CTRL, SAA7146_BEFORE },
67 { 0, 0 }
68};
69
70#define HEXIUM_CONTROLS 1 59#define HEXIUM_CONTROLS 1
71static struct v4l2_queryctrl hexium_controls[] = { 60static struct v4l2_queryctrl hexium_controls[] = {
72 { V4L2_CID_PRIVATE_BASE, V4L2_CTRL_TYPE_BOOLEAN, "B/W", 0, 1, 1, 0, 0 }, 61 { V4L2_CID_PRIVATE_BASE, V4L2_CTRL_TYPE_BOOLEAN, "B/W", 0, 1, 1, 0, 0 },
@@ -231,6 +220,132 @@ static int hexium_set_standard(struct hexium *hexium, struct hexium_data *vdec)
231 return 0; 220 return 0;
232} 221}
233 222
223static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
224{
225 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
226
227 if (i->index < 0 || i->index >= HEXIUM_INPUTS)
228 return -EINVAL;
229
230 memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
231
232 DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
233 return 0;
234}
235
236static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
237{
238 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
239 struct hexium *hexium = (struct hexium *) dev->ext_priv;
240
241 *input = hexium->cur_input;
242
243 DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
244 return 0;
245}
246
247static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
248{
249 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
250 struct hexium *hexium = (struct hexium *) dev->ext_priv;
251
252 DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
253
254 if (input < 0 || input >= HEXIUM_INPUTS)
255 return -EINVAL;
256
257 hexium->cur_input = input;
258 hexium_set_input(hexium, input);
259 return 0;
260}
261
262/* the saa7146 provides some controls (brightness, contrast, saturation)
263 which gets registered *after* this function. because of this we have
264 to return with a value != 0 even if the function succeded.. */
265static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
266{
267 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
268 int i;
269
270 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
271 if (hexium_controls[i].id == qc->id) {
272 *qc = hexium_controls[i];
273 DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
274 return 0;
275 }
276 }
277 return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
278}
279
280static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
281{
282 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
283 struct hexium *hexium = (struct hexium *) dev->ext_priv;
284 int i;
285
286 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
287 if (hexium_controls[i].id == vc->id)
288 break;
289 }
290
291 if (i < 0)
292 return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
293
294 if (vc->id == V4L2_CID_PRIVATE_BASE) {
295 vc->value = hexium->cur_bw;
296 DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value));
297 return 0;
298 }
299 return -EINVAL;
300}
301
302static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
303{
304 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
305 struct hexium *hexium = (struct hexium *) dev->ext_priv;
306 int i = 0;
307
308 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
309 if (hexium_controls[i].id == vc->id)
310 break;
311 }
312
313 if (i < 0)
314 return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
315
316 if (vc->id == V4L2_CID_PRIVATE_BASE)
317 hexium->cur_bw = vc->value;
318
319 DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw));
320
321 if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
322 hexium_set_standard(hexium, hexium_pal);
323 return 0;
324 }
325 if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
326 hexium_set_standard(hexium, hexium_ntsc);
327 return 0;
328 }
329 if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
330 hexium_set_standard(hexium, hexium_secam);
331 return 0;
332 }
333 if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
334 hexium_set_standard(hexium, hexium_pal_bw);
335 return 0;
336 }
337 if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
338 hexium_set_standard(hexium, hexium_ntsc_bw);
339 return 0;
340 }
341 if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std)
342 /* fixme: is there no bw secam mode? */
343 return -EINVAL;
344
345 return -EINVAL;
346}
347
348
234static struct saa7146_ext_vv vv_data; 349static struct saa7146_ext_vv vv_data;
235 350
236/* this function only gets called when the probing was successful */ 351/* this function only gets called when the probing was successful */
@@ -279,6 +394,12 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
279 hexium->cur_input = 0; 394 hexium->cur_input = 0;
280 395
281 saa7146_vv_init(dev, &vv_data); 396 saa7146_vv_init(dev, &vv_data);
397 vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
398 vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
399 vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
400 vv_data.ops.vidioc_enum_input = vidioc_enum_input;
401 vv_data.ops.vidioc_g_input = vidioc_g_input;
402 vv_data.ops.vidioc_s_input = vidioc_s_input;
282 if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER)) { 403 if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER)) {
283 printk("hexium_gemini: cannot register capture v4l2 device. skipping.\n"); 404 printk("hexium_gemini: cannot register capture v4l2 device. skipping.\n");
284 return -1; 405 return -1;
@@ -306,153 +427,6 @@ static int hexium_detach(struct saa7146_dev *dev)
306 return 0; 427 return 0;
307} 428}
308 429
309static long hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
310{
311 struct saa7146_dev *dev = fh->dev;
312 struct hexium *hexium = (struct hexium *) dev->ext_priv;
313/*
314 struct saa7146_vv *vv = dev->vv_data;
315*/
316 switch (cmd) {
317 case VIDIOC_ENUMINPUT:
318 {
319 struct v4l2_input *i = arg;
320 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
321
322 if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
323 return -EINVAL;
324 }
325
326 memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
327
328 DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
329 return 0;
330 }
331 case VIDIOC_G_INPUT:
332 {
333 int *input = (int *) arg;
334 *input = hexium->cur_input;
335
336 DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
337 return 0;
338 }
339 case VIDIOC_S_INPUT:
340 {
341 int input = *(int *) arg;
342
343 DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
344
345 if (input < 0 || input >= HEXIUM_INPUTS) {
346 return -EINVAL;
347 }
348
349 hexium->cur_input = input;
350 hexium_set_input(hexium, input);
351
352 return 0;
353 }
354 /* the saa7146 provides some controls (brightness, contrast, saturation)
355 which gets registered *after* this function. because of this we have
356 to return with a value != 0 even if the function succeded.. */
357 case VIDIOC_QUERYCTRL:
358 {
359 struct v4l2_queryctrl *qc = arg;
360 int i;
361
362 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
363 if (hexium_controls[i].id == qc->id) {
364 *qc = hexium_controls[i];
365 DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
366 return 0;
367 }
368 }
369 return -EAGAIN;
370 }
371 case VIDIOC_G_CTRL:
372 {
373 struct v4l2_control *vc = arg;
374 int i;
375
376 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
377 if (hexium_controls[i].id == vc->id) {
378 break;
379 }
380 }
381
382 if (i < 0) {
383 return -EAGAIN;
384 }
385
386 switch (vc->id) {
387 case V4L2_CID_PRIVATE_BASE:{
388 vc->value = hexium->cur_bw;
389 DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value));
390 return 0;
391 }
392 }
393 return -EINVAL;
394 }
395
396 case VIDIOC_S_CTRL:
397 {
398 struct v4l2_control *vc = arg;
399 int i = 0;
400
401 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
402 if (hexium_controls[i].id == vc->id) {
403 break;
404 }
405 }
406
407 if (i < 0) {
408 return -EAGAIN;
409 }
410
411 switch (vc->id) {
412 case V4L2_CID_PRIVATE_BASE:{
413 hexium->cur_bw = vc->value;
414 break;
415 }
416 }
417
418 DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw));
419
420 if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
421 hexium_set_standard(hexium, hexium_pal);
422 return 0;
423 }
424 if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
425 hexium_set_standard(hexium, hexium_ntsc);
426 return 0;
427 }
428 if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
429 hexium_set_standard(hexium, hexium_secam);
430 return 0;
431 }
432 if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
433 hexium_set_standard(hexium, hexium_pal_bw);
434 return 0;
435 }
436 if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
437 hexium_set_standard(hexium, hexium_ntsc_bw);
438 return 0;
439 }
440 if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
441 /* fixme: is there no bw secam mode? */
442 return -EINVAL;
443 }
444
445 return -EINVAL;
446 }
447 default:
448/*
449 DEB_D(("hexium_ioctl() does not handle this ioctl.\n"));
450*/
451 return -ENOIOCTLCMD;
452 }
453 return 0;
454}
455
456static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std) 430static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
457{ 431{
458 struct hexium *hexium = (struct hexium *) dev->ext_priv; 432 struct hexium *hexium = (struct hexium *) dev->ext_priv;
@@ -514,8 +488,6 @@ static struct saa7146_ext_vv vv_data = {
514 .stds = &hexium_standards[0], 488 .stds = &hexium_standards[0],
515 .num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard), 489 .num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
516 .std_callback = &std_callback, 490 .std_callback = &std_callback,
517 .ioctls = &ioctls[0],
518 .ioctl = hexium_ioctl,
519}; 491};
520 492
521static struct saa7146_extension hexium_extension = { 493static struct saa7146_extension hexium_extension = {
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c
index 074bec711fe0..2bc39f628455 100644
--- a/drivers/media/video/hexium_orion.c
+++ b/drivers/media/video/hexium_orion.c
@@ -57,14 +57,6 @@ struct hexium_data
57 u8 byte; 57 u8 byte;
58}; 58};
59 59
60static struct saa7146_extension_ioctls ioctls[] = {
61 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
62 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
63 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
64 { VIDIOC_S_STD, SAA7146_AFTER },
65 { 0, 0 }
66};
67
68struct hexium 60struct hexium
69{ 61{
70 int type; 62 int type;
@@ -329,6 +321,44 @@ static int hexium_set_input(struct hexium *hexium, int input)
329 return 0; 321 return 0;
330} 322}
331 323
324static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
325{
326 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
327
328 if (i->index < 0 || i->index >= HEXIUM_INPUTS)
329 return -EINVAL;
330
331 memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
332
333 DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
334 return 0;
335}
336
337static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
338{
339 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
340 struct hexium *hexium = (struct hexium *) dev->ext_priv;
341
342 *input = hexium->cur_input;
343
344 DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
345 return 0;
346}
347
348static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
349{
350 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
351 struct hexium *hexium = (struct hexium *) dev->ext_priv;
352
353 if (input < 0 || input >= HEXIUM_INPUTS)
354 return -EINVAL;
355
356 hexium->cur_input = input;
357 hexium_set_input(hexium, input);
358
359 return 0;
360}
361
332static struct saa7146_ext_vv vv_data; 362static struct saa7146_ext_vv vv_data;
333 363
334/* this function only gets called when the probing was successful */ 364/* this function only gets called when the probing was successful */
@@ -339,6 +369,9 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
339 DEB_EE((".\n")); 369 DEB_EE((".\n"));
340 370
341 saa7146_vv_init(dev, &vv_data); 371 saa7146_vv_init(dev, &vv_data);
372 vv_data.ops.vidioc_enum_input = vidioc_enum_input;
373 vv_data.ops.vidioc_g_input = vidioc_g_input;
374 vv_data.ops.vidioc_s_input = vidioc_s_input;
342 if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_GRABBER)) { 375 if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_GRABBER)) {
343 printk("hexium_orion: cannot register capture v4l2 device. skipping.\n"); 376 printk("hexium_orion: cannot register capture v4l2 device. skipping.\n");
344 return -1; 377 return -1;
@@ -370,58 +403,6 @@ static int hexium_detach(struct saa7146_dev *dev)
370 return 0; 403 return 0;
371} 404}
372 405
373static long hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
374{
375 struct saa7146_dev *dev = fh->dev;
376 struct hexium *hexium = (struct hexium *) dev->ext_priv;
377/*
378 struct saa7146_vv *vv = dev->vv_data;
379*/
380 switch (cmd) {
381 case VIDIOC_ENUMINPUT:
382 {
383 struct v4l2_input *i = arg;
384 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
385
386 if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
387 return -EINVAL;
388 }
389
390 memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
391
392 DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
393 return 0;
394 }
395 case VIDIOC_G_INPUT:
396 {
397 int *input = (int *) arg;
398 *input = hexium->cur_input;
399
400 DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
401 return 0;
402 }
403 case VIDIOC_S_INPUT:
404 {
405 int input = *(int *) arg;
406
407 if (input < 0 || input >= HEXIUM_INPUTS) {
408 return -EINVAL;
409 }
410
411 hexium->cur_input = input;
412 hexium_set_input(hexium, input);
413
414 return 0;
415 }
416 default:
417/*
418 DEB_D(("hexium_ioctl() does not handle this ioctl.\n"));
419*/
420 return -ENOIOCTLCMD;
421 }
422 return 0;
423}
424
425static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std) 406static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
426{ 407{
427 return 0; 408 return 0;
@@ -479,8 +460,6 @@ static struct saa7146_ext_vv vv_data = {
479 .stds = &hexium_standards[0], 460 .stds = &hexium_standards[0],
480 .num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard), 461 .num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
481 .std_callback = &std_callback, 462 .std_callback = &std_callback,
482 .ioctls = &ioctls[0],
483 .ioctl = hexium_ioctl,
484}; 463};
485 464
486static struct saa7146_extension extension = { 465static struct saa7146_extension extension = {
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index e3cbe14c349a..8ecda8dfbd04 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -110,26 +110,6 @@ static struct v4l2_queryctrl mxb_controls[] = {
110 { V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 }, 110 { V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 },
111}; 111};
112 112
113static struct saa7146_extension_ioctls ioctls[] = {
114 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
115 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
116 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
117 { VIDIOC_QUERYCTRL, SAA7146_BEFORE },
118 { VIDIOC_G_CTRL, SAA7146_BEFORE },
119 { VIDIOC_S_CTRL, SAA7146_BEFORE },
120 { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE },
121 { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
122 { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE },
123 { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE },
124 { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
125 { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
126 { VIDIOC_DBG_G_REGISTER, SAA7146_EXCLUSIVE },
127 { VIDIOC_DBG_S_REGISTER, SAA7146_EXCLUSIVE },
128 { MXB_S_AUDIO_CD, SAA7146_EXCLUSIVE }, /* custom control */
129 { MXB_S_AUDIO_LINE, SAA7146_EXCLUSIVE }, /* custom control */
130 { 0, 0 }
131};
132
133struct mxb 113struct mxb
134{ 114{
135 struct video_device *video_dev; 115 struct video_device *video_dev;
@@ -424,387 +404,430 @@ void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
424} 404}
425*/ 405*/
426 406
427static struct saa7146_ext_vv vv_data; 407static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
428
429/* this function only gets called when the probing was successful */
430static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
431{ 408{
432 struct mxb *mxb = (struct mxb *)dev->ext_priv; 409 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
410 int i;
433 411
434 DEB_EE(("dev:%p\n", dev)); 412 for (i = MAXCONTROLS - 1; i >= 0; i--) {
413 if (mxb_controls[i].id == qc->id) {
414 *qc = mxb_controls[i];
415 DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
416 return 0;
417 }
418 }
419 return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
420}
435 421
436 /* checking for i2c-devices can be omitted here, because we 422static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
437 already did this in "mxb_vl42_probe" */ 423{
424 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
425 struct mxb *mxb = (struct mxb *)dev->ext_priv;
426 int i;
438 427
439 saa7146_vv_init(dev, &vv_data); 428 for (i = MAXCONTROLS - 1; i >= 0; i--) {
440 if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) { 429 if (mxb_controls[i].id == vc->id)
441 ERR(("cannot register capture v4l2 device. skipping.\n")); 430 break;
442 return -1;
443 } 431 }
444 432
445 /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ 433 if (i < 0)
446 if (MXB_BOARD_CAN_DO_VBI(dev)) { 434 return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
447 if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
448 ERR(("cannot register vbi v4l2 device. skipping.\n"));
449 }
450 }
451 435
452 i2c_use_client(mxb->tea6420_1); 436 if (vc->id == V4L2_CID_AUDIO_MUTE) {
453 i2c_use_client(mxb->tea6420_2); 437 vc->value = mxb->cur_mute;
454 i2c_use_client(mxb->tea6415c); 438 DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
455 i2c_use_client(mxb->tda9840); 439 return 0;
456 i2c_use_client(mxb->saa7111a); 440 }
457 i2c_use_client(mxb->tuner);
458
459 printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num);
460 441
461 mxb_num++; 442 DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
462 mxb_init_done(dev);
463 return 0; 443 return 0;
464} 444}
465 445
466static int mxb_detach(struct saa7146_dev *dev) 446static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
467{ 447{
448 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
468 struct mxb *mxb = (struct mxb *)dev->ext_priv; 449 struct mxb *mxb = (struct mxb *)dev->ext_priv;
450 int i = 0;
469 451
470 DEB_EE(("dev:%p\n", dev)); 452 for (i = MAXCONTROLS - 1; i >= 0; i--) {
471 453 if (mxb_controls[i].id == vc->id)
472 i2c_release_client(mxb->tea6420_1); 454 break;
473 i2c_release_client(mxb->tea6420_2); 455 }
474 i2c_release_client(mxb->tea6415c);
475 i2c_release_client(mxb->tda9840);
476 i2c_release_client(mxb->saa7111a);
477 i2c_release_client(mxb->tuner);
478
479 saa7146_unregister_device(&mxb->video_dev,dev);
480 if (MXB_BOARD_CAN_DO_VBI(dev))
481 saa7146_unregister_device(&mxb->vbi_dev, dev);
482 saa7146_vv_release(dev);
483 456
484 mxb_num--; 457 if (i < 0)
458 return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
485 459
486 i2c_del_adapter(&mxb->i2c_adapter); 460 if (vc->id == V4L2_CID_AUDIO_MUTE) {
487 kfree(mxb); 461 mxb->cur_mute = vc->value;
462 if (!vc->value) {
463 /* switch the audio-source */
464 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
465 &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
466 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
467 &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
468 } else {
469 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
470 &TEA6420_line[6][0]);
471 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
472 &TEA6420_line[6][1]);
473 }
474 DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
475 }
476 return 0;
477}
488 478
479static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
480{
481 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
482 if (i->index < 0 || i->index >= MXB_INPUTS)
483 return -EINVAL;
484 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
489 return 0; 485 return 0;
490} 486}
491 487
492static long mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) 488static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
493{ 489{
494 struct saa7146_dev *dev = fh->dev; 490 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
495 struct mxb *mxb = (struct mxb *)dev->ext_priv; 491 struct mxb *mxb = (struct mxb *)dev->ext_priv;
496 struct saa7146_vv *vv = dev->vv_data; 492 *i = mxb->cur_input;
497 493
498 switch(cmd) { 494 DEB_EE(("VIDIOC_G_INPUT %d.\n", *i));
499 case VIDIOC_ENUMINPUT: 495 return 0;
500 { 496}
501 struct v4l2_input *i = arg;
502 497
503 DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index)); 498static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
504 if (i->index < 0 || i->index >= MXB_INPUTS) 499{
505 return -EINVAL; 500 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
506 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input)); 501 struct mxb *mxb = (struct mxb *)dev->ext_priv;
507 return 0; 502 struct tea6415c_multiplex vm;
508 } 503 struct v4l2_routing route;
509 /* the saa7146 provides some controls (brightness, contrast, saturation) 504 int i = 0;
510 which gets registered *after* this function. because of this we have
511 to return with a value != 0 even if the function succeded.. */
512 case VIDIOC_QUERYCTRL:
513 {
514 struct v4l2_queryctrl *qc = arg;
515 int i;
516
517 for (i = MAXCONTROLS - 1; i >= 0; i--) {
518 if (mxb_controls[i].id == qc->id) {
519 *qc = mxb_controls[i];
520 DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
521 return 0;
522 }
523 }
524 return -EAGAIN;
525 }
526 case VIDIOC_G_CTRL:
527 {
528 struct v4l2_control *vc = arg;
529 int i;
530 505
531 for (i = MAXCONTROLS - 1; i >= 0; i--) { 506 DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
532 if (mxb_controls[i].id == vc->id)
533 break;
534 }
535 507
536 if (i < 0) 508 if (input < 0 || input >= MXB_INPUTS)
537 return -EAGAIN; 509 return -EINVAL;
538 510
539 if (vc->id == V4L2_CID_AUDIO_MUTE) { 511 mxb->cur_input = input;
540 vc->value = mxb->cur_mute;
541 DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
542 return 0;
543 }
544 512
545 DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value)); 513 saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
546 return 0; 514 input_port_selection[input].hps_sync);
547 }
548 515
549 case VIDIOC_S_CTRL: 516 /* prepare switching of tea6415c and saa7111a;
550 { 517 have a look at the 'background'-file for further informations */
551 struct v4l2_control *vc = arg; 518 switch (input) {
552 int i = 0; 519 case TUNER:
520 i = SAA7115_COMPOSITE0;
521 vm.in = 3;
522 vm.out = 17;
553 523
554 for (i = MAXCONTROLS - 1; i >= 0; i--) { 524 if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
555 if (mxb_controls[i].id == vc->id) 525 printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n");
556 break; 526 return -EFAULT;
557 } 527 }
528 /* connect tuner-output always to multicable */
529 vm.in = 3;
530 vm.out = 13;
531 break;
532 case AUX3_YC:
533 /* nothing to be done here. aux3_yc is
534 directly connected to the saa711a */
535 i = SAA7115_SVIDEO1;
536 break;
537 case AUX3:
538 /* nothing to be done here. aux3 is
539 directly connected to the saa711a */
540 i = SAA7115_COMPOSITE1;
541 break;
542 case AUX1:
543 i = SAA7115_COMPOSITE0;
544 vm.in = 1;
545 vm.out = 17;
546 break;
547 }
558 548
559 if (i < 0) 549 /* switch video in tea6415c only if necessary */
560 return -EAGAIN; 550 switch (input) {
561 551 case TUNER:
562 if (vc->id == V4L2_CID_AUDIO_MUTE) { 552 case AUX1:
563 mxb->cur_mute = vc->value; 553 if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
564 if (!vc->value) { 554 printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n");
565 /* switch the audio-source */ 555 return -EFAULT;
566 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
567 &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
568 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
569 &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
570 } else {
571 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
572 &TEA6420_line[6][0]);
573 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
574 &TEA6420_line[6][1]);
575 }
576 DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
577 } 556 }
578 return 0; 557 break;
558 default:
559 break;
579 } 560 }
580 case VIDIOC_G_INPUT:
581 {
582 int *input = (int *)arg;
583 *input = mxb->cur_input;
584 561
585 DEB_EE(("VIDIOC_G_INPUT %d.\n", *input)); 562 /* switch video in saa7111a */
586 return 0; 563 route.input = i;
564 route.output = 0;
565 if (mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route))
566 printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a #1.\n");
567
568 /* switch the audio-source only if necessary */
569 if (0 == mxb->cur_mute) {
570 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
571 &TEA6420_line[video_audio_connect[input]][0]);
572 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
573 &TEA6420_line[video_audio_connect[input]][1]);
587 } 574 }
588 case VIDIOC_S_INPUT:
589 {
590 int input = *(int *)arg;
591 struct tea6415c_multiplex vm;
592 struct v4l2_routing route;
593 int i = 0;
594 575
595 DEB_EE(("VIDIOC_S_INPUT %d.\n", input)); 576 return 0;
577}
596 578
597 if (input < 0 || input >= MXB_INPUTS) 579static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
598 return -EINVAL; 580{
581 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
582 struct mxb *mxb = (struct mxb *)dev->ext_priv;
599 583
600 mxb->cur_input = input; 584 if (t->index) {
585 DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
586 return -EINVAL;
587 }
601 588
602 saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, 589 DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
603 input_port_selection[input].hps_sync);
604 590
605 /* prepare switching of tea6415c and saa7111a; 591 memset(t, 0, sizeof(*t));
606 have a look at the 'background'-file for further informations */ 592 i2c_clients_command(&mxb->i2c_adapter, VIDIOC_G_TUNER, t);
607 switch (input) {
608 case TUNER:
609 i = SAA7115_COMPOSITE0;
610 vm.in = 3;
611 vm.out = 17;
612 593
613 if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) { 594 strlcpy(t->name, "TV Tuner", sizeof(t->name));
614 printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n"); 595 t->type = V4L2_TUNER_ANALOG_TV;
615 return -EFAULT; 596 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
616 } 597 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
617 /* connect tuner-output always to multicable */ 598 t->audmode = mxb->cur_mode;
618 vm.in = 3; 599 return 0;
619 vm.out = 13; 600}
620 break;
621 case AUX3_YC:
622 /* nothing to be done here. aux3_yc is
623 directly connected to the saa711a */
624 i = SAA7115_SVIDEO1;
625 break;
626 case AUX3:
627 /* nothing to be done here. aux3 is
628 directly connected to the saa711a */
629 i = SAA7115_COMPOSITE1;
630 break;
631 case AUX1:
632 i = SAA7115_COMPOSITE0;
633 vm.in = 1;
634 vm.out = 17;
635 break;
636 }
637 601
638 /* switch video in tea6415c only if necessary */ 602static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
639 switch (input) { 603{
640 case TUNER: 604 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
641 case AUX1: 605 struct mxb *mxb = (struct mxb *)dev->ext_priv;
642 if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
643 printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n");
644 return -EFAULT;
645 }
646 break;
647 default:
648 break;
649 }
650 606
651 /* switch video in saa7111a */ 607 if (t->index) {
652 route.input = i; 608 DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n", t->index));
653 route.output = 0; 609 return -EINVAL;
654 if (mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route)) 610 }
655 printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");
656 611
657 /* switch the audio-source only if necessary */ 612 mxb->cur_mode = t->audmode;
658 if( 0 == mxb->cur_mute ) { 613 i2c_clients_command(&mxb->i2c_adapter, VIDIOC_S_TUNER, t);
659 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, 614 return 0;
660 &TEA6420_line[video_audio_connect[input]][0]); 615}
661 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
662 &TEA6420_line[video_audio_connect[input]][1]);
663 }
664 616
665 return 0; 617static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
618{
619 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
620 struct mxb *mxb = (struct mxb *)dev->ext_priv;
621
622 if (mxb->cur_input) {
623 DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",
624 mxb->cur_input));
625 return -EINVAL;
666 } 626 }
667 case VIDIOC_G_TUNER:
668 {
669 struct v4l2_tuner *t = arg;
670 627
671 if (t->index) { 628 *f = mxb->cur_freq;
672 DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
673 return -EINVAL;
674 }
675 629
676 DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index)); 630 DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
631 return 0;
632}
677 633
678 memset(t, 0, sizeof(*t)); 634static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
679 i2c_clients_command(&mxb->i2c_adapter, cmd, arg); 635{
636 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
637 struct mxb *mxb = (struct mxb *)dev->ext_priv;
638 struct saa7146_vv *vv = dev->vv_data;
680 639
681 strlcpy(t->name, "TV Tuner", sizeof(t->name)); 640 if (f->tuner)
682 t->type = V4L2_TUNER_ANALOG_TV; 641 return -EINVAL;
683 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | \
684 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
685 t->audmode = mxb->cur_mode;
686 return 0;
687 }
688 case VIDIOC_S_TUNER:
689 {
690 struct v4l2_tuner *t = arg;
691 642
692 if (t->index) { 643 if (V4L2_TUNER_ANALOG_TV != f->type)
693 DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index)); 644 return -EINVAL;
694 return -EINVAL;
695 }
696 645
697 mxb->cur_mode = t->audmode; 646 if (mxb->cur_input) {
698 i2c_clients_command(&mxb->i2c_adapter, cmd, arg); 647 DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input));
699 return 0; 648 return -EINVAL;
700 } 649 }
701 case VIDIOC_G_FREQUENCY:
702 {
703 struct v4l2_frequency *f = arg;
704 650
705 if (mxb->cur_input) { 651 mxb->cur_freq = *f;
706 DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n", 652 DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
707 mxb->cur_input));
708 return -EINVAL;
709 }
710 653
711 *f = mxb->cur_freq; 654 /* tune in desired frequency */
655 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq);
712 656
713 DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency)); 657 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
714 return 0; 658 spin_lock(&dev->slock);
659 vv->vbi_fieldcount = 0;
660 spin_unlock(&dev->slock);
661
662 return 0;
663}
664
665static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
666{
667 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
668 struct mxb *mxb = (struct mxb *)dev->ext_priv;
669
670 if (a->index < 0 || a->index > MXB_INPUTS) {
671 DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
672 return -EINVAL;
715 } 673 }
716 case VIDIOC_S_FREQUENCY:
717 {
718 struct v4l2_frequency *f = arg;
719 674
720 if (f->tuner) 675 DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index));
721 return -EINVAL; 676 memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
677 return 0;
678}
722 679
723 if (V4L2_TUNER_ANALOG_TV != f->type) 680static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
724 return -EINVAL; 681{
682 DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index));
683 return 0;
684}
725 685
726 if (mxb->cur_input) { 686#ifdef CONFIG_VIDEO_ADV_DEBUG
727 DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input)); 687static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
728 return -EINVAL; 688{
729 } 689 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
690 struct mxb *mxb = (struct mxb *)dev->ext_priv;
730 691
731 mxb->cur_freq = *f; 692 i2c_clients_command(&mxb->i2c_adapter, VIDIOC_DBG_G_REGISTER, reg);
732 DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency)); 693 return 0;
694}
733 695
734 /* tune in desired frequency */ 696static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
735 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq); 697{
698 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
699 struct mxb *mxb = (struct mxb *)dev->ext_priv;
736 700
737 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */ 701 i2c_clients_command(&mxb->i2c_adapter, VIDIOC_DBG_S_REGISTER, reg);
738 spin_lock(&dev->slock); 702 return 0;
739 vv->vbi_fieldcount = 0; 703}
740 spin_unlock(&dev->slock); 704#endif
741 705
742 return 0; 706static long vidioc_default(struct file *file, void *fh, int cmd, void *arg)
743 } 707{
708 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
709 struct mxb *mxb = (struct mxb *)dev->ext_priv;
710
711 switch (cmd) {
744 case MXB_S_AUDIO_CD: 712 case MXB_S_AUDIO_CD:
745 { 713 {
746 int i = *(int*)arg; 714 int i = *(int *)arg;
747 715
748 if (i < 0 || i >= MXB_AUDIOS) { 716 if (i < 0 || i >= MXB_AUDIOS) {
749 DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i)); 717 DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n", i));
750 return -EINVAL; 718 return -EINVAL;
751 } 719 }
752 720
753 DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i)); 721 DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n", i));
754 722
755 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]); 723 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_cd[i][0]);
756 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]); 724 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_cd[i][1]);
757 725
758 return 0; 726 return 0;
759 } 727 }
760 case MXB_S_AUDIO_LINE: 728 case MXB_S_AUDIO_LINE:
761 { 729 {
762 int i = *(int*)arg; 730 int i = *(int *)arg;
763 731
764 if (i < 0 || i >= MXB_AUDIOS) { 732 if (i < 0 || i >= MXB_AUDIOS) {
765 DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i)); 733 DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n", i));
766 return -EINVAL; 734 return -EINVAL;
767 } 735 }
768 736
769 DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i)); 737 DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n", i));
770 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]); 738 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_line[i][0]);
771 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]); 739 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_line[i][1]);
772 740
773 return 0; 741 return 0;
774 } 742 }
775 case VIDIOC_G_AUDIO: 743 default:
776 { 744/*
777 struct v4l2_audio *a = arg; 745 DEB2(printk("does not handle this ioctl.\n"));
746*/
747 return -ENOIOCTLCMD;
748 }
749 return 0;
750}
778 751
779 if (a->index < 0 || a->index > MXB_INPUTS) { 752static struct saa7146_ext_vv vv_data;
780 DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index)); 753
781 return -EINVAL; 754/* this function only gets called when the probing was successful */
782 } 755static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
756{
757 struct mxb *mxb = (struct mxb *)dev->ext_priv;
783 758
784 DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index)); 759 DEB_EE(("dev:%p\n", dev));
785 memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
786 760
787 return 0; 761 /* checking for i2c-devices can be omitted here, because we
788 } 762 already did this in "mxb_vl42_probe" */
789 case VIDIOC_S_AUDIO:
790 {
791 struct v4l2_audio *a = arg;
792 763
793 DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index)); 764 saa7146_vv_init(dev, &vv_data);
794 return 0; 765 vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
795 } 766 vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
767 vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
768 vv_data.ops.vidioc_enum_input = vidioc_enum_input;
769 vv_data.ops.vidioc_g_input = vidioc_g_input;
770 vv_data.ops.vidioc_s_input = vidioc_s_input;
771 vv_data.ops.vidioc_g_tuner = vidioc_g_tuner;
772 vv_data.ops.vidioc_s_tuner = vidioc_s_tuner;
773 vv_data.ops.vidioc_g_frequency = vidioc_g_frequency;
774 vv_data.ops.vidioc_s_frequency = vidioc_s_frequency;
775 vv_data.ops.vidioc_g_audio = vidioc_g_audio;
776 vv_data.ops.vidioc_s_audio = vidioc_s_audio;
796#ifdef CONFIG_VIDEO_ADV_DEBUG 777#ifdef CONFIG_VIDEO_ADV_DEBUG
797 case VIDIOC_DBG_S_REGISTER: 778 vv_data.ops.vidioc_g_register = vidioc_g_register;
798 case VIDIOC_DBG_G_REGISTER: 779 vv_data.ops.vidioc_s_register = vidioc_s_register;
799 i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
800 return 0;
801#endif 780#endif
802 default: 781 vv_data.ops.vidioc_default = vidioc_default;
803/* 782 if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
804 DEB2(printk("does not handle this ioctl.\n")); 783 ERR(("cannot register capture v4l2 device. skipping.\n"));
805*/ 784 return -1;
806 return -ENOIOCTLCMD; 785 }
786
787 /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
788 if (MXB_BOARD_CAN_DO_VBI(dev)) {
789 if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
790 ERR(("cannot register vbi v4l2 device. skipping.\n"));
791 }
807 } 792 }
793
794 i2c_use_client(mxb->tea6420_1);
795 i2c_use_client(mxb->tea6420_2);
796 i2c_use_client(mxb->tea6415c);
797 i2c_use_client(mxb->tda9840);
798 i2c_use_client(mxb->saa7111a);
799 i2c_use_client(mxb->tuner);
800
801 printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num);
802
803 mxb_num++;
804 mxb_init_done(dev);
805 return 0;
806}
807
808static int mxb_detach(struct saa7146_dev *dev)
809{
810 struct mxb *mxb = (struct mxb *)dev->ext_priv;
811
812 DEB_EE(("dev:%p\n", dev));
813
814 i2c_release_client(mxb->tea6420_1);
815 i2c_release_client(mxb->tea6420_2);
816 i2c_release_client(mxb->tea6415c);
817 i2c_release_client(mxb->tda9840);
818 i2c_release_client(mxb->saa7111a);
819 i2c_release_client(mxb->tuner);
820
821 saa7146_unregister_device(&mxb->video_dev,dev);
822 if (MXB_BOARD_CAN_DO_VBI(dev))
823 saa7146_unregister_device(&mxb->vbi_dev, dev);
824 saa7146_vv_release(dev);
825
826 mxb_num--;
827
828 i2c_del_adapter(&mxb->i2c_adapter);
829 kfree(mxb);
830
808 return 0; 831 return 0;
809} 832}
810 833
@@ -885,8 +908,6 @@ static struct saa7146_ext_vv vv_data = {
885 .stds = &standard[0], 908 .stds = &standard[0],
886 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard), 909 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
887 .std_callback = &std_callback, 910 .std_callback = &std_callback,
888 .ioctls = &ioctls[0],
889 .ioctl = mxb_ioctl,
890}; 911};
891 912
892static struct saa7146_extension extension = { 913static struct saa7146_extension extension = {