aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx88/cx88-tvaudio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx88/cx88-tvaudio.c')
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c115
1 files changed, 86 insertions, 29 deletions
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 7dd506b987fe..e8316cf7f32f 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -163,6 +163,8 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
163 /* unmute */ 163 /* unmute */
164 volume = cx_sread(SHADOW_AUD_VOL_CTL); 164 volume = cx_sread(SHADOW_AUD_VOL_CTL);
165 cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, volume); 165 cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, volume);
166
167 core->last_change = jiffies;
166} 168}
167 169
168/* ----------------------------------------------------------- */ 170/* ----------------------------------------------------------- */
@@ -745,6 +747,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
745 break; 747 break;
746 case WW_BG: 748 case WW_BG:
747 case WW_DK: 749 case WW_DK:
750 case WW_M:
748 case WW_I: 751 case WW_I:
749 case WW_L: 752 case WW_L:
750 /* prepare all dsp registers */ 753 /* prepare all dsp registers */
@@ -756,6 +759,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
756 if (0 == cx88_detect_nicam(core)) { 759 if (0 == cx88_detect_nicam(core)) {
757 /* fall back to fm / am mono */ 760 /* fall back to fm / am mono */
758 set_audio_standard_A2(core, EN_A2_FORCE_MONO1); 761 set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
762 core->audiomode_current = V4L2_TUNER_MODE_MONO;
759 core->use_nicam = 0; 763 core->use_nicam = 0;
760 } else { 764 } else {
761 core->use_nicam = 1; 765 core->use_nicam = 1;
@@ -787,6 +791,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
787void cx88_newstation(struct cx88_core *core) 791void cx88_newstation(struct cx88_core *core)
788{ 792{
789 core->audiomode_manual = UNSET; 793 core->audiomode_manual = UNSET;
794 core->last_change = jiffies;
790} 795}
791 796
792void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) 797void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
@@ -805,12 +810,50 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
805 aud_ctl_names[cx_read(AUD_CTL) & 63]); 810 aud_ctl_names[cx_read(AUD_CTL) & 63]);
806 core->astat = reg; 811 core->astat = reg;
807 812
808/* TODO 813 t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP |
809 Reading from AUD_STATUS is not enough 814 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
810 for auto-detecting sap/dual-fm/nicam. 815 t->rxsubchans = UNSET;
811 Add some code here later. 816 t->audmode = V4L2_TUNER_MODE_MONO;
812*/ 817
818 switch (mode) {
819 case 0:
820 t->audmode = V4L2_TUNER_MODE_STEREO;
821 break;
822 case 1:
823 t->audmode = V4L2_TUNER_MODE_LANG2;
824 break;
825 case 2:
826 t->audmode = V4L2_TUNER_MODE_MONO;
827 break;
828 case 3:
829 t->audmode = V4L2_TUNER_MODE_SAP;
830 break;
831 }
813 832
833 switch (core->tvaudio) {
834 case WW_BTSC:
835 case WW_BG:
836 case WW_DK:
837 case WW_M:
838 case WW_EIAJ:
839 if (!core->use_nicam) {
840 t->rxsubchans = cx88_dsp_detect_stereo_sap(core);
841 break;
842 }
843 break;
844 default:
845 /* nothing */
846 break;
847 }
848
849 /* If software stereo detection is not supported... */
850 if (UNSET == t->rxsubchans) {
851 t->rxsubchans = V4L2_TUNER_SUB_MONO;
852 /* If the hardware itself detected stereo, also return
853 stereo as an available subchannel */
854 if (V4L2_TUNER_MODE_STEREO == t->audmode)
855 t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
856 }
814 return; 857 return;
815} 858}
816 859
@@ -847,6 +890,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
847 break; 890 break;
848 case WW_BG: 891 case WW_BG:
849 case WW_DK: 892 case WW_DK:
893 case WW_M:
850 case WW_I: 894 case WW_I:
851 case WW_L: 895 case WW_L:
852 if (1 == core->use_nicam) { 896 if (1 == core->use_nicam) {
@@ -872,20 +916,18 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
872 set_audio_standard_A2(core, EN_A2_FORCE_MONO1); 916 set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
873 } else { 917 } else {
874 /* TODO: Add A2 autodection */ 918 /* TODO: Add A2 autodection */
919 mask = 0x3f;
875 switch (mode) { 920 switch (mode) {
876 case V4L2_TUNER_MODE_MONO: 921 case V4L2_TUNER_MODE_MONO:
877 case V4L2_TUNER_MODE_LANG1: 922 case V4L2_TUNER_MODE_LANG1:
878 set_audio_standard_A2(core, 923 ctl = EN_A2_FORCE_MONO1;
879 EN_A2_FORCE_MONO1);
880 break; 924 break;
881 case V4L2_TUNER_MODE_LANG2: 925 case V4L2_TUNER_MODE_LANG2:
882 set_audio_standard_A2(core, 926 ctl = EN_A2_FORCE_MONO2;
883 EN_A2_FORCE_MONO2);
884 break; 927 break;
885 case V4L2_TUNER_MODE_STEREO: 928 case V4L2_TUNER_MODE_STEREO:
886 case V4L2_TUNER_MODE_LANG1_LANG2: 929 case V4L2_TUNER_MODE_LANG1_LANG2:
887 set_audio_standard_A2(core, 930 ctl = EN_A2_FORCE_STEREO;
888 EN_A2_FORCE_STEREO);
889 break; 931 break;
890 } 932 }
891 } 933 }
@@ -932,24 +974,39 @@ int cx88_audio_thread(void *data)
932 break; 974 break;
933 try_to_freeze(); 975 try_to_freeze();
934 976
935 /* just monitor the audio status for now ... */ 977 switch (core->tvaudio) {
936 memset(&t, 0, sizeof(t)); 978 case WW_BG:
937 cx88_get_stereo(core, &t); 979 case WW_DK:
938 980 case WW_M:
939 if (UNSET != core->audiomode_manual) 981 case WW_I:
940 /* manually set, don't do anything. */ 982 case WW_L:
941 continue; 983 if (core->use_nicam)
942 984 goto hw_autodetect;
943 /* monitor signal */ 985
944 if (t.rxsubchans & V4L2_TUNER_SUB_STEREO) 986 /* just monitor the audio status for now ... */
945 mode = V4L2_TUNER_MODE_STEREO; 987 memset(&t, 0, sizeof(t));
946 else 988 cx88_get_stereo(core, &t);
947 mode = V4L2_TUNER_MODE_MONO; 989
948 if (mode == core->audiomode_current) 990 if (UNSET != core->audiomode_manual)
949 continue; 991 /* manually set, don't do anything. */
950 992 continue;
951 /* automatically switch to best available mode */ 993
952 cx88_set_stereo(core, mode, 0); 994 /* monitor signal and set stereo if available */
995 if (t.rxsubchans & V4L2_TUNER_SUB_STEREO)
996 mode = V4L2_TUNER_MODE_STEREO;
997 else
998 mode = V4L2_TUNER_MODE_MONO;
999 if (mode == core->audiomode_current)
1000 continue;
1001 /* automatically switch to best available mode */
1002 cx88_set_stereo(core, mode, 0);
1003 break;
1004 default:
1005hw_autodetect:
1006 /* stereo autodetection is supported by hardware so
1007 we don't need to do it manually. Do nothing. */
1008 break;
1009 }
953 } 1010 }
954 1011
955 dprintk("cx88: tvaudio thread exiting\n"); 1012 dprintk("cx88: tvaudio thread exiting\n");