diff mbox

em28xx device mode detection based on endpoints

Message ID d9def9db0905230805h5258a9b6h7920a5bd4ce62e7c@mail.gmail.com (mailing list archive)
State Changes Requested
Delegated to: Douglas Landgraf
Headers show

Commit Message

Markus Rechberger May 23, 2009, 3:05 p.m. UTC
Hi,

On Sat, May 23, 2009 at 4:49 PM, Markus Rechberger
<mrechberger@gmail.com> wrote:
> On Sat, May 23, 2009 at 4:04 PM, Markus Rechberger
> <mrechberger@gmail.com> wrote:
>> Hi,
>>
>> for em28xx devices the device node detection can be based on the
>> encoded endpoint address, for example EP 0x81 (USB IN, Interrupt),
>> 0x82 (analog video EP), 0x83 (analog audio ep), 0x84 (mpeg-ts input
>> EP).
>> It is not necessary that digital TV devices have a frontend, the
>> em28xx chip only specifies an MPEG-TS input EP.
>>
>> Following patch adds a check based on the Endpoints, although it might
>> be extended that all devices match the possible devicenodes based on
>> the endpoints, currently the driver registers an analog TV node by
>> default for all unknown devices which is not necessarily correct, this
>> patch disables the ATV node if no analog TV endpoint is available.
>>
>

attached patch fixes the deregistration, as well loads the em28xx-dvb
module automatically as soon as an MPEG-TS endpoint was found.

Signed-off-by: Markus Rechberger <mrechberger@gmail.com>

best regards,
Markus

Comments

Devin Heitmueller June 1, 2009, 3:19 p.m. UTC | #1
On Sat, May 23, 2009 at 11:05 AM, Markus Rechberger
<mrechberger@gmail.com> wrote:
> Hi,
>
> On Sat, May 23, 2009 at 4:49 PM, Markus Rechberger
> <mrechberger@gmail.com> wrote:
>> On Sat, May 23, 2009 at 4:04 PM, Markus Rechberger
>> <mrechberger@gmail.com> wrote:
>>> Hi,
>>>
>>> for em28xx devices the device node detection can be based on the
>>> encoded endpoint address, for example EP 0x81 (USB IN, Interrupt),
>>> 0x82 (analog video EP), 0x83 (analog audio ep), 0x84 (mpeg-ts input
>>> EP).
>>> It is not necessary that digital TV devices have a frontend, the
>>> em28xx chip only specifies an MPEG-TS input EP.
>>>
>>> Following patch adds a check based on the Endpoints, although it might
>>> be extended that all devices match the possible devicenodes based on
>>> the endpoints, currently the driver registers an analog TV node by
>>> default for all unknown devices which is not necessarily correct, this
>>> patch disables the ATV node if no analog TV endpoint is available.
>>>
>>
>
> attached patch fixes the deregistration, as well loads the em28xx-dvb
> module automatically as soon as an MPEG-TS endpoint was found.
>
> Signed-off-by: Markus Rechberger <mrechberger@gmail.com>
>
> best regards,
> Markus
>

Hello Markus,

I spent some time reviewing this patch, and the patch's content does
not seem to match your description of its functionality.  Further,
this patch appears to be a combination of a number of several
different changes, rather than being broken into separate patches.

First off, I totally agree that the analog subsystem should not be
loaded on devices such as em287[0-4].  I was going to do this work
(using the chip id to determine analog support) but just had not had a
chance to doing the necessary testing to ensure it did not break
anything.

The patch appears to be primarily for devices that are not supported
in the kernel.  In fact, the logic as written *only* gets used for
unknown devices.  Further, the code that doesn't create the frontend
device has no application in the kernel.  All devices currently in the
kernel make use of the dvb frontend interface, so there is no
practical application to loading the driver and setting up the isoc
handlers but blocking access to the dvb frontend device.

Aside from the code that selectively disables analog support, the
patch only seems to advance compatibility with your userland em28xx
framework while providing no benefit to the in-kernel driver.

Regarding the possibility of custom firmware, we currently do not have
any devices in the in-kernel driver that make use of custom firmware.
If you could tell me how to check for custom firmware versus the
default vendor firmware, I could potentially do a patch that uses the
vendor registers unless custom firmware is installed, at which point
we could have custom logic (such as using the endpoint definition).
However, given there are no such devices in-kernel, this is not a high
priority as far as I am concerned.

For what it's worth, I did add an additional patch to allow the user
to disable the 480Mbps check via a modprobe option (to avoid a
regression for any of your existing customers), and I will be checking
in the code to properly compute the isoc size for em2874/em2884 based
on the vendor registers (even though there are currently no supported
devices in the kernel that require it currently).  However, I do not
believe the patch you have proposed is appropriate for inclusion in
the mainline kernel.

Regards,

Devin
Markus Rechberger June 1, 2009, 3:32 p.m. UTC | #2
On Mon, Jun 1, 2009 at 5:19 PM, Devin Heitmueller
<dheitmueller@kernellabs.com> wrote:
> On Sat, May 23, 2009 at 11:05 AM, Markus Rechberger
> <mrechberger@gmail.com> wrote:
>> Hi,
>>
>> On Sat, May 23, 2009 at 4:49 PM, Markus Rechberger
>> <mrechberger@gmail.com> wrote:
>>> On Sat, May 23, 2009 at 4:04 PM, Markus Rechberger
>>> <mrechberger@gmail.com> wrote:
>>>> Hi,
>>>>
>>>> for em28xx devices the device node detection can be based on the
>>>> encoded endpoint address, for example EP 0x81 (USB IN, Interrupt),
>>>> 0x82 (analog video EP), 0x83 (analog audio ep), 0x84 (mpeg-ts input
>>>> EP).
>>>> It is not necessary that digital TV devices have a frontend, the
>>>> em28xx chip only specifies an MPEG-TS input EP.
>>>>
>>>> Following patch adds a check based on the Endpoints, although it might
>>>> be extended that all devices match the possible devicenodes based on
>>>> the endpoints, currently the driver registers an analog TV node by
>>>> default for all unknown devices which is not necessarily correct, this
>>>> patch disables the ATV node if no analog TV endpoint is available.
>>>>
>>>
>>
>> attached patch fixes the deregistration, as well loads the em28xx-dvb
>> module automatically as soon as an MPEG-TS endpoint was found.
>>
>> Signed-off-by: Markus Rechberger <mrechberger@gmail.com>
>>
>> best regards,
>> Markus
>>
>
> Hello Markus,
>
> I spent some time reviewing this patch, and the patch's content does
> not seem to match your description of its functionality.  Further,
> this patch appears to be a combination of a number of several
> different changes, rather than being broken into separate patches.
>

what doesn't match the description?

> First off, I totally agree that the analog subsystem should not be
> loaded on devices such as em287[0-4].  I was going to do this work
> (using the chip id to determine analog support) but just had not had a
> chance to doing the necessary testing to ensure it did not break
> anything.
>
> The patch appears to be primarily for devices that are not supported
> in the kernel.  In fact, the logic as written *only* gets used for
> unknown devices.  Further, the code that doesn't create the frontend
> device has no application in the kernel.

this is wrong, there are devices without a tuner frontend, mpeg
encoders (as written earlier already)
The em28xx chip only defines an mpeg-ts input, whenever a customer
wants to add a frontend or
mpeg encoder is up to him.

> All devices currently in the
> kernel make use of the dvb frontend interface, so there is no
> practical application to loading the driver and setting up the isoc
> handlers but blocking access to the dvb frontend device.
>
> Aside from the code that selectively disables analog support, the
> patch only seems to advance compatibility with your userland em28xx
> framework while providing no benefit to the in-kernel driver.
>

There's also a tuner customization option in the kernel module (eg set tuner ID
manually). This more or less can be seen as a cleanup, further patches would
come up. The next step would be to add customization support for various chips
this would allow me to just drop in a demod for certain customers who are aware
that they are not allowed to forward their modules. The application is mainly
for business customers who don't ship to endusers and make up a direct deal
with eg. Micronas. There is no reason to punish one company because the other
one denies it.

> Regarding the possibility of custom firmware, we currently do not have
> any devices in the in-kernel driver that make use of custom firmware.
> If you could tell me how to check for custom firmware versus the
> default vendor firmware, I could potentially do a patch that uses the
> vendor registers unless custom firmware is installed, at which point
> we could have custom logic (such as using the endpoint definition).
> However, given there are no such devices in-kernel, this is not a high
> priority as far as I am concerned.
>

endpoint size as mentioned already, old firmware shows up the endpoint size of 0
newer one shows up a certain size.

> For what it's worth, I did add an additional patch to allow the user
> to disable the 480Mbps check via a modprobe option (to avoid a
> regression for any of your existing customers)

All my customers are using the other kernel driver since the existing
one is too limited right now

best regards,
Markus
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Douglas Schilling Landgraf June 1, 2009, 4:04 p.m. UTC | #3
Hello Devin,

On Mon, 1 Jun 2009 11:19:22 -0400
Devin Heitmueller <dheitmueller@kernellabs.com> wrote:

> On Sat, May 23, 2009 at 11:05 AM, Markus Rechberger
> <mrechberger@gmail.com> wrote:
> > Hi,
> >
> > On Sat, May 23, 2009 at 4:49 PM, Markus Rechberger
> > <mrechberger@gmail.com> wrote:
> >> On Sat, May 23, 2009 at 4:04 PM, Markus Rechberger
> >> <mrechberger@gmail.com> wrote:
> >>> Hi,
> >>>
> >>> for em28xx devices the device node detection can be based on the
> >>> encoded endpoint address, for example EP 0x81 (USB IN, Interrupt),
> >>> 0x82 (analog video EP), 0x83 (analog audio ep), 0x84 (mpeg-ts
> >>> input EP).
> >>> It is not necessary that digital TV devices have a frontend, the
> >>> em28xx chip only specifies an MPEG-TS input EP.
> >>>
> >>> Following patch adds a check based on the Endpoints, although it
> >>> might be extended that all devices match the possible devicenodes
> >>> based on the endpoints, currently the driver registers an analog
> >>> TV node by default for all unknown devices which is not
> >>> necessarily correct, this patch disables the ATV node if no
> >>> analog TV endpoint is available.
> >>>
> >>
> >
> > attached patch fixes the deregistration, as well loads the
> > em28xx-dvb module automatically as soon as an MPEG-TS endpoint was
> > found.
> >
> > Signed-off-by: Markus Rechberger <mrechberger@gmail.com>
> >
> > best regards,
> > Markus
> >
> 
> Hello Markus,
> 
> I spent some time reviewing this patch, and the patch's content does
> not seem to match your description of its functionality.  Further,
> this patch appears to be a combination of a number of several
> different changes, rather than being broken into separate patches.
> 
> First off, I totally agree that the analog subsystem should not be
> loaded on devices such as em287[0-4].  I was going to do this work
> (using the chip id to determine analog support) but just had not had a
> chance to doing the necessary testing to ensure it did not break
> anything.
> 
> The patch appears to be primarily for devices that are not supported
> in the kernel.  In fact, the logic as written *only* gets used for
> unknown devices.  Further, the code that doesn't create the frontend
> device has no application in the kernel.  All devices currently in the
> kernel make use of the dvb frontend interface, so there is no
> practical application to loading the driver and setting up the isoc
> handlers but blocking access to the dvb frontend device.
> 
> Aside from the code that selectively disables analog support, the
> patch only seems to advance compatibility with your userland em28xx
> framework while providing no benefit to the in-kernel driver.
>
> Regarding the possibility of custom firmware, we currently do not have
> any devices in the in-kernel driver that make use of custom firmware.
> If you could tell me how to check for custom firmware versus the
> default vendor firmware, I could potentially do a patch that uses the
> vendor registers unless custom firmware is installed, at which point
> we could have custom logic (such as using the endpoint definition).
> However, given there are no such devices in-kernel, this is not a high
> priority as far as I am concerned.
> 
> For what it's worth, I did add an additional patch to allow the user
> to disable the 480Mbps check via a modprobe option (to avoid a
> regression for any of your existing customers), and I will be checking
> in the code to properly compute the isoc size for em2874/em2884 based
> on the vendor registers (even though there are currently no supported
> devices in the kernel that require it currently).  However, I do not
> believe the patch you have proposed is appropriate for inclusion in
> the mainline kernel.

Agree with you Devin. 

Also, the patch does a lot of changes instead of break it in several
patches.

Cheers,
Douglas
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Markus Rechberger June 1, 2009, 4:07 p.m. UTC | #4
On Mon, Jun 1, 2009 at 6:04 PM, Douglas Schilling Landgraf
<dougsland@gmail.com> wrote:
> Hello Devin,
>
> On Mon, 1 Jun 2009 11:19:22 -0400
> Devin Heitmueller <dheitmueller@kernellabs.com> wrote:
>
>> On Sat, May 23, 2009 at 11:05 AM, Markus Rechberger
>> <mrechberger@gmail.com> wrote:
>> > Hi,
>> >
>> > On Sat, May 23, 2009 at 4:49 PM, Markus Rechberger
>> > <mrechberger@gmail.com> wrote:
>> >> On Sat, May 23, 2009 at 4:04 PM, Markus Rechberger
>> >> <mrechberger@gmail.com> wrote:
>> >>> Hi,
>> >>>
>> >>> for em28xx devices the device node detection can be based on the
>> >>> encoded endpoint address, for example EP 0x81 (USB IN, Interrupt),
>> >>> 0x82 (analog video EP), 0x83 (analog audio ep), 0x84 (mpeg-ts
>> >>> input EP).
>> >>> It is not necessary that digital TV devices have a frontend, the
>> >>> em28xx chip only specifies an MPEG-TS input EP.
>> >>>
>> >>> Following patch adds a check based on the Endpoints, although it
>> >>> might be extended that all devices match the possible devicenodes
>> >>> based on the endpoints, currently the driver registers an analog
>> >>> TV node by default for all unknown devices which is not
>> >>> necessarily correct, this patch disables the ATV node if no
>> >>> analog TV endpoint is available.
>> >>>
>> >>
>> >
>> > attached patch fixes the deregistration, as well loads the
>> > em28xx-dvb module automatically as soon as an MPEG-TS endpoint was
>> > found.
>> >
>> > Signed-off-by: Markus Rechberger <mrechberger@gmail.com>
>> >
>> > best regards,
>> > Markus
>> >
>>
>> Hello Markus,
>>
>> I spent some time reviewing this patch, and the patch's content does
>> not seem to match your description of its functionality.  Further,
>> this patch appears to be a combination of a number of several
>> different changes, rather than being broken into separate patches.
>>
>> First off, I totally agree that the analog subsystem should not be
>> loaded on devices such as em287[0-4].  I was going to do this work
>> (using the chip id to determine analog support) but just had not had a
>> chance to doing the necessary testing to ensure it did not break
>> anything.
>>
>> The patch appears to be primarily for devices that are not supported
>> in the kernel.  In fact, the logic as written *only* gets used for
>> unknown devices.  Further, the code that doesn't create the frontend
>> device has no application in the kernel.  All devices currently in the
>> kernel make use of the dvb frontend interface, so there is no
>> practical application to loading the driver and setting up the isoc
>> handlers but blocking access to the dvb frontend device.
>>
>> Aside from the code that selectively disables analog support, the
>> patch only seems to advance compatibility with your userland em28xx
>> framework while providing no benefit to the in-kernel driver.
>>
>> Regarding the possibility of custom firmware, we currently do not have
>> any devices in the in-kernel driver that make use of custom firmware.
>> If you could tell me how to check for custom firmware versus the
>> default vendor firmware, I could potentially do a patch that uses the
>> vendor registers unless custom firmware is installed, at which point
>> we could have custom logic (such as using the endpoint definition).
>> However, given there are no such devices in-kernel, this is not a high
>> priority as far as I am concerned.
>>
>> For what it's worth, I did add an additional patch to allow the user
>> to disable the 480Mbps check via a modprobe option (to avoid a
>> regression for any of your existing customers), and I will be checking
>> in the code to properly compute the isoc size for em2874/em2884 based
>> on the vendor registers (even though there are currently no supported
>> devices in the kernel that require it currently).  However, I do not
>> believe the patch you have proposed is appropriate for inclusion in
>> the mainline kernel.
>
> Agree with you Devin.
>
> Also, the patch does a lot of changes instead of break it in several
> patches.
>

do you want smaller patches?

regards,
Markus
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Mauro Carvalho Chehab June 1, 2009, 4:31 p.m. UTC | #5
Em Mon, 1 Jun 2009 18:07:24 +0200
Markus Rechberger <mrechberger@gmail.com> escreveu:

> >> I spent some time reviewing this patch, and the patch's content does
> >> not seem to match your description of its functionality.  Further,
> >> this patch appears to be a combination of a number of several
> >> different changes, rather than being broken into separate patches.
> >>
> >> First off, I totally agree that the analog subsystem should not be
> >> loaded on devices such as em287[0-4].  I was going to do this work
> >> (using the chip id to determine analog support) but just had not had a
> >> chance to doing the necessary testing to ensure it did not break
> >> anything.
> >>
> >> The patch appears to be primarily for devices that are not supported
> >> in the kernel.  In fact, the logic as written *only* gets used for
> >> unknown devices.  Further, the code that doesn't create the frontend
> >> device has no application in the kernel.  All devices currently in the
> >> kernel make use of the dvb frontend interface, so there is no
> >> practical application to loading the driver and setting up the isoc
> >> handlers but blocking access to the dvb frontend device.
> >>
> >> Aside from the code that selectively disables analog support, the
> >> patch only seems to advance compatibility with your userland em28xx
> >> framework while providing no benefit to the in-kernel driver.
> >>
> >> Regarding the possibility of custom firmware, we currently do not have
> >> any devices in the in-kernel driver that make use of custom firmware.
> >> If you could tell me how to check for custom firmware versus the
> >> default vendor firmware, I could potentially do a patch that uses the
> >> vendor registers unless custom firmware is installed, at which point
> >> we could have custom logic (such as using the endpoint definition).
> >> However, given there are no such devices in-kernel, this is not a high
> >> priority as far as I am concerned.
> >>
> >> For what it's worth, I did add an additional patch to allow the user
> >> to disable the 480Mbps check via a modprobe option (to avoid a
> >> regression for any of your existing customers), and I will be checking
> >> in the code to properly compute the isoc size for em2874/em2884 based
> >> on the vendor registers (even though there are currently no supported
> >> devices in the kernel that require it currently).  However, I do not
> >> believe the patch you have proposed is appropriate for inclusion in
> >> the mainline kernel.
> >
> > Agree with you Devin.
> >
> > Also, the patch does a lot of changes instead of break it in several
> > patches.
> >
> 
> do you want smaller patches?

Markus,

Please break it into smaller patches, being one patch per change. This makes
easier for me to review and for people to comment each one of the addressed issues.



Cheers,
Mauro
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff -r 315bc4b65b4f linux/drivers/media/video/em28xx/em28xx-cards.c
--- a/linux/drivers/media/video/em28xx/em28xx-cards.c	Sun May 17 12:28:55 2009 +0000
+++ b/linux/drivers/media/video/em28xx/em28xx-cards.c	Sat May 23 17:03:00 2009 +0200
@@ -1596,9 +1596,13 @@ 
 /* Since em28xx_pre_card_setup() requires a proper dev->model,
  * this won't work for boards with generic PCI IDs
  */
-void em28xx_pre_card_setup(struct em28xx *dev)
+static int em28xx_pre_card_setup(struct em28xx *dev,
+				struct usb_interface *intf)
 {
 	int rc;
+	int i;
+	struct usb_host_interface *host_interface = &intf->altsetting[0];
+	int select_alt;
 
 	em28xx_set_model(dev);
 
@@ -1647,6 +1651,18 @@ 
 		}
 	}
 
+	/* this is for protecting wrong devices against the rest of the control
+	   commands
+	   for example:
+	   $ cd /sys/bus/usb/drivers/em28xx
+	   $ echo "1234 1234" > new_id
+	*/
+
+
+	if (dev->model == EM2800_BOARD_UNKNOWN &&
+		dev->chip_id >= CHIP_ID_EM2883)
+		dev->lock_control_commands = 1;
+
 	/* Prepopulate cached GPO register content */
 	rc = em28xx_read_reg(dev, dev->reg_gpo_num);
 	if (rc >= 0)
@@ -1658,8 +1674,66 @@ 
 	em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed);
 	msleep(50);
 
+	if (dev->model != EM2800_BOARD_UNKNOWN)
+		/* defaulting to have the same behaviour as we always had */
+		dev->has_atv = 1;
+
 	/* request some modules */
 	switch (dev->model) {
+	case EM2800_BOARD_UNKNOWN:
+		if (dev->chip_id < CHIP_ID_EM2820) {
+			/* defaulting again .. */
+			dev->has_atv = 1;
+			break;
+		}
+
+		em28xx_info("Probing device modes (ignore all upcoming"
+			     "errors)\n");
+		em28xx_info("Found endpoints: %d\n",
+				host_interface->desc.bNumEndpoints);
+		em28xx_info("Found alternate: %d\n", dev->num_alt);
+
+		switch (dev->num_alt) {
+		case 2:
+			select_alt = 1;
+			break;
+		case 8:
+			select_alt = 7;
+			break;
+		default:
+			/* guaranteed no EETI TV device */
+			return -EINVAL;
+		}
+		for (i = 0; i < host_interface->desc.bNumEndpoints; i++) {
+			em28xx_info("Alternate setting %d [%02x]\n",
+				select_alt,
+				intf->altsetting[select_alt].endpoint[i].
+					desc.bEndpointAddress);
+
+			switch (intf->altsetting[select_alt].endpoint[i].
+				desc.bEndpointAddress) {
+			case EM28XX_INTERRUPT_EP:
+				/* currently not implemented */
+				break;
+			case EM28XX_ANALOG_VIDEO_EP:
+				/* registered by default already which
+				   is bogus */
+				em28xx_info("FOUND ATV EP\n");
+				dev->has_atv = 1;
+				break;
+			case EM28XX_ANALOG_AUDIO_EP:
+				em28xx_info("Found PCMAUDIO EP\n");
+				dev->has_alsa_audio = 1;
+				break;
+			case EM28XX_DIGITALTV_EP:
+				em28xx_info("Found MPEG-TS EP\n");
+				dev->has_dvb = 1;
+				break;
+			default:
+				return -EINVAL;
+			}
+		}
+		break;
 	case EM2861_BOARD_PLEXTOR_PX_TV100U:
 		/* FIXME guess */
 		/* Turn on analog audio output */
@@ -1748,6 +1822,7 @@ 
 
 	/* Unlock device */
 	em28xx_set_mode(dev, EM28XX_SUSPEND);
+	return 0;
 }
 
 static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
@@ -2119,7 +2194,7 @@ 
 	else if (dev->has_alsa_audio)
 		request_module("em28xx-alsa");
 
-	if (dev->board.has_dvb)
+	if (dev->board.has_dvb || dev->has_dvb)
 		request_module("em28xx-dvb");
 }
 
@@ -2191,8 +2266,12 @@ 
 	dev->em28xx_write_regs_req = em28xx_write_regs_req;
 	dev->em28xx_read_reg_req = em28xx_read_reg_req;
 	dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800;
+	dev->has_dvb = dev->board.has_dvb;
 
-	em28xx_pre_card_setup(dev);
+	retval = em28xx_pre_card_setup(dev, interface);
+
+	if (retval)
+		return retval;
 
 	if (!dev->board.is_em2800) {
 		/* Sets I2C speed to 100 KHz */
@@ -2265,16 +2344,19 @@ 
 
 	em28xx_add_into_devlist(dev);
 
-	retval = em28xx_register_analog_devices(dev);
-	if (retval < 0) {
-		em28xx_release_resources(dev);
-		goto fail_reg_devices;
+	if (dev->has_atv) {
+		retval = em28xx_register_analog_devices(dev);
+		if (retval < 0) {
+			em28xx_release_resources(dev);
+			goto fail_reg_devices;
+		}
 	}
 
 	em28xx_init_extension(dev);
 
-	/* Save some power by putting tuner to sleep */
-	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby);
+	if (dev->has_atv)
+		/* Save some power by putting tuner to sleep */
+		v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby);
 
 	return 0;
 
diff -r 315bc4b65b4f linux/drivers/media/video/em28xx/em28xx-core.c
--- a/linux/drivers/media/video/em28xx/em28xx-core.c	Sun May 17 12:28:55 2009 +0000
+++ b/linux/drivers/media/video/em28xx/em28xx-core.c	Sat May 23 17:03:00 2009 +0200
@@ -68,7 +68,12 @@ 
 				   char *buf, int len)
 {
 	int ret;
-	int pipe = usb_rcvctrlpipe(dev->udev, 0);
+	int pipe;
+
+	if (dev->lock_control_commands)
+		return -EINVAL;
+
+	pipe = usb_rcvctrlpipe(dev->udev, 0);
 
 	if (dev->state & DEV_DISCONNECTED)
 		return -ENODEV;
@@ -143,7 +148,12 @@ 
 				 int len)
 {
 	int ret;
-	int pipe = usb_sndctrlpipe(dev->udev, 0);
+	int pipe;
+
+	if (dev->lock_control_commands)
+		return -EINVAL;
+
+	pipe = usb_sndctrlpipe(dev->udev, 0);
 
 	if (dev->state & DEV_DISCONNECTED)
 		return -ENODEV;
diff -r 315bc4b65b4f linux/drivers/media/video/em28xx/em28xx-dvb.c
--- a/linux/drivers/media/video/em28xx/em28xx-dvb.c	Sun May 17 12:28:55 2009 +0000
+++ b/linux/drivers/media/video/em28xx/em28xx-dvb.c	Sat May 23 17:03:00 2009 +0200
@@ -301,17 +301,20 @@ 
 		goto fail_adapter;
 	}
 
-	/* Ensure all frontends negotiate bus access */
-	dvb->frontend->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl;
+	if (dev->has_frontend)
+		/* Ensure all frontends negotiate bus access */
+		dvb->frontend->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl;
 
 	dvb->adapter.priv = dev;
 
-	/* register frontend */
-	result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
-	if (result < 0) {
-		printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n",
-		       dev->name, result);
-		goto fail_frontend;
+	if (dev->has_frontend) {
+		/* register frontend */
+		result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
+		if (result < 0) {
+			printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n",
+					dev->name, result);
+			goto fail_frontend;
+		}
 	}
 
 	/* register demux stuff */
@@ -349,19 +352,23 @@ 
 		goto fail_fe_hw;
 	}
 
-	dvb->fe_mem.source = DMX_MEMORY_FE;
-	result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
-	if (result < 0) {
-		printk(KERN_WARNING "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n",
-		       dev->name, result);
-		goto fail_fe_mem;
-	}
+	if (dev->has_frontend) {
+		dvb->fe_mem.source = DMX_MEMORY_FE;
+		result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx,
+							&dvb->fe_mem);
+		if (result < 0) {
+			printk(KERN_WARNING "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n",
+					dev->name, result);
+			goto fail_fe_mem;
+		}
 
-	result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
-	if (result < 0) {
-		printk(KERN_WARNING "%s: connect_frontend failed (errno = %d)\n",
-		       dev->name, result);
-		goto fail_fe_conn;
+		result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx,
+								&dvb->fe_hw);
+		if (result < 0) {
+			printk(KERN_WARNING "%s: connect_frontend failed (errno = %d)\n",
+					dev->name, result);
+			goto fail_fe_conn;
+		}
 	}
 
 	/* register network adapter */
@@ -369,17 +376,22 @@ 
 	return 0;
 
 fail_fe_conn:
-	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
+	if (dev->has_frontend)
+		dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
 fail_fe_mem:
-	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
+	if (dev->has_frontend)
+		dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
 fail_fe_hw:
 	dvb_dmxdev_release(&dvb->dmxdev);
 fail_dmxdev:
 	dvb_dmx_release(&dvb->demux);
 fail_dmx:
-	dvb_unregister_frontend(dvb->frontend);
+	if (dev->has_frontend)
+		dvb_unregister_frontend(dvb->frontend);
 fail_frontend:
-	dvb_frontend_detach(dvb->frontend);
+	if (dev->has_frontend)
+		dvb_frontend_detach(dvb->frontend);
+
 	dvb_unregister_adapter(&dvb->adapter);
 fail_adapter:
 	return result;
@@ -388,12 +400,17 @@ 
 static void unregister_dvb(struct em28xx_dvb *dvb)
 {
 	dvb_net_release(&dvb->net);
-	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
-	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
+	if (dvb->frontend) {
+		dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
+		dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
+	}
 	dvb_dmxdev_release(&dvb->dmxdev);
 	dvb_dmx_release(&dvb->demux);
-	dvb_unregister_frontend(dvb->frontend);
-	dvb_frontend_detach(dvb->frontend);
+	if (dvb->frontend) {
+		dvb_unregister_frontend(dvb->frontend);
+		dvb_frontend_detach(dvb->frontend);
+		dvb->frontend = NULL;
+	}
 	dvb_unregister_adapter(&dvb->adapter);
 }
 
@@ -403,8 +420,9 @@ 
 	int result = 0;
 	struct em28xx_dvb *dvb;
 
-	if (!dev->board.has_dvb) {
+	if (!dev->board.has_dvb && dev->has_dvb == 0) {
 		/* This device does not support the extension */
+		printk(KERN_INFO "em28xx_dvb: This device does not support the DVB extension\n");
 		return 0;
 	}
 
@@ -415,6 +433,7 @@ 
 		return -ENOMEM;
 	}
 	dev->dvb = dvb;
+	dev->has_frontend = 1; /* defaulting for old devices */
 
 	em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
 	/* init frontend */
@@ -465,21 +484,26 @@ 
 		}
 		break;
 #endif
+	case EM2800_BOARD_UNKNOWN:
+		dev->has_frontend = 0;
+		break;
 	default:
 		printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
 				" isn't supported yet\n",
 		       dev->name);
 		break;
 	}
-	if (NULL == dvb->frontend) {
+	if (NULL == dvb->frontend && dev->has_frontend == 1) {
 		printk(KERN_ERR
 		       "%s/2: frontend initialization failed\n",
 		       dev->name);
 		result = -EINVAL;
 		goto out_free;
 	}
-	/* define general-purpose callback pointer */
-	dvb->frontend->callback = em28xx_tuner_callback;
+
+	if (dev->has_frontend)
+		/* define general-purpose callback pointer */
+		dvb->frontend->callback = em28xx_tuner_callback;
 
 	/* register everything */
 	result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev);
@@ -500,7 +524,7 @@ 
 
 static int dvb_fini(struct em28xx *dev)
 {
-	if (!dev->board.has_dvb) {
+	if (!dev->board.has_dvb && dev->has_dvb == 0) {
 		/* This device does not support the extension */
 		return 0;
 	}
diff -r 315bc4b65b4f linux/drivers/media/video/em28xx/em28xx.h
--- a/linux/drivers/media/video/em28xx/em28xx.h	Sun May 17 12:28:55 2009 +0000
+++ b/linux/drivers/media/video/em28xx/em28xx.h	Sat May 23 17:03:00 2009 +0200
@@ -429,6 +429,11 @@ 
 #define EM28XX_AUDIO   0x10
 #define EM28XX_DVB     0x20
 
+#define EM28XX_INTERRUPT_EP	0x81
+#define EM28XX_ANALOG_VIDEO_EP	0x82
+#define EM28XX_ANALOG_AUDIO_EP	0x83
+#define EM28XX_DIGITALTV_EP	0x84
+
 struct em28xx_audio {
 	char name[50];
 	char *transfer_buffer[EM28XX_AUDIO_BUFS];
@@ -479,6 +484,13 @@ 
 	unsigned int stream_on:1;	/* Locks streams */
 	unsigned int has_audio_class:1;
 	unsigned int has_alsa_audio:1;
+	/* some devices do not have a frontend,
+	   eg reading TS stream only from alternative
+	   sources eg. mpeg encoder devices */
+	unsigned int has_frontend:1;
+	/* private section, only if _this_ board supports mpeg-ts */
+	unsigned int has_dvb:1;
+	unsigned int has_atv:1;
 
 	struct em28xx_fmt *format;
 
@@ -580,6 +592,8 @@ 
 	struct delayed_work sbutton_query_work;
 
 	struct em28xx_dvb *dvb;
+
+	unsigned int lock_control_commands:1;
 };
 
 struct em28xx_ops {
@@ -645,7 +659,6 @@ 
 
 /* Provided by em28xx-cards.c */
 extern int em2800_variant_detect(struct usb_device *udev, int model);
-extern void em28xx_pre_card_setup(struct em28xx *dev);
 extern void em28xx_card_setup(struct em28xx *dev);
 extern struct em28xx_board em28xx_boards[];
 extern struct usb_device_id em28xx_id_table[];