aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/mxb.c
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/video/mxb.c
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/video/mxb.c')
-rw-r--r--drivers/media/video/mxb.c641
1 files changed, 331 insertions, 310 deletions
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 = {