aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx88/cx88-video.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx88/cx88-video.c')
-rw-r--r--drivers/media/video/cx88/cx88-video.c67
1 files changed, 42 insertions, 25 deletions
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index ef4d56ea0027..3904b73f52ee 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -426,24 +426,7 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input)
426 426
427 /* if there are audioroutes defined, we have an external 427 /* if there are audioroutes defined, we have an external
428 ADC to deal with audio */ 428 ADC to deal with audio */
429
430 if (INPUT(input).audioroute) { 429 if (INPUT(input).audioroute) {
431
432 /* cx2388's C-ADC is connected to the tuner only.
433 When used with S-Video, that ADC is busy dealing with
434 chroma, so an external must be used for baseband audio */
435
436 if (INPUT(input).type != CX88_VMUX_TELEVISION &&
437 INPUT(input).type != CX88_RADIO) {
438 /* "ADC mode" */
439 cx_write(AUD_I2SCNTL, 0x1);
440 cx_set(AUD_CTL, EN_I2SIN_ENABLE);
441 } else {
442 /* Normal mode */
443 cx_write(AUD_I2SCNTL, 0x0);
444 cx_clear(AUD_CTL, EN_I2SIN_ENABLE);
445 }
446
447 /* The wm8775 module has the "2" route hardwired into 430 /* The wm8775 module has the "2" route hardwired into
448 the initialization. Some boards may use different 431 the initialization. Some boards may use different
449 routes for different inputs. HVR-1300 surely does */ 432 routes for different inputs. HVR-1300 surely does */
@@ -454,9 +437,19 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input)
454 route.input = INPUT(input).audioroute; 437 route.input = INPUT(input).audioroute;
455 cx88_call_i2c_clients(core, 438 cx88_call_i2c_clients(core,
456 VIDIOC_INT_S_AUDIO_ROUTING, &route); 439 VIDIOC_INT_S_AUDIO_ROUTING, &route);
457
458 } 440 }
459 441 /* cx2388's C-ADC is connected to the tuner only.
442 When used with S-Video, that ADC is busy dealing with
443 chroma, so an external must be used for baseband audio */
444 if (INPUT(input).type != CX88_VMUX_TELEVISION ) {
445 /* "I2S ADC mode" */
446 core->tvaudio = WW_I2SADC;
447 cx88_set_tvaudio(core);
448 } else {
449 /* Normal mode */
450 cx_write(AUD_I2SCNTL, 0x0);
451 cx_clear(AUD_CTL, EN_I2SIN_ENABLE);
452 }
460 } 453 }
461 454
462 return 0; 455 return 0;
@@ -773,6 +766,7 @@ static int video_open(struct inode *inode, struct file *file)
773 enum v4l2_buf_type type = 0; 766 enum v4l2_buf_type type = 0;
774 int radio = 0; 767 int radio = 0;
775 768
769 lock_kernel();
776 list_for_each_entry(h, &cx8800_devlist, devlist) { 770 list_for_each_entry(h, &cx8800_devlist, devlist) {
777 if (h->video_dev->minor == minor) { 771 if (h->video_dev->minor == minor) {
778 dev = h; 772 dev = h;
@@ -788,8 +782,10 @@ static int video_open(struct inode *inode, struct file *file)
788 dev = h; 782 dev = h;
789 } 783 }
790 } 784 }
791 if (NULL == dev) 785 if (NULL == dev) {
786 unlock_kernel();
792 return -ENODEV; 787 return -ENODEV;
788 }
793 789
794 core = dev->core; 790 core = dev->core;
795 791
@@ -798,8 +794,10 @@ static int video_open(struct inode *inode, struct file *file)
798 794
799 /* allocate + initialize per filehandle data */ 795 /* allocate + initialize per filehandle data */
800 fh = kzalloc(sizeof(*fh),GFP_KERNEL); 796 fh = kzalloc(sizeof(*fh),GFP_KERNEL);
801 if (NULL == fh) 797 if (NULL == fh) {
798 unlock_kernel();
802 return -ENOMEM; 799 return -ENOMEM;
800 }
803 file->private_data = fh; 801 file->private_data = fh;
804 fh->dev = dev; 802 fh->dev = dev;
805 fh->radio = radio; 803 fh->radio = radio;
@@ -827,11 +825,29 @@ static int video_open(struct inode *inode, struct file *file)
827 cx_write(MO_GP0_IO, core->board.radio.gpio0); 825 cx_write(MO_GP0_IO, core->board.radio.gpio0);
828 cx_write(MO_GP1_IO, core->board.radio.gpio1); 826 cx_write(MO_GP1_IO, core->board.radio.gpio1);
829 cx_write(MO_GP2_IO, core->board.radio.gpio2); 827 cx_write(MO_GP2_IO, core->board.radio.gpio2);
830 core->tvaudio = WW_FM; 828 if (core->board.radio.audioroute) {
831 cx88_set_tvaudio(core); 829 if(core->board.audio_chip &&
832 cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1); 830 core->board.audio_chip == V4L2_IDENT_WM8775) {
831 struct v4l2_routing route;
832
833 route.input = core->board.radio.audioroute;
834 cx88_call_i2c_clients(core,
835 VIDIOC_INT_S_AUDIO_ROUTING, &route);
836 }
837 /* "I2S ADC mode" */
838 core->tvaudio = WW_I2SADC;
839 cx88_set_tvaudio(core);
840 } else {
841 /* FM Mode */
842 core->tvaudio = WW_FM;
843 cx88_set_tvaudio(core);
844 cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1);
845 }
833 cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL); 846 cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL);
834 } 847 }
848 unlock_kernel();
849
850 atomic_inc(&core->users);
835 851
836 return 0; 852 return 0;
837} 853}
@@ -920,7 +936,8 @@ static int video_release(struct inode *inode, struct file *file)
920 file->private_data = NULL; 936 file->private_data = NULL;
921 kfree(fh); 937 kfree(fh);
922 938
923 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); 939 if(atomic_dec_and_test(&dev->core->users))
940 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
924 941
925 return 0; 942 return 0;
926} 943}