diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-04-30 03:58:27 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-14 13:56:27 -0400 |
commit | 6680427791c94e611220a6cb34ae47dac9e3aa98 (patch) | |
tree | c1536c36314be55c08ed089049cc131becac039b | |
parent | d69f4a517c0a9b0b4795f4604aed8cf96dcd5223 (diff) |
[media] mxb: fix audio handling
Instead of using custom ioctls use the VIDIOC_ENUM/G/S/_AUDIO ioctls.
Also send the same audio to both CDROM-out and line-out.
This is what you would expect and anyway, the CDROM-out connector is unlikely
to be used these days as it is obsolete.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/mxb.c | 90 | ||||
-rw-r--r-- | drivers/media/video/mxb.h | 13 |
2 files changed, 26 insertions, 77 deletions
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index aa3d75c1e351..a698c24bea20 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c | |||
@@ -31,10 +31,11 @@ | |||
31 | #include <media/saa7115.h> | 31 | #include <media/saa7115.h> |
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | 33 | ||
34 | #include "mxb.h" | ||
35 | #include "tea6415c.h" | 34 | #include "tea6415c.h" |
36 | #include "tea6420.h" | 35 | #include "tea6420.h" |
37 | 36 | ||
37 | #define MXB_AUDIOS 6 | ||
38 | |||
38 | #define I2C_SAA7111A 0x24 | 39 | #define I2C_SAA7111A 0x24 |
39 | #define I2C_TDA9840 0x42 | 40 | #define I2C_TDA9840 0x42 |
40 | #define I2C_TEA6415C 0x43 | 41 | #define I2C_TEA6415C 0x43 |
@@ -62,10 +63,14 @@ MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); | |||
62 | enum { TUNER, AUX1, AUX3, AUX3_YC }; | 63 | enum { TUNER, AUX1, AUX3, AUX3_YC }; |
63 | 64 | ||
64 | static struct v4l2_input mxb_inputs[MXB_INPUTS] = { | 65 | static struct v4l2_input mxb_inputs[MXB_INPUTS] = { |
65 | { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, | 66 | { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 0x2f, 0, |
66 | { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, | 67 | V4L2_STD_PAL_BG | V4L2_STD_PAL_I, 0, V4L2_IN_CAP_STD }, |
67 | { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 8, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, | 68 | { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 0x2f, 0, |
68 | { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 8, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, | 69 | V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, |
70 | { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 0x2f, 0, | ||
71 | V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, | ||
72 | { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 0x2f, 0, | ||
73 | V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, | ||
69 | }; | 74 | }; |
70 | 75 | ||
71 | /* this array holds the information, which port of the saa7146 each | 76 | /* this array holds the information, which port of the saa7146 each |
@@ -160,6 +165,7 @@ struct mxb | |||
160 | 165 | ||
161 | int cur_mode; /* current audio mode (mono, stereo, ...) */ | 166 | int cur_mode; /* current audio mode (mono, stereo, ...) */ |
162 | int cur_input; /* current input */ | 167 | int cur_input; /* current input */ |
168 | int cur_audinput; /* current audio input */ | ||
163 | int cur_mute; /* current mute status */ | 169 | int cur_mute; /* current mute status */ |
164 | struct v4l2_frequency cur_freq; /* current frequency the tuner is tuned to */ | 170 | struct v4l2_frequency cur_freq; /* current frequency the tuner is tuned to */ |
165 | }; | 171 | }; |
@@ -175,16 +181,12 @@ struct mxb | |||
175 | #define call_all(dev, o, f, args...) \ | 181 | #define call_all(dev, o, f, args...) \ |
176 | v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args) | 182 | v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args) |
177 | 183 | ||
178 | static inline void tea6420_route_cd(struct mxb *mxb, int idx) | 184 | static inline void tea6420_route(struct mxb *mxb, int idx) |
179 | { | 185 | { |
180 | v4l2_subdev_call(mxb->tea6420_1, audio, s_routing, | 186 | v4l2_subdev_call(mxb->tea6420_1, audio, s_routing, |
181 | TEA6420_cd[idx][0].input, TEA6420_cd[idx][0].output, 0); | 187 | TEA6420_cd[idx][0].input, TEA6420_cd[idx][0].output, 0); |
182 | v4l2_subdev_call(mxb->tea6420_2, audio, s_routing, | 188 | v4l2_subdev_call(mxb->tea6420_2, audio, s_routing, |
183 | TEA6420_cd[idx][1].input, TEA6420_cd[idx][1].output, 0); | 189 | TEA6420_cd[idx][1].input, TEA6420_cd[idx][1].output, 0); |
184 | } | ||
185 | |||
186 | static inline void tea6420_route_line(struct mxb *mxb, int idx) | ||
187 | { | ||
188 | v4l2_subdev_call(mxb->tea6420_1, audio, s_routing, | 190 | v4l2_subdev_call(mxb->tea6420_1, audio, s_routing, |
189 | TEA6420_line[idx][0].input, TEA6420_line[idx][0].output, 0); | 191 | TEA6420_line[idx][0].input, TEA6420_line[idx][0].output, 0); |
190 | v4l2_subdev_call(mxb->tea6420_2, audio, s_routing, | 192 | v4l2_subdev_call(mxb->tea6420_2, audio, s_routing, |
@@ -203,7 +205,7 @@ static int mxb_s_ctrl(struct v4l2_ctrl *ctrl) | |||
203 | case V4L2_CID_AUDIO_MUTE: | 205 | case V4L2_CID_AUDIO_MUTE: |
204 | mxb->cur_mute = ctrl->val; | 206 | mxb->cur_mute = ctrl->val; |
205 | /* switch the audio-source */ | 207 | /* switch the audio-source */ |
206 | tea6420_route_line(mxb, ctrl->val ? 6 : | 208 | tea6420_route(mxb, ctrl->val ? 6 : |
207 | video_audio_connect[mxb->cur_input]); | 209 | video_audio_connect[mxb->cur_input]); |
208 | break; | 210 | break; |
209 | default: | 211 | default: |
@@ -365,8 +367,7 @@ static int mxb_init_done(struct saa7146_dev* dev) | |||
365 | tuner_call(mxb, core, s_std, std); | 367 | tuner_call(mxb, core, s_std, std); |
366 | 368 | ||
367 | /* mute audio on tea6420s */ | 369 | /* mute audio on tea6420s */ |
368 | tea6420_route_line(mxb, 6); | 370 | tea6420_route(mxb, 6); |
369 | tea6420_route_cd(mxb, 6); | ||
370 | 371 | ||
371 | /* switch to tuner-channel on tea6415c */ | 372 | /* switch to tuner-channel on tea6415c */ |
372 | tea6415c_call(mxb, video, s_routing, 3, 17, 0); | 373 | tea6415c_call(mxb, video, s_routing, 3, 17, 0); |
@@ -376,6 +377,7 @@ static int mxb_init_done(struct saa7146_dev* dev) | |||
376 | 377 | ||
377 | /* the rest for mxb */ | 378 | /* the rest for mxb */ |
378 | mxb->cur_input = 0; | 379 | mxb->cur_input = 0; |
380 | mxb->cur_audinput = video_audio_connect[mxb->cur_input]; | ||
379 | mxb->cur_mute = 0; | 381 | mxb->cur_mute = 0; |
380 | 382 | ||
381 | mxb->cur_mode = V4L2_TUNER_MODE_STEREO; | 383 | mxb->cur_mode = V4L2_TUNER_MODE_STEREO; |
@@ -512,9 +514,10 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input) | |||
512 | if (saa7111a_call(mxb, video, s_routing, i, SAA7111_FMT_CCIR, 0)) | 514 | if (saa7111a_call(mxb, video, s_routing, i, SAA7111_FMT_CCIR, 0)) |
513 | pr_err("VIDIOC_S_INPUT: could not address saa7111a\n"); | 515 | pr_err("VIDIOC_S_INPUT: could not address saa7111a\n"); |
514 | 516 | ||
517 | mxb->cur_audinput = video_audio_connect[input]; | ||
515 | /* switch the audio-source only if necessary */ | 518 | /* switch the audio-source only if necessary */ |
516 | if (0 == mxb->cur_mute) | 519 | if (0 == mxb->cur_mute) |
517 | tea6420_route_line(mxb, video_audio_connect[input]); | 520 | tea6420_route(mxb, mxb->cur_audinput); |
518 | 521 | ||
519 | return 0; | 522 | return 0; |
520 | } | 523 | } |
@@ -619,7 +622,7 @@ static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) | |||
619 | } | 622 | } |
620 | 623 | ||
621 | DEB_EE("VIDIOC_G_AUDIO %d\n", a->index); | 624 | DEB_EE("VIDIOC_G_AUDIO %d\n", a->index); |
622 | memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio)); | 625 | memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_audinput]], sizeof(struct v4l2_audio)); |
623 | return 0; | 626 | return 0; |
624 | } | 627 | } |
625 | 628 | ||
@@ -629,8 +632,13 @@ static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a) | |||
629 | struct mxb *mxb = (struct mxb *)dev->ext_priv; | 632 | struct mxb *mxb = (struct mxb *)dev->ext_priv; |
630 | 633 | ||
631 | DEB_D("VIDIOC_S_AUDIO %d\n", a->index); | 634 | DEB_D("VIDIOC_S_AUDIO %d\n", a->index); |
632 | if (mxb_inputs[mxb->cur_input].audioset & (1 << a->index)) | 635 | if (mxb_inputs[mxb->cur_input].audioset & (1 << a->index)) { |
636 | if (mxb->cur_audinput != a->index) { | ||
637 | mxb->cur_audinput = a->index; | ||
638 | tea6420_route(mxb, a->index); | ||
639 | } | ||
633 | return 0; | 640 | return 0; |
641 | } | ||
634 | return -EINVAL; | 642 | return -EINVAL; |
635 | } | 643 | } |
636 | 644 | ||
@@ -650,50 +658,6 @@ static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_regist | |||
650 | } | 658 | } |
651 | #endif | 659 | #endif |
652 | 660 | ||
653 | static long vidioc_default(struct file *file, void *fh, bool valid_prio, | ||
654 | int cmd, void *arg) | ||
655 | { | ||
656 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
657 | struct mxb *mxb = (struct mxb *)dev->ext_priv; | ||
658 | |||
659 | switch (cmd) { | ||
660 | case MXB_S_AUDIO_CD: | ||
661 | { | ||
662 | int i = *(int *)arg; | ||
663 | |||
664 | if (i < 0 || i >= MXB_AUDIOS) { | ||
665 | DEB_D("invalid argument to MXB_S_AUDIO_CD: i:%d\n", i); | ||
666 | return -EINVAL; | ||
667 | } | ||
668 | |||
669 | DEB_EE("MXB_S_AUDIO_CD: i:%d\n", i); | ||
670 | |||
671 | tea6420_route_cd(mxb, i); | ||
672 | return 0; | ||
673 | } | ||
674 | case MXB_S_AUDIO_LINE: | ||
675 | { | ||
676 | int i = *(int *)arg; | ||
677 | |||
678 | if (i < 0 || i >= MXB_AUDIOS) { | ||
679 | DEB_D("invalid argument to MXB_S_AUDIO_LINE: i:%d\n", | ||
680 | i); | ||
681 | return -EINVAL; | ||
682 | } | ||
683 | |||
684 | DEB_EE("MXB_S_AUDIO_LINE: i:%d\n", i); | ||
685 | tea6420_route_line(mxb, i); | ||
686 | return 0; | ||
687 | } | ||
688 | default: | ||
689 | /* | ||
690 | DEB2(pr_err("does not handle this ioctl\n")); | ||
691 | */ | ||
692 | return -ENOTTY; | ||
693 | } | ||
694 | return 0; | ||
695 | } | ||
696 | |||
697 | static struct saa7146_ext_vv vv_data; | 661 | static struct saa7146_ext_vv vv_data; |
698 | 662 | ||
699 | /* this function only gets called when the probing was successful */ | 663 | /* this function only gets called when the probing was successful */ |
@@ -724,7 +688,6 @@ static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data | |||
724 | vv_data.ops.vidioc_g_register = vidioc_g_register; | 688 | vv_data.ops.vidioc_g_register = vidioc_g_register; |
725 | vv_data.ops.vidioc_s_register = vidioc_s_register; | 689 | vv_data.ops.vidioc_s_register = vidioc_s_register; |
726 | #endif | 690 | #endif |
727 | vv_data.ops.vidioc_default = vidioc_default; | ||
728 | if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) { | 691 | if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) { |
729 | ERR("cannot register capture v4l2 device. skipping.\n"); | 692 | ERR("cannot register capture v4l2 device. skipping.\n"); |
730 | saa7146_vv_release(dev); | 693 | saa7146_vv_release(dev); |
@@ -752,8 +715,7 @@ static int mxb_detach(struct saa7146_dev *dev) | |||
752 | DEB_EE("dev:%p\n", dev); | 715 | DEB_EE("dev:%p\n", dev); |
753 | 716 | ||
754 | /* mute audio on tea6420s */ | 717 | /* mute audio on tea6420s */ |
755 | tea6420_route_line(mxb, 6); | 718 | tea6420_route(mxb, 6); |
756 | tea6420_route_cd(mxb, 6); | ||
757 | 719 | ||
758 | saa7146_unregister_device(&mxb->video_dev,dev); | 720 | saa7146_unregister_device(&mxb->video_dev,dev); |
759 | if (MXB_BOARD_CAN_DO_VBI(dev)) | 721 | if (MXB_BOARD_CAN_DO_VBI(dev)) |
@@ -852,7 +814,7 @@ static struct saa7146_ext_vv vv_data = { | |||
852 | }; | 814 | }; |
853 | 815 | ||
854 | static struct saa7146_extension extension = { | 816 | static struct saa7146_extension extension = { |
855 | .name = MXB_IDENTIFIER, | 817 | .name = "Multimedia eXtension Board", |
856 | .flags = SAA7146_USE_I2C_IRQ, | 818 | .flags = SAA7146_USE_I2C_IRQ, |
857 | 819 | ||
858 | .pci_tbl = &pci_tbl[0], | 820 | .pci_tbl = &pci_tbl[0], |
diff --git a/drivers/media/video/mxb.h b/drivers/media/video/mxb.h deleted file mode 100644 index dfa4b1cca23a..000000000000 --- a/drivers/media/video/mxb.h +++ /dev/null | |||
@@ -1,13 +0,0 @@ | |||
1 | #ifndef __MXB__ | ||
2 | #define __MXB__ | ||
3 | |||
4 | #define BASE_VIDIOC_MXB 10 | ||
5 | |||
6 | #define MXB_S_AUDIO_CD _IOW ('V', BASE_VIDIOC_PRIVATE+BASE_VIDIOC_MXB+0, int) | ||
7 | #define MXB_S_AUDIO_LINE _IOW ('V', BASE_VIDIOC_PRIVATE+BASE_VIDIOC_MXB+1, int) | ||
8 | |||
9 | #define MXB_IDENTIFIER "Multimedia eXtension Board" | ||
10 | |||
11 | #define MXB_AUDIOS 6 | ||
12 | |||
13 | #endif | ||