diff options
Diffstat (limited to 'drivers/media/dvb/ttpci/av7110.c')
-rw-r--r-- | drivers/media/dvb/ttpci/av7110.c | 251 |
1 files changed, 153 insertions, 98 deletions
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 8e33a850e13e..e4c6e87f6c5d 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -116,13 +116,18 @@ static int av7110_num = 0; | |||
116 | 116 | ||
117 | static void init_av7110_av(struct av7110 *av7110) | 117 | static void init_av7110_av(struct av7110 *av7110) |
118 | { | 118 | { |
119 | int ret; | ||
119 | struct saa7146_dev *dev = av7110->dev; | 120 | struct saa7146_dev *dev = av7110->dev; |
120 | 121 | ||
121 | /* set internal volume control to maximum */ | 122 | /* set internal volume control to maximum */ |
122 | av7110->adac_type = DVB_ADAC_TI; | 123 | av7110->adac_type = DVB_ADAC_TI; |
123 | av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right); | 124 | ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right); |
125 | if (ret < 0) | ||
126 | printk("dvb-ttpci:cannot set internal volume to maximum:%d\n",ret); | ||
124 | 127 | ||
125 | av7710_set_video_mode(av7110, vidmode); | 128 | ret = av7710_set_video_mode(av7110, vidmode); |
129 | if (ret < 0) | ||
130 | printk("dvb-ttpci:cannot set video mode:%d\n",ret); | ||
126 | 131 | ||
127 | /* handle different card types */ | 132 | /* handle different card types */ |
128 | /* remaining inits according to card and frontend type */ | 133 | /* remaining inits according to card and frontend type */ |
@@ -156,8 +161,12 @@ static void init_av7110_av(struct av7110 *av7110) | |||
156 | 161 | ||
157 | if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) { | 162 | if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) { |
158 | // switch DVB SCART on | 163 | // switch DVB SCART on |
159 | av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0); | 164 | ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0); |
160 | av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1); | 165 | if (ret < 0) |
166 | printk("dvb-ttpci:cannot switch on SCART(Main):%d\n",ret); | ||
167 | ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1); | ||
168 | if (ret < 0) | ||
169 | printk("dvb-ttpci:cannot switch on SCART(AD):%d\n",ret); | ||
161 | if (rgb_on && | 170 | if (rgb_on && |
162 | (av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) { | 171 | (av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) { |
163 | saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16 | 172 | saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16 |
@@ -165,8 +174,12 @@ static void init_av7110_av(struct av7110 *av7110) | |||
165 | } | 174 | } |
166 | } | 175 | } |
167 | 176 | ||
168 | av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right); | 177 | ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right); |
169 | av7110_setup_irc_config(av7110, 0); | 178 | if (ret < 0) |
179 | printk("dvb-ttpci:cannot set volume :%d\n",ret); | ||
180 | ret = av7110_setup_irc_config(av7110, 0); | ||
181 | if (ret < 0) | ||
182 | printk("dvb-ttpci:cannot setup irc config :%d\n",ret); | ||
170 | } | 183 | } |
171 | 184 | ||
172 | static void recover_arm(struct av7110 *av7110) | 185 | static void recover_arm(struct av7110 *av7110) |
@@ -258,8 +271,9 @@ static int arm_thread(void *data) | |||
258 | * | 271 | * |
259 | * If we want to support multiple controls we would have to do much more... | 272 | * If we want to support multiple controls we would have to do much more... |
260 | */ | 273 | */ |
261 | void av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config) | 274 | int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config) |
262 | { | 275 | { |
276 | int ret = 0; | ||
263 | static struct av7110 *last; | 277 | static struct av7110 *last; |
264 | 278 | ||
265 | dprintk(4, "%p\n", av7110); | 279 | dprintk(4, "%p\n", av7110); |
@@ -270,9 +284,10 @@ void av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config) | |||
270 | last = av7110; | 284 | last = av7110; |
271 | 285 | ||
272 | if (av7110) { | 286 | if (av7110) { |
273 | av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config); | 287 | ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config); |
274 | av7110->ir_config = ir_config; | 288 | av7110->ir_config = ir_config; |
275 | } | 289 | } |
290 | return ret; | ||
276 | } | 291 | } |
277 | 292 | ||
278 | static void (*irc_handler)(u32); | 293 | static void (*irc_handler)(u32); |
@@ -765,13 +780,14 @@ static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, | |||
765 | pcrpid, vpid, apid, ttpid, subpid); | 780 | pcrpid, vpid, apid, ttpid, subpid); |
766 | } | 781 | } |
767 | 782 | ||
768 | void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, | 783 | int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, |
769 | u16 subpid, u16 pcrpid) | 784 | u16 subpid, u16 pcrpid) |
770 | { | 785 | { |
786 | int ret = 0; | ||
771 | dprintk(4, "%p\n", av7110); | 787 | dprintk(4, "%p\n", av7110); |
772 | 788 | ||
773 | if (down_interruptible(&av7110->pid_mutex)) | 789 | if (down_interruptible(&av7110->pid_mutex)) |
774 | return; | 790 | return -ERESTARTSYS; |
775 | 791 | ||
776 | if (!(vpid & 0x8000)) | 792 | if (!(vpid & 0x8000)) |
777 | av7110->pids[DMX_PES_VIDEO] = vpid; | 793 | av7110->pids[DMX_PES_VIDEO] = vpid; |
@@ -786,10 +802,11 @@ void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, | |||
786 | 802 | ||
787 | if (av7110->fe_synced) { | 803 | if (av7110->fe_synced) { |
788 | pcrpid = av7110->pids[DMX_PES_PCR]; | 804 | pcrpid = av7110->pids[DMX_PES_PCR]; |
789 | SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid); | 805 | ret = SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid); |
790 | } | 806 | } |
791 | 807 | ||
792 | up(&av7110->pid_mutex); | 808 | up(&av7110->pid_mutex); |
809 | return ret; | ||
793 | } | 810 | } |
794 | 811 | ||
795 | 812 | ||
@@ -832,11 +849,13 @@ static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter) | |||
832 | ret = av7110_fw_request(av7110, buf, 20, &handle, 1); | 849 | ret = av7110_fw_request(av7110, buf, 20, &handle, 1); |
833 | if (ret != 0 || handle >= 32) { | 850 | if (ret != 0 || handle >= 32) { |
834 | printk("dvb-ttpci: %s error buf %04x %04x %04x %04x " | 851 | printk("dvb-ttpci: %s error buf %04x %04x %04x %04x " |
835 | "ret %x handle %04x\n", | 852 | "ret %d handle %04x\n", |
836 | __FUNCTION__, buf[0], buf[1], buf[2], buf[3], | 853 | __FUNCTION__, buf[0], buf[1], buf[2], buf[3], |
837 | ret, handle); | 854 | ret, handle); |
838 | dvbdmxfilter->hw_handle = 0xffff; | 855 | dvbdmxfilter->hw_handle = 0xffff; |
839 | return -1; | 856 | if (!ret) |
857 | ret = -1; | ||
858 | return ret; | ||
840 | } | 859 | } |
841 | 860 | ||
842 | av7110->handle2filter[handle] = dvbdmxfilter; | 861 | av7110->handle2filter[handle] = dvbdmxfilter; |
@@ -859,7 +878,7 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter) | |||
859 | if (handle >= 32) { | 878 | if (handle >= 32) { |
860 | printk("%s tried to stop invalid filter %04x, filter type = %x\n", | 879 | printk("%s tried to stop invalid filter %04x, filter type = %x\n", |
861 | __FUNCTION__, handle, dvbdmxfilter->type); | 880 | __FUNCTION__, handle, dvbdmxfilter->type); |
862 | return 0; | 881 | return -EINVAL; |
863 | } | 882 | } |
864 | 883 | ||
865 | av7110->handle2filter[handle] = NULL; | 884 | av7110->handle2filter[handle] = NULL; |
@@ -873,18 +892,20 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter) | |||
873 | "resp %04x %04x pid %d\n", | 892 | "resp %04x %04x pid %d\n", |
874 | __FUNCTION__, buf[0], buf[1], buf[2], ret, | 893 | __FUNCTION__, buf[0], buf[1], buf[2], ret, |
875 | answ[0], answ[1], dvbdmxfilter->feed->pid); | 894 | answ[0], answ[1], dvbdmxfilter->feed->pid); |
876 | ret = -1; | 895 | if (!ret) |
896 | ret = -1; | ||
877 | } | 897 | } |
878 | return ret; | 898 | return ret; |
879 | } | 899 | } |
880 | 900 | ||
881 | 901 | ||
882 | static void dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed) | 902 | static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed) |
883 | { | 903 | { |
884 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | 904 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; |
885 | struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv; | 905 | struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv; |
886 | u16 *pid = dvbdmx->pids, npids[5]; | 906 | u16 *pid = dvbdmx->pids, npids[5]; |
887 | int i; | 907 | int i; |
908 | int ret = 0; | ||
888 | 909 | ||
889 | dprintk(4, "%p\n", av7110); | 910 | dprintk(4, "%p\n", av7110); |
890 | 911 | ||
@@ -893,36 +914,49 @@ static void dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed) | |||
893 | npids[i] = (pid[i]&0x8000) ? 0 : pid[i]; | 914 | npids[i] = (pid[i]&0x8000) ? 0 : pid[i]; |
894 | if ((i == 2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) { | 915 | if ((i == 2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) { |
895 | npids[i] = 0; | 916 | npids[i] = 0; |
896 | ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); | 917 | ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); |
897 | StartHWFilter(dvbdmxfeed->filter); | 918 | if (!ret) |
898 | return; | 919 | ret = StartHWFilter(dvbdmxfeed->filter); |
920 | return ret; | ||
921 | } | ||
922 | if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4) { | ||
923 | ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); | ||
924 | if (ret) | ||
925 | return ret; | ||
899 | } | 926 | } |
900 | if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4) | ||
901 | ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); | ||
902 | 927 | ||
903 | if (dvbdmxfeed->pes_type < 2 && npids[0]) | 928 | if (dvbdmxfeed->pes_type < 2 && npids[0]) |
904 | if (av7110->fe_synced) | 929 | if (av7110->fe_synced) |
905 | av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); | 930 | { |
931 | ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); | ||
932 | if (ret) | ||
933 | return ret; | ||
934 | } | ||
906 | 935 | ||
907 | if ((dvbdmxfeed->ts_type & TS_PACKET)) { | 936 | if ((dvbdmxfeed->ts_type & TS_PACKET)) { |
908 | if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000)) | 937 | if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000)) |
909 | av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed); | 938 | ret = av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed); |
910 | if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000)) | 939 | if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000)) |
911 | av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed); | 940 | ret = av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed); |
912 | } | 941 | } |
942 | return ret; | ||
913 | } | 943 | } |
914 | 944 | ||
915 | static void dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed) | 945 | static int dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed) |
916 | { | 946 | { |
917 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | 947 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; |
918 | struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv; | 948 | struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv; |
919 | u16 *pid = dvbdmx->pids, npids[5]; | 949 | u16 *pid = dvbdmx->pids, npids[5]; |
920 | int i; | 950 | int i; |
921 | 951 | ||
952 | int ret = 0; | ||
953 | |||
922 | dprintk(4, "%p\n", av7110); | 954 | dprintk(4, "%p\n", av7110); |
923 | 955 | ||
924 | if (dvbdmxfeed->pes_type <= 1) { | 956 | if (dvbdmxfeed->pes_type <= 1) { |
925 | av7110_av_stop(av7110, dvbdmxfeed->pes_type ? RP_VIDEO : RP_AUDIO); | 957 | ret = av7110_av_stop(av7110, dvbdmxfeed->pes_type ? RP_VIDEO : RP_AUDIO); |
958 | if (ret) | ||
959 | return ret; | ||
926 | if (!av7110->rec_mode) | 960 | if (!av7110->rec_mode) |
927 | dvbdmx->recording = 0; | 961 | dvbdmx->recording = 0; |
928 | if (!av7110->playing) | 962 | if (!av7110->playing) |
@@ -933,24 +967,27 @@ static void dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed) | |||
933 | switch (i) { | 967 | switch (i) { |
934 | case 2: //teletext | 968 | case 2: //teletext |
935 | if (dvbdmxfeed->ts_type & TS_PACKET) | 969 | if (dvbdmxfeed->ts_type & TS_PACKET) |
936 | StopHWFilter(dvbdmxfeed->filter); | 970 | ret = StopHWFilter(dvbdmxfeed->filter); |
937 | npids[2] = 0; | 971 | npids[2] = 0; |
938 | break; | 972 | break; |
939 | case 0: | 973 | case 0: |
940 | case 1: | 974 | case 1: |
941 | case 4: | 975 | case 4: |
942 | if (!pids_off) | 976 | if (!pids_off) |
943 | return; | 977 | return 0; |
944 | npids[i] = (pid[i]&0x8000) ? 0 : pid[i]; | 978 | npids[i] = (pid[i]&0x8000) ? 0 : pid[i]; |
945 | break; | 979 | break; |
946 | } | 980 | } |
947 | ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); | 981 | if (!ret) |
982 | ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); | ||
983 | return ret; | ||
948 | } | 984 | } |
949 | 985 | ||
950 | static int av7110_start_feed(struct dvb_demux_feed *feed) | 986 | static int av7110_start_feed(struct dvb_demux_feed *feed) |
951 | { | 987 | { |
952 | struct dvb_demux *demux = feed->demux; | 988 | struct dvb_demux *demux = feed->demux; |
953 | struct av7110 *av7110 = demux->priv; | 989 | struct av7110 *av7110 = demux->priv; |
990 | int ret = 0; | ||
954 | 991 | ||
955 | dprintk(4, "%p\n", av7110); | 992 | dprintk(4, "%p\n", av7110); |
956 | 993 | ||
@@ -971,21 +1008,22 @@ static int av7110_start_feed(struct dvb_demux_feed *feed) | |||
971 | !(demux->pids[1] & 0x8000)) { | 1008 | !(demux->pids[1] & 0x8000)) { |
972 | dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); | 1009 | dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); |
973 | dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); | 1010 | dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); |
974 | av7110_av_start_play(av7110,RP_AV); | 1011 | ret = av7110_av_start_play(av7110,RP_AV); |
975 | demux->playing = 1; | 1012 | if (!ret) |
1013 | demux->playing = 1; | ||
976 | } | 1014 | } |
977 | break; | 1015 | break; |
978 | default: | 1016 | default: |
979 | dvb_feed_start_pid(feed); | 1017 | ret = dvb_feed_start_pid(feed); |
980 | break; | 1018 | break; |
981 | } | 1019 | } |
982 | } else if ((feed->ts_type & TS_PACKET) && | 1020 | } else if ((feed->ts_type & TS_PACKET) && |
983 | (demux->dmx.frontend->source != DMX_MEMORY_FE)) { | 1021 | (demux->dmx.frontend->source != DMX_MEMORY_FE)) { |
984 | StartHWFilter(feed->filter); | 1022 | ret = StartHWFilter(feed->filter); |
985 | } | 1023 | } |
986 | } | 1024 | } |
987 | 1025 | ||
988 | if (feed->type == DMX_TYPE_SEC) { | 1026 | else if (feed->type == DMX_TYPE_SEC) { |
989 | int i; | 1027 | int i; |
990 | 1028 | ||
991 | for (i = 0; i < demux->filternum; i++) { | 1029 | for (i = 0; i < demux->filternum; i++) { |
@@ -996,12 +1034,15 @@ static int av7110_start_feed(struct dvb_demux_feed *feed) | |||
996 | if (demux->filter[i].filter.parent != &feed->feed.sec) | 1034 | if (demux->filter[i].filter.parent != &feed->feed.sec) |
997 | continue; | 1035 | continue; |
998 | demux->filter[i].state = DMX_STATE_GO; | 1036 | demux->filter[i].state = DMX_STATE_GO; |
999 | if (demux->dmx.frontend->source != DMX_MEMORY_FE) | 1037 | if (demux->dmx.frontend->source != DMX_MEMORY_FE) { |
1000 | StartHWFilter(&demux->filter[i]); | 1038 | ret = StartHWFilter(&demux->filter[i]); |
1039 | if (ret) | ||
1040 | break; | ||
1041 | } | ||
1001 | } | 1042 | } |
1002 | } | 1043 | } |
1003 | 1044 | ||
1004 | return 0; | 1045 | return ret; |
1005 | } | 1046 | } |
1006 | 1047 | ||
1007 | 1048 | ||
@@ -1009,7 +1050,7 @@ static int av7110_stop_feed(struct dvb_demux_feed *feed) | |||
1009 | { | 1050 | { |
1010 | struct dvb_demux *demux = feed->demux; | 1051 | struct dvb_demux *demux = feed->demux; |
1011 | struct av7110 *av7110 = demux->priv; | 1052 | struct av7110 *av7110 = demux->priv; |
1012 | 1053 | int i, rc, ret = 0; | |
1013 | dprintk(4, "%p\n", av7110); | 1054 | dprintk(4, "%p\n", av7110); |
1014 | 1055 | ||
1015 | if (feed->type == DMX_TYPE_TS) { | 1056 | if (feed->type == DMX_TYPE_TS) { |
@@ -1022,26 +1063,29 @@ static int av7110_stop_feed(struct dvb_demux_feed *feed) | |||
1022 | } | 1063 | } |
1023 | if (feed->ts_type & TS_DECODER && | 1064 | if (feed->ts_type & TS_DECODER && |
1024 | feed->pes_type < DMX_TS_PES_OTHER) { | 1065 | feed->pes_type < DMX_TS_PES_OTHER) { |
1025 | dvb_feed_stop_pid(feed); | 1066 | ret = dvb_feed_stop_pid(feed); |
1026 | } else | 1067 | } else |
1027 | if ((feed->ts_type & TS_PACKET) && | 1068 | if ((feed->ts_type & TS_PACKET) && |
1028 | (demux->dmx.frontend->source != DMX_MEMORY_FE)) | 1069 | (demux->dmx.frontend->source != DMX_MEMORY_FE)) |
1029 | StopHWFilter(feed->filter); | 1070 | ret = StopHWFilter(feed->filter); |
1030 | } | 1071 | } |
1031 | 1072 | ||
1032 | if (feed->type == DMX_TYPE_SEC) { | 1073 | if (!ret && feed->type == DMX_TYPE_SEC) { |
1033 | int i; | 1074 | for (i = 0; i<demux->filternum; i++) { |
1034 | |||
1035 | for (i = 0; i<demux->filternum; i++) | ||
1036 | if (demux->filter[i].state == DMX_STATE_GO && | 1075 | if (demux->filter[i].state == DMX_STATE_GO && |
1037 | demux->filter[i].filter.parent == &feed->feed.sec) { | 1076 | demux->filter[i].filter.parent == &feed->feed.sec) { |
1038 | demux->filter[i].state = DMX_STATE_READY; | 1077 | demux->filter[i].state = DMX_STATE_READY; |
1039 | if (demux->dmx.frontend->source != DMX_MEMORY_FE) | 1078 | if (demux->dmx.frontend->source != DMX_MEMORY_FE) { |
1040 | StopHWFilter(&demux->filter[i]); | 1079 | rc = StopHWFilter(&demux->filter[i]); |
1080 | if (!ret) | ||
1081 | ret = rc; | ||
1082 | /* keep going, stop as many filters as possible */ | ||
1083 | } | ||
1084 | } | ||
1041 | } | 1085 | } |
1042 | } | 1086 | } |
1043 | 1087 | ||
1044 | return 0; | 1088 | return ret; |
1045 | } | 1089 | } |
1046 | 1090 | ||
1047 | 1091 | ||
@@ -1093,7 +1137,7 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num, | |||
1093 | ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4); | 1137 | ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4); |
1094 | if (ret) { | 1138 | if (ret) { |
1095 | printk(KERN_ERR "%s: av7110_fw_request error\n", __FUNCTION__); | 1139 | printk(KERN_ERR "%s: av7110_fw_request error\n", __FUNCTION__); |
1096 | return -EIO; | 1140 | return ret; |
1097 | } | 1141 | } |
1098 | dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n", | 1142 | dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n", |
1099 | fwstc[0], fwstc[1], fwstc[2], fwstc[3]); | 1143 | fwstc[0], fwstc[1], fwstc[2], fwstc[3]); |
@@ -1119,18 +1163,14 @@ static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | |||
1119 | 1163 | ||
1120 | switch (tone) { | 1164 | switch (tone) { |
1121 | case SEC_TONE_ON: | 1165 | case SEC_TONE_ON: |
1122 | Set22K(av7110, 1); | 1166 | return Set22K(av7110, 1); |
1123 | break; | ||
1124 | 1167 | ||
1125 | case SEC_TONE_OFF: | 1168 | case SEC_TONE_OFF: |
1126 | Set22K(av7110, 0); | 1169 | return Set22K(av7110, 0); |
1127 | break; | ||
1128 | 1170 | ||
1129 | default: | 1171 | default: |
1130 | return -EINVAL; | 1172 | return -EINVAL; |
1131 | } | 1173 | } |
1132 | |||
1133 | return 0; | ||
1134 | } | 1174 | } |
1135 | 1175 | ||
1136 | static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe, | 1176 | static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe, |
@@ -1138,9 +1178,7 @@ static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe, | |||
1138 | { | 1178 | { |
1139 | struct av7110* av7110 = fe->dvb->priv; | 1179 | struct av7110* av7110 = fe->dvb->priv; |
1140 | 1180 | ||
1141 | av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1); | 1181 | return av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1); |
1142 | |||
1143 | return 0; | ||
1144 | } | 1182 | } |
1145 | 1183 | ||
1146 | static int av7110_diseqc_send_burst(struct dvb_frontend* fe, | 1184 | static int av7110_diseqc_send_burst(struct dvb_frontend* fe, |
@@ -1148,9 +1186,7 @@ static int av7110_diseqc_send_burst(struct dvb_frontend* fe, | |||
1148 | { | 1186 | { |
1149 | struct av7110* av7110 = fe->dvb->priv; | 1187 | struct av7110* av7110 = fe->dvb->priv; |
1150 | 1188 | ||
1151 | av7110_diseqc_send(av7110, 0, NULL, minicmd); | 1189 | return av7110_diseqc_send(av7110, 0, NULL, minicmd); |
1152 | |||
1153 | return 0; | ||
1154 | } | 1190 | } |
1155 | 1191 | ||
1156 | /* simplified code from budget-core.c */ | 1192 | /* simplified code from budget-core.c */ |
@@ -1992,76 +2028,85 @@ static struct l64781_config grundig_29504_401_config = { | |||
1992 | 2028 | ||
1993 | 2029 | ||
1994 | 2030 | ||
1995 | static void av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status) | 2031 | static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status) |
1996 | { | 2032 | { |
2033 | int ret = 0; | ||
1997 | int synced = (status & FE_HAS_LOCK) ? 1 : 0; | 2034 | int synced = (status & FE_HAS_LOCK) ? 1 : 0; |
1998 | 2035 | ||
1999 | av7110->fe_status = status; | 2036 | av7110->fe_status = status; |
2000 | 2037 | ||
2001 | if (av7110->fe_synced == synced) | 2038 | if (av7110->fe_synced == synced) |
2002 | return; | 2039 | return 0; |
2003 | |||
2004 | av7110->fe_synced = synced; | ||
2005 | 2040 | ||
2006 | if (av7110->playing) | 2041 | if (av7110->playing) |
2007 | return; | 2042 | return 0; |
2008 | 2043 | ||
2009 | if (down_interruptible(&av7110->pid_mutex)) | 2044 | if (down_interruptible(&av7110->pid_mutex)) |
2010 | return; | 2045 | return -ERESTARTSYS; |
2011 | 2046 | ||
2012 | if (av7110->fe_synced) { | 2047 | if (synced) { |
2013 | SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO], | 2048 | ret = SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO], |
2014 | av7110->pids[DMX_PES_AUDIO], | 2049 | av7110->pids[DMX_PES_AUDIO], |
2015 | av7110->pids[DMX_PES_TELETEXT], 0, | 2050 | av7110->pids[DMX_PES_TELETEXT], 0, |
2016 | av7110->pids[DMX_PES_PCR]); | 2051 | av7110->pids[DMX_PES_PCR]); |
2017 | av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); | 2052 | if (!ret) |
2053 | ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); | ||
2018 | } else { | 2054 | } else { |
2019 | SetPIDs(av7110, 0, 0, 0, 0, 0); | 2055 | ret = SetPIDs(av7110, 0, 0, 0, 0, 0); |
2020 | av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0); | 2056 | if (!ret) { |
2021 | av7110_wait_msgstate(av7110, GPMQBusy); | 2057 | ret = av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0); |
2058 | if (!ret) | ||
2059 | ret = av7110_wait_msgstate(av7110, GPMQBusy); | ||
2060 | } | ||
2022 | } | 2061 | } |
2023 | 2062 | ||
2063 | if (!ret) | ||
2064 | av7110->fe_synced = synced; | ||
2065 | |||
2024 | up(&av7110->pid_mutex); | 2066 | up(&av7110->pid_mutex); |
2067 | return ret; | ||
2025 | } | 2068 | } |
2026 | 2069 | ||
2027 | static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 2070 | static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
2028 | { | 2071 | { |
2029 | struct av7110* av7110 = fe->dvb->priv; | 2072 | struct av7110* av7110 = fe->dvb->priv; |
2030 | av7110_fe_lock_fix(av7110, 0); | 2073 | |
2031 | return av7110->fe_set_frontend(fe, params); | 2074 | int ret = av7110_fe_lock_fix(av7110, 0); |
2075 | if (!ret) | ||
2076 | ret = av7110->fe_set_frontend(fe, params); | ||
2077 | return ret; | ||
2032 | } | 2078 | } |
2033 | 2079 | ||
2034 | static int av7110_fe_init(struct dvb_frontend* fe) | 2080 | static int av7110_fe_init(struct dvb_frontend* fe) |
2035 | { | 2081 | { |
2036 | struct av7110* av7110 = fe->dvb->priv; | 2082 | struct av7110* av7110 = fe->dvb->priv; |
2037 | 2083 | ||
2038 | av7110_fe_lock_fix(av7110, 0); | 2084 | int ret = av7110_fe_lock_fix(av7110, 0); |
2039 | return av7110->fe_init(fe); | 2085 | if (!ret) |
2086 | ret = av7110->fe_init(fe); | ||
2087 | return ret; | ||
2040 | } | 2088 | } |
2041 | 2089 | ||
2042 | static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status) | 2090 | static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status) |
2043 | { | 2091 | { |
2044 | struct av7110* av7110 = fe->dvb->priv; | 2092 | struct av7110* av7110 = fe->dvb->priv; |
2045 | int ret; | ||
2046 | 2093 | ||
2047 | /* call the real implementation */ | 2094 | /* call the real implementation */ |
2048 | ret = av7110->fe_read_status(fe, status); | 2095 | int ret = av7110->fe_read_status(fe, status); |
2049 | if (ret) | 2096 | if (!ret) |
2050 | return ret; | 2097 | if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK)) |
2051 | 2098 | ret = av7110_fe_lock_fix(av7110, *status); | |
2052 | if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK)) { | 2099 | return ret; |
2053 | av7110_fe_lock_fix(av7110, *status); | ||
2054 | } | ||
2055 | |||
2056 | return 0; | ||
2057 | } | 2100 | } |
2058 | 2101 | ||
2059 | static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe) | 2102 | static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe) |
2060 | { | 2103 | { |
2061 | struct av7110* av7110 = fe->dvb->priv; | 2104 | struct av7110* av7110 = fe->dvb->priv; |
2062 | 2105 | ||
2063 | av7110_fe_lock_fix(av7110, 0); | 2106 | int ret = av7110_fe_lock_fix(av7110, 0); |
2064 | return av7110->fe_diseqc_reset_overload(fe); | 2107 | if (!ret) |
2108 | ret = av7110->fe_diseqc_reset_overload(fe); | ||
2109 | return ret; | ||
2065 | } | 2110 | } |
2066 | 2111 | ||
2067 | static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe, | 2112 | static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe, |
@@ -2069,40 +2114,50 @@ static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe, | |||
2069 | { | 2114 | { |
2070 | struct av7110* av7110 = fe->dvb->priv; | 2115 | struct av7110* av7110 = fe->dvb->priv; |
2071 | 2116 | ||
2072 | av7110_fe_lock_fix(av7110, 0); | 2117 | int ret = av7110_fe_lock_fix(av7110, 0); |
2073 | return av7110->fe_diseqc_send_master_cmd(fe, cmd); | 2118 | if (!ret) |
2119 | ret = av7110->fe_diseqc_send_master_cmd(fe, cmd); | ||
2120 | return ret; | ||
2074 | } | 2121 | } |
2075 | 2122 | ||
2076 | static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) | 2123 | static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) |
2077 | { | 2124 | { |
2078 | struct av7110* av7110 = fe->dvb->priv; | 2125 | struct av7110* av7110 = fe->dvb->priv; |
2079 | 2126 | ||
2080 | av7110_fe_lock_fix(av7110, 0); | 2127 | int ret = av7110_fe_lock_fix(av7110, 0); |
2081 | return av7110->fe_diseqc_send_burst(fe, minicmd); | 2128 | if (!ret) |
2129 | ret = av7110->fe_diseqc_send_burst(fe, minicmd); | ||
2130 | return ret; | ||
2082 | } | 2131 | } |
2083 | 2132 | ||
2084 | static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | 2133 | static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) |
2085 | { | 2134 | { |
2086 | struct av7110* av7110 = fe->dvb->priv; | 2135 | struct av7110* av7110 = fe->dvb->priv; |
2087 | 2136 | ||
2088 | av7110_fe_lock_fix(av7110, 0); | 2137 | int ret = av7110_fe_lock_fix(av7110, 0); |
2089 | return av7110->fe_set_tone(fe, tone); | 2138 | if (!ret) |
2139 | ret = av7110->fe_set_tone(fe, tone); | ||
2140 | return ret; | ||
2090 | } | 2141 | } |
2091 | 2142 | ||
2092 | static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | 2143 | static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) |
2093 | { | 2144 | { |
2094 | struct av7110* av7110 = fe->dvb->priv; | 2145 | struct av7110* av7110 = fe->dvb->priv; |
2095 | 2146 | ||
2096 | av7110_fe_lock_fix(av7110, 0); | 2147 | int ret = av7110_fe_lock_fix(av7110, 0); |
2097 | return av7110->fe_set_voltage(fe, voltage); | 2148 | if (!ret) |
2149 | ret = av7110->fe_set_voltage(fe, voltage); | ||
2150 | return ret; | ||
2098 | } | 2151 | } |
2099 | 2152 | ||
2100 | static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned int cmd) | 2153 | static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned int cmd) |
2101 | { | 2154 | { |
2102 | struct av7110* av7110 = fe->dvb->priv; | 2155 | struct av7110* av7110 = fe->dvb->priv; |
2103 | 2156 | ||
2104 | av7110_fe_lock_fix(av7110, 0); | 2157 | int ret = av7110_fe_lock_fix(av7110, 0); |
2105 | return av7110->fe_dishnetwork_send_legacy_command(fe, cmd); | 2158 | if (!ret) |
2159 | ret = av7110->fe_dishnetwork_send_legacy_command(fe, cmd); | ||
2160 | return ret; | ||
2106 | } | 2161 | } |
2107 | 2162 | ||
2108 | static u8 read_pwm(struct av7110* av7110) | 2163 | static u8 read_pwm(struct av7110* av7110) |