Skip to contentSkip to conversation

af9015/af9013 full pid filtering

PATCH In review Malcolm Priestley 2 participants 4 messages Nov 12, 2011 Media (V4L/DVB)

lore
Share & tools
lore
#0 lore raw

PATCH 3/7 af9015/af9013 full pid filtering

Allowing the pid to be enabled seems to suppress corrupted stream packets from the first frontend. This is mainly caused by other high speed devices on the usb bus.

Full pid filtering on all frontends.
no_pid is defaulted to on.
TS frame size it limited to 21, this because if we are only filtering pid 0000, it takes too long to fill up the buffer when tuning or scanning.

---
 drivers/media/dvb/dvb-usb/af9015.c |   82 ++++++++++++++++++++++++++++++------
 1 files changed, 69 insertions(+), 13 deletions(-)
drivers/media/dvb/dvb-usb/af9015.c +69 -13
index eb464c8..c9da2aa 100644
@@ -41,6 +41,9 @@ static int dvb_usb_af9015_remote;
 module_param_named(remote, dvb_usb_af9015_remote, int, 0644);
 MODULE_PARM_DESC(remote, "select remote");
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+static int no_pid_filter;
+module_param_named(no_pid, no_pid_filter, int, 0644);
+MODULE_PARM_DESC(no_pid, "set default 0=on 1=off");
 
 static DEFINE_MUTEX(af9015_usb_mutex);
 
@@ -223,6 +226,25 @@ static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
 	return af9015_ctrl_msg(d, &req);
 }
 
+static int af9015_write_fe(struct dvb_usb_device *d, u8 adap, u16 reg,
+	u8 val)
+{
+	int ret;
+	u8 addr1 = af9015_af9013_config[1].demod_address;
+
+	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+		return -EAGAIN;
+
+	if (adap == 0)
+		ret = af9015_write_reg(d, reg, val);
+	else
+		ret = af9015_write_reg_i2c(d, addr1, reg, val);
+
+
+	mutex_unlock(&d->i2c_mutex);
+	return ret;
+}
+
 static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
 	u8 *val)
 {
@@ -407,6 +429,9 @@ static int af9015_init_endpoint(struct dvb_usb_device *d)
 #define TS_USB20_PACKET_COUNT      87
 #define TS_USB20_FRAME_SIZE       (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT)
 
+#define TS_PID_PACKET_COUNT	21
+#define TS_PID_FRAME_SIZE	(TS_PACKET_SIZE*TS_PID_PACKET_COUNT)
+
 #define TS_USB11_PACKET_COUNT       5
 #define TS_USB11_FRAME_SIZE       (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT)
 
@@ -420,6 +445,8 @@ static int af9015_init_endpoint(struct dvb_usb_device *d)
 		frame_size = TS_USB20_FRAME_SIZE/4;
 		packet_size = TS_USB20_MAX_PACKET_SIZE/4;
 	}
+	if (!no_pid_filter)
+		frame_size = TS_PID_FRAME_SIZE/4;
 
 	ret = af9015_set_reg_bit(d, 0xd507, 2); /* assert EP4 reset */
 	if (ret)
@@ -635,9 +662,9 @@ static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
 	deb_info("%s: onoff:%d\n", __func__, onoff);
 
 	if (onoff)
-		ret = af9015_set_reg_bit(adap->dev, 0xd503, 0);
+		ret = af9015_write_fe(adap->dev, adap->id, 0xd503, 0x1);
 	else
-		ret = af9015_clear_reg_bit(adap->dev, 0xd503, 0);
+		ret = af9015_write_fe(adap->dev, adap->id, 0xd503, 0x0);
 
 	return ret;
 }
@@ -651,16 +678,15 @@ static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
 	deb_info("%s: set pid filter, index %d, pid %x, onoff %d\n",
 		__func__, index, pid, onoff);
 
-	ret = af9015_write_reg(adap->dev, 0xd505, (pid & 0xff));
+	ret = af9015_write_fe(adap->dev, adap->id, 0xd505, (pid & 0xff));
 	if (ret)
 		goto error;
-
-	ret = af9015_write_reg(adap->dev, 0xd506, (pid >> 8));
+	ret = af9015_write_fe(adap->dev, adap->id, 0xd506, (pid >> 8));
 	if (ret)
 		goto error;
 
 	idx = ((index & 0x1f) | (1 << 5));
-	ret = af9015_write_reg(adap->dev, 0xd504, idx);
+	ret = af9015_write_fe(adap->dev, adap->id, 0xd504, idx);
 
 error:
 	return ret;
@@ -859,15 +885,20 @@ static int af9015_read_config(struct usb_device *udev,
 	/* Set adapter0 buffer size according to USB port speed, adapter1 buffer
 	   size can be static because it is enabled only USB2.0 */
 	/* USB1.1 set smaller buffersize and disable 2nd adapter */
-	if (udev->speed == USB_SPEED_FULL) {
-		props->adapter[0].fe[0].stream.u.bulk.buffersize
-			= TS_USB11_FRAME_SIZE;
+	for (i = 0; i < props->num_adapters; i++) {
+		if (udev->speed == USB_SPEED_FULL) {
+			props->adapter[i].fe[0].stream.u.bulk.buffersize
+				= TS_USB11_FRAME_SIZE;
 		/* disable 2nd adapter because we don't have
 			   PID-filters */
 		af9015_config.dual_mode = 0;
-	} else {
-		props->adapter[0].fe[0].stream.u.bulk.buffersize
-			= TS_USB20_FRAME_SIZE;
+		break;
+		} else if (!no_pid_filter)
+			props->adapter[i].fe[0].stream.u.bulk.buffersize
+				= TS_PID_FRAME_SIZE;
+		else
+			props->adapter[i].fe[0].stream.u.bulk.buffersize
+				= TS_USB20_FRAME_SIZE;
 	}
 
 	if (af9015_config.dual_mode) {
@@ -1001,7 +1032,7 @@ static int af9015_identify_state(struct usb_device *udev,
 				 struct dvb_usb_device_description **desc,
 				 int *cold)
 {
-	int ret;
+	int ret, i;
 	u8 reply;
 	struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply};
 
@@ -1019,6 +1050,12 @@ static int af9015_identify_state(struct usb_device *udev,
 	else
 		*cold = 1;
 
+	for (i = 0; i < props->num_adapters; i++) {
+		if (!no_pid_filter)
+			props->adapter[i].fe[0].caps |=
+				DVB_USB_ADAP_NEED_PID_FILTERING;
+	}
+
 	return ret;
 }
 
@@ -1324,6 +1361,12 @@ static struct dvb_usb_device_properties af9015_properties[] = {
 			{
 			.num_frontends = 1,
 			.fe = {{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER |
+				DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+
+				.pid_filter_count = 32,
+				.pid_filter       = af9015_pid_filter,
+				.pid_filter_ctrl  = af9015_pid_filter_ctrl,
 				.frontend_attach =
 					af9015_af9013_frontend_attach,
 				.tuner_attach    = af9015_tuner_attach,
@@ -1458,6 +1501,12 @@ static struct dvb_usb_device_properties af9015_properties[] = {
 			{
 			.num_frontends = 1,
 			.fe = {{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER |
+				DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+
+				.pid_filter_count = 32,
+				.pid_filter       = af9015_pid_filter,
+				.pid_filter_ctrl  = af9015_pid_filter_ctrl,
 				.frontend_attach =
 					af9015_af9013_frontend_attach,
 				.tuner_attach    = af9015_tuner_attach,
@@ -1581,6 +1630,13 @@ static struct dvb_usb_device_properties af9015_properties[] = {
 			{
 			.num_frontends = 1,
 			.fe = {{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER |
+				DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+
+				.pid_filter_count = 32,
+				.pid_filter       = af9015_pid_filter,
+				.pid_filter_ctrl  = af9015_pid_filter_ctrl,
+
 				.frontend_attach =
 					af9015_af9013_frontend_attach,
 				.tuner_attach    = af9015_tuner_attach,
Signature · 1 line
1.7.5.4
#1 lore raw
Quoted 9 lines · Malcolm Priestley

Allowing the pid to be enabled seems to suppress corrupted stream packets from the first frontend. This is mainly caused by other high speed devices on the usb bus.

Full pid filtering on all frontends.
no_pid is defaulted to on.
TS frame size it limited to 21, this because if we are only filtering pid 0000, it takes too long to fill up the buffer when tuning or scanning.

Could you explain that?
PID filter should not be used unless there is no USB1.1 or it is forced using DVB USB module param. PID filter is controlled by DVB USB.

Logic about PID-filtering was done way that it disables 2nd FE when USB1.1 is used since I did not see way to set PID filtering for FE1 and without filtering stream is too wide for USB1.1.

Does that patch force PID filter always on or what?

Antti

Signature · 1 line
http://palosaari.fi/
#2 lore raw
Quoted 5 lines · Antti Palosaari
Quoted 4 lines · Malcolm Priestley

Allowing the pid to be enabled seems to suppress corrupted stream packets from the first frontend. This is mainly caused by other high speed devices on the usb bus.

Quoted 7 lines
Quoted 5 lines

Full pid filtering on all frontends.
no_pid is defaulted to on.
TS frame size it limited to 21, this because if we are only filtering pid 0000, it takes too long to fill up the buffer when tuning or scanning.

Could you explain that?

Pid 0 transport stream id on some channels is not transmitted very often.

It needs to be transmitted at least 84 times to fill the devices buffer up which is typically 5 or 6 seconds, enough for a time out.

The pid packet size is reduced to 21 bring it back in tolerance of most applications.

Quoted 2 lines

PID filter should not be used unless there is no USB1.1 or it is forced using DVB USB module param. PID filter is controlled by DVB USB.

Why?

It can't be module controlled?

Quoted 4 lines

Logic about PID-filtering was done way that it disables 2nd FE when USB1.1 is used since I did not see way to set PID filtering for FE1 and without filtering stream is too wide for USB1.1.

The second frontend is still disabled in USB1.1

Quoted 2 lines

Does that patch force PID filter always on or what?

Yes, and why not?

Pid filtering has it uses in usb 2.0 and works very well. Low power and low bus usage.

Regards

Malcolm

#3 lore raw
Quoted 8 lines · Malcolm Priestley
Quoted 1 line · Antti Palosaari

Does that patch force PID filter always on or what?

Yes, and why not?

Pid filtering has it uses in usb 2.0 and works very well. Low power and low bus usage.

Actually, I do not know the exact reason. That is how it was defaulted by DVB USB framework.

Sending whole TS to Kernel demux still sounds good idea for my ears.

Is there anyone who can say why we send whole TS to Kernel demux in case of USB2.0 ?

Antti

Signature · 1 line
http://palosaari.fi/