Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] b2c2: Add option to skip the first 6 pid filters

The flexcop bridge chip has two banks of hardware pid filters -
an initial 6, and on some chip revisions an additional bank of 32.

A bug is present on the initial 6 - when changing transponders
one of two PAT packets from the old transponder would be included
in the initial packets from the new transponder. This usually
transpired with userspace programs complaining about services
missing, because they are seeing a PAT that they would not be
expecting. Running in full TS mode does not exhibit this problem,
neither does using just the additional 32.

This patch adds in an option to not use the inital 6 and solely use
just the additional 32, and enables this option for the SkystarS2
card. Other cards can be added as required if they also have
this bug.

Signed-off-by: Jemma Denson <jdenson@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>

authored by

Jemma Denson and committed by
Mauro Carvalho Chehab
d3525b63 25e057fd

+18 -2
+1
drivers/media/common/b2c2/flexcop-common.h
··· 91 91 int feedcount; 92 92 int pid_filtering; 93 93 int fullts_streaming_state; 94 + int skip_6_hw_pid_filter; 94 95 95 96 /* bus specific callbacks */ 96 97 flexcop_ibi_value(*read_ibi_reg) (struct flexcop_device *,
+3
drivers/media/common/b2c2/flexcop-fe-tuner.c
··· 652 652 } 653 653 info("ISL6421 successfully attached."); 654 654 655 + if (fc->has_32_hw_pid_filter) 656 + fc->skip_6_hw_pid_filter = 1; 657 + 655 658 return 1; 656 659 } 657 660 #else
+14 -2
drivers/media/common/b2c2/flexcop-hw-filter.c
··· 117 117 deb_ts("setting pid: %5d %04x at index %d '%s'\n", 118 118 pid, pid, index, onoff ? "on" : "off"); 119 119 120 + /* First 6 can be buggy - skip over them if option set */ 121 + if (fc->skip_6_hw_pid_filter) 122 + index += 6; 123 + 120 124 /* We could use bit magic here to reduce source code size. 121 125 * I decided against it, but to use the real register names */ 122 126 switch (index) { ··· 174 170 int flexcop_pid_feed_control(struct flexcop_device *fc, 175 171 struct dvb_demux_feed *dvbdmxfeed, int onoff) 176 172 { 177 - int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32; 173 + int max_pid_filter = 6; 174 + 175 + max_pid_filter -= 6 * fc->skip_6_hw_pid_filter; 176 + max_pid_filter += 32 * fc->has_32_hw_pid_filter; 178 177 179 178 fc->feedcount += onoff ? 1 : -1; /* the number of PIDs/Feed currently requested */ 180 179 if (dvbdmxfeed->index >= max_pid_filter) ··· 224 217 { 225 218 int i; 226 219 flexcop_ibi_value v; 227 - for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++) 220 + int max_pid_filter = 6; 221 + 222 + max_pid_filter -= 6 * fc->skip_6_hw_pid_filter; 223 + max_pid_filter += 32 * fc->has_32_hw_pid_filter; 224 + 225 + for (i = 0; i < max_pid_filter; i++) 228 226 flexcop_pid_control(fc, i, 0x1fff, 0); 229 227 230 228 flexcop_pid_group_filter(fc, 0, 0x1fe0);