summaryrefslogtreecommitdiff
path: root/drivers/media/usb/em28xx/em28xx-core.c
diff options
context:
space:
mode:
authorFrank Schaefer <fschaefer.oss@googlemail.com>2012-11-08 14:11:52 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-12-22 18:17:52 -0200
commitc647a91a2558c4031eddd013e5860ca5a41363a7 (patch)
tree90a0b103355b59ef61fa7d2f88a6ec78e24e189b /drivers/media/usb/em28xx/em28xx-core.c
parentc8e9d95b41f2a441b2af0a1899448dd45ad7632d (diff)
[media] em28xx: improve USB endpoint logic, also use bulk transfers
The current enpoint logic ignores all bulk endpoints and uses a fixed mapping between endpint addresses and the supported data stream types (analog/audio/DVB): Ep 0x82, isoc => analog Ep 0x83, isoc => audio Ep 0x84, isoc => DVB Now that the code can also do bulk transfers, the endpoint logic has to be extended to also consider bulk endpoints. The new logic preserves backwards compatibility and reflects the endpoint configurations we have seen so far: Ep 0x82, isoc => analog Ep 0x82, bulk => analog Ep 0x83, isoc* => audio Ep 0x84, isoc => digital Ep 0x84, bulk => analog or digital** (*: audio should always be isoc) (**: analog, if ep 0x82 is isoc, otherwise digital) [mchehab@redhat.com: Fix a CodingStyle issue: don't break strings into separate lines] Signed-off-by: Frank Schäfer <fschaefer.oss@googlemail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/usb/em28xx/em28xx-core.c')
-rw-r--r--drivers/media/usb/em28xx/em28xx-core.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c
index cdf4cd24007d..b10d959fefe5 100644
--- a/drivers/media/usb/em28xx/em28xx-core.c
+++ b/drivers/media/usb/em28xx/em28xx-core.c
@@ -847,11 +847,13 @@ set_alt:
if (dev->alt != prev_alt) {
if (dev->analog_xfer_bulk) {
dev->max_pkt_size = 512; /* USB 2.0 spec */
+ dev->packet_multiplier = EM28XX_BULK_PACKET_MULTIPLIER;
} else { /* isoc */
em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n",
min_pkt_size, dev->alt);
dev->max_pkt_size =
dev->alt_max_pkt_size_isoc[dev->alt];
+ dev->packet_multiplier = EM28XX_NUM_ISOC_PACKETS;
}
em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n",
dev->alt, dev->max_pkt_size);
@@ -1054,10 +1056,28 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk,
em28xx_isocdbg("em28xx: called em28xx_alloc_isoc in mode %d\n", mode);
- if (mode == EM28XX_DIGITAL_MODE)
+ /* Check mode and if we have an endpoint for the selected
+ transfer type, select buffer */
+ if (mode == EM28XX_DIGITAL_MODE) {
+ if ((xfer_bulk && !dev->dvb_ep_bulk) ||
+ (!xfer_bulk && !dev->dvb_ep_isoc)) {
+ em28xx_errdev("no endpoint for DVB mode and transfer type %d\n",
+ xfer_bulk > 0);
+ return -EINVAL;
+ }
usb_bufs = &dev->usb_ctl.digital_bufs;
- else
+ } else if (mode == EM28XX_ANALOG_MODE) {
+ if ((xfer_bulk && !dev->analog_ep_bulk) ||
+ (!xfer_bulk && !dev->analog_ep_isoc)) {
+ em28xx_errdev("no endpoint for analog mode and transfer type %d\n",
+ xfer_bulk > 0);
+ return -EINVAL;
+ }
usb_bufs = &dev->usb_ctl.analog_bufs;
+ } else {
+ em28xx_errdev("invalid mode selected\n");
+ return -EINVAL;
+ }
/* De-allocates all pending stuff */
em28xx_uninit_usb_xfer(dev, mode);
@@ -1113,8 +1133,8 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk,
if (xfer_bulk) { /* bulk */
pipe = usb_rcvbulkpipe(dev->udev,
mode == EM28XX_ANALOG_MODE ?
- EM28XX_EP_ANALOG :
- EM28XX_EP_DIGITAL);
+ dev->analog_ep_bulk :
+ dev->dvb_ep_bulk);
usb_fill_bulk_urb(urb, dev->udev, pipe,
usb_bufs->transfer_buffer[i], sb_size,
em28xx_irq_callback, dev);
@@ -1122,8 +1142,8 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk,
} else { /* isoc */
pipe = usb_rcvisocpipe(dev->udev,
mode == EM28XX_ANALOG_MODE ?
- EM28XX_EP_ANALOG :
- EM28XX_EP_DIGITAL);
+ dev->analog_ep_isoc :
+ dev->dvb_ep_isoc);
usb_fill_int_urb(urb, dev->udev, pipe,
usb_bufs->transfer_buffer[i], sb_size,
em28xx_irq_callback, dev, 1);