diff options
| author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-05-01 09:12:22 -0400 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-14 13:57:22 -0400 |
| commit | 4894b709d14c593466cc05e55ee493af931205e8 (patch) | |
| tree | ec83ae06bbab87a54f75b87dcf62f65ba2721f76 /drivers/media/video/mxb.c | |
| parent | 8bb5bafa8057a91613d50f7b0bec025852360237 (diff) | |
[media] mxb: fix audio and standard handling
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/mxb.c')
| -rw-r--r-- | drivers/media/video/mxb.c | 53 |
1 files changed, 33 insertions, 20 deletions
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index d26781871b1..db0c5ddec87 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c | |||
| @@ -63,13 +63,13 @@ MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); | |||
| 63 | enum { TUNER, AUX1, AUX3, AUX3_YC }; | 63 | enum { TUNER, AUX1, AUX3, AUX3_YC }; |
| 64 | 64 | ||
| 65 | static struct v4l2_input mxb_inputs[MXB_INPUTS] = { | 65 | static struct v4l2_input mxb_inputs[MXB_INPUTS] = { |
| 66 | { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 0x2f, 0, | 66 | { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 0x3f, 0, |
| 67 | V4L2_STD_PAL_BG | V4L2_STD_PAL_I, 0, V4L2_IN_CAP_STD }, | 67 | V4L2_STD_PAL_BG | V4L2_STD_PAL_I, 0, V4L2_IN_CAP_STD }, |
| 68 | { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 0x2f, 0, | 68 | { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 0x3f, 0, |
| 69 | V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, | 69 | V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, |
| 70 | { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 0x2f, 0, | 70 | { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 0x3f, 0, |
| 71 | V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, | 71 | V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, |
| 72 | { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 0x2f, 0, | 72 | { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 0x3f, 0, |
| 73 | V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, | 73 | V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, |
| 74 | }; | 74 | }; |
| 75 | 75 | ||
| @@ -181,6 +181,15 @@ struct mxb | |||
| 181 | #define call_all(dev, o, f, args...) \ | 181 | #define call_all(dev, o, f, args...) \ |
| 182 | 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) |
| 183 | 183 | ||
| 184 | static void mxb_update_audmode(struct mxb *mxb) | ||
| 185 | { | ||
| 186 | struct v4l2_tuner t = { | ||
| 187 | .audmode = mxb->cur_mode, | ||
| 188 | }; | ||
| 189 | |||
| 190 | tda9840_call(mxb, tuner, s_tuner, &t); | ||
| 191 | } | ||
| 192 | |||
| 184 | static inline void tea6420_route(struct mxb *mxb, int idx) | 193 | static inline void tea6420_route(struct mxb *mxb, int idx) |
| 185 | { | 194 | { |
| 186 | v4l2_subdev_call(mxb->tea6420_1, audio, s_routing, | 195 | v4l2_subdev_call(mxb->tea6420_1, audio, s_routing, |
| @@ -224,7 +233,7 @@ static int mxb_probe(struct saa7146_dev *dev) | |||
| 224 | struct mxb *mxb = NULL; | 233 | struct mxb *mxb = NULL; |
| 225 | 234 | ||
| 226 | v4l2_ctrl_new_std(hdl, &mxb_ctrl_ops, | 235 | v4l2_ctrl_new_std(hdl, &mxb_ctrl_ops, |
| 227 | V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); | 236 | V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); |
| 228 | if (hdl->error) | 237 | if (hdl->error) |
| 229 | return hdl->error; | 238 | return hdl->error; |
| 230 | mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL); | 239 | mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL); |
| @@ -344,6 +353,9 @@ static int mxb_init_done(struct saa7146_dev* dev) | |||
| 344 | 353 | ||
| 345 | int i = 0, err = 0; | 354 | int i = 0, err = 0; |
| 346 | 355 | ||
| 356 | /* mute audio on tea6420s */ | ||
| 357 | tea6420_route(mxb, 6); | ||
| 358 | |||
| 347 | /* select video mode in saa7111a */ | 359 | /* select video mode in saa7111a */ |
| 348 | saa7111a_call(mxb, core, s_std, std); | 360 | saa7111a_call(mxb, core, s_std, std); |
| 349 | 361 | ||
| @@ -364,11 +376,12 @@ static int mxb_init_done(struct saa7146_dev* dev) | |||
| 364 | tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq); | 376 | tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq); |
| 365 | 377 | ||
| 366 | /* set a default video standard */ | 378 | /* set a default video standard */ |
| 379 | /* These two gpio calls set the GPIO pins that control the tda9820 */ | ||
| 380 | saa7146_write(dev, GPIO_CTRL, 0x00404050); | ||
| 381 | saa7111a_call(mxb, core, s_gpio, 1); | ||
| 382 | saa7111a_call(mxb, core, s_std, std); | ||
| 367 | tuner_call(mxb, core, s_std, std); | 383 | tuner_call(mxb, core, s_std, std); |
| 368 | 384 | ||
| 369 | /* mute audio on tea6420s */ | ||
| 370 | tea6420_route(mxb, 6); | ||
| 371 | |||
| 372 | /* switch to tuner-channel on tea6415c */ | 385 | /* switch to tuner-channel on tea6415c */ |
| 373 | tea6415c_call(mxb, video, s_routing, 3, 17, 0); | 386 | tea6415c_call(mxb, video, s_routing, 3, 17, 0); |
| 374 | 387 | ||
| @@ -378,9 +391,10 @@ static int mxb_init_done(struct saa7146_dev* dev) | |||
| 378 | /* the rest for mxb */ | 391 | /* the rest for mxb */ |
| 379 | mxb->cur_input = 0; | 392 | mxb->cur_input = 0; |
| 380 | mxb->cur_audinput = video_audio_connect[mxb->cur_input]; | 393 | mxb->cur_audinput = video_audio_connect[mxb->cur_input]; |
| 381 | mxb->cur_mute = 0; | 394 | mxb->cur_mute = 1; |
| 382 | 395 | ||
| 383 | mxb->cur_mode = V4L2_TUNER_MODE_STEREO; | 396 | mxb->cur_mode = V4L2_TUNER_MODE_STEREO; |
| 397 | mxb_update_audmode(mxb); | ||
| 384 | 398 | ||
| 385 | /* check if the saa7740 (aka 'sound arena module') is present | 399 | /* check if the saa7740 (aka 'sound arena module') is present |
| 386 | on the mxb. if so, we must initialize it. due to lack of | 400 | on the mxb. if so, we must initialize it. due to lack of |
| @@ -518,6 +532,8 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input) | |||
| 518 | /* switch the audio-source only if necessary */ | 532 | /* switch the audio-source only if necessary */ |
| 519 | if (0 == mxb->cur_mute) | 533 | if (0 == mxb->cur_mute) |
| 520 | tea6420_route(mxb, mxb->cur_audinput); | 534 | tea6420_route(mxb, mxb->cur_audinput); |
| 535 | if (mxb->cur_audinput == 0) | ||
| 536 | mxb_update_audmode(mxb); | ||
| 521 | 537 | ||
| 522 | return 0; | 538 | return 0; |
| 523 | } | 539 | } |
| @@ -591,6 +607,8 @@ static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency | |||
| 591 | /* let the tuner subdev clamp the frequency to the tuner range */ | 607 | /* let the tuner subdev clamp the frequency to the tuner range */ |
| 592 | tuner_call(mxb, tuner, g_frequency, f); | 608 | tuner_call(mxb, tuner, g_frequency, f); |
| 593 | mxb->cur_freq = *f; | 609 | mxb->cur_freq = *f; |
| 610 | if (mxb->cur_audinput == 0) | ||
| 611 | mxb_update_audmode(mxb); | ||
| 594 | 612 | ||
| 595 | if (mxb->cur_input) | 613 | if (mxb->cur_input) |
| 596 | return 0; | 614 | return 0; |
| @@ -616,13 +634,8 @@ static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) | |||
| 616 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | 634 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; |
| 617 | struct mxb *mxb = (struct mxb *)dev->ext_priv; | 635 | struct mxb *mxb = (struct mxb *)dev->ext_priv; |
| 618 | 636 | ||
| 619 | if (a->index > MXB_INPUTS) { | 637 | DEB_EE("VIDIOC_G_AUDIO\n"); |
| 620 | DEB_D("VIDIOC_G_AUDIO %d out of range\n", a->index); | 638 | *a = mxb_audios[mxb->cur_audinput]; |
| 621 | return -EINVAL; | ||
| 622 | } | ||
| 623 | |||
| 624 | DEB_EE("VIDIOC_G_AUDIO %d\n", a->index); | ||
| 625 | *a = mxb_audios[video_audio_connect[mxb->cur_audinput]]; | ||
| 626 | return 0; | 639 | return 0; |
| 627 | } | 640 | } |
| 628 | 641 | ||
| @@ -636,6 +649,8 @@ static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a) | |||
| 636 | if (mxb->cur_audinput != a->index) { | 649 | if (mxb->cur_audinput != a->index) { |
| 637 | mxb->cur_audinput = a->index; | 650 | mxb->cur_audinput = a->index; |
| 638 | tea6420_route(mxb, a->index); | 651 | tea6420_route(mxb, a->index); |
| 652 | if (mxb->cur_audinput == 0) | ||
| 653 | mxb_update_audmode(mxb); | ||
| 639 | } | 654 | } |
| 640 | return 0; | 655 | return 0; |
| 641 | } | 656 | } |
| @@ -738,9 +753,8 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa | |||
| 738 | v4l2_std_id std = V4L2_STD_PAL_I; | 753 | v4l2_std_id std = V4L2_STD_PAL_I; |
| 739 | 754 | ||
| 740 | DEB_D("VIDIOC_S_STD: setting mxb for PAL_I\n"); | 755 | DEB_D("VIDIOC_S_STD: setting mxb for PAL_I\n"); |
| 741 | /* set the 7146 gpio register -- I don't know what this does exactly */ | 756 | /* These two gpio calls set the GPIO pins that control the tda9820 */ |
| 742 | saa7146_write(dev, GPIO_CTRL, 0x00404050); | 757 | saa7146_write(dev, GPIO_CTRL, 0x00404050); |
| 743 | /* unset the 7111 gpio register -- I don't know what this does exactly */ | ||
| 744 | saa7111a_call(mxb, core, s_gpio, 0); | 758 | saa7111a_call(mxb, core, s_gpio, 0); |
| 745 | saa7111a_call(mxb, core, s_std, std); | 759 | saa7111a_call(mxb, core, s_std, std); |
| 746 | if (mxb->cur_input == 0) | 760 | if (mxb->cur_input == 0) |
| @@ -751,9 +765,8 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa | |||
| 751 | if (mxb->cur_input) | 765 | if (mxb->cur_input) |
| 752 | std = standard->id; | 766 | std = standard->id; |
| 753 | DEB_D("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM\n"); | 767 | DEB_D("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM\n"); |
| 754 | /* set the 7146 gpio register -- I don't know what this does exactly */ | 768 | /* These two gpio calls set the GPIO pins that control the tda9820 */ |
| 755 | saa7146_write(dev, GPIO_CTRL, 0x00404050); | 769 | saa7146_write(dev, GPIO_CTRL, 0x00404050); |
| 756 | /* set the 7111 gpio register -- I don't know what this does exactly */ | ||
| 757 | saa7111a_call(mxb, core, s_gpio, 1); | 770 | saa7111a_call(mxb, core, s_gpio, 1); |
| 758 | saa7111a_call(mxb, core, s_std, std); | 771 | saa7111a_call(mxb, core, s_std, std); |
| 759 | if (mxb->cur_input == 0) | 772 | if (mxb->cur_input == 0) |
