Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 330710
b: refs/heads/master
c: 43f2ccc
h: refs/heads/master
v: v3
  • Loading branch information
Devin Heitmueller authored and Mauro Carvalho Chehab committed Aug 9, 2012
1 parent 8ff9982 commit f930048
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b0c4878ebe3ad9706ea2e452331550fd6d171977
refs/heads/master: 43f2cccfc81c0af719a425ea816ce8003bb09748
54 changes: 48 additions & 6 deletions trunk/drivers/media/video/au0828/au0828-dvb.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,14 @@ static struct tda18271_config hauppauge_woodbury_tunerconfig = {
.gate = TDA18271_GATE_DIGITAL,
};

static void au0828_restart_dvb_streaming(struct work_struct *work);

/*-------------------------------------------------------------------*/
static void urb_completion(struct urb *purb)
{
struct au0828_dev *dev = purb->context;
int ptype = usb_pipetype(purb->pipe);
unsigned char *ptr;

dprintk(2, "%s()\n", __func__);

Expand All @@ -121,6 +124,16 @@ static void urb_completion(struct urb *purb)
return;
}

/* See if the stream is corrupted (to work around a hardware
bug where the stream gets misaligned */
ptr = purb->transfer_buffer;
if (purb->actual_length > 0 && ptr[0] != 0x47) {
dprintk(1, "Need to restart streaming %02x len=%d!\n",
ptr[0], purb->actual_length);
schedule_work(&dev->restart_streaming);
return;
}

/* Feed the transport payload into the kernel demux */
dvb_dmx_swfilter_packets(&dev->dvb.demux,
purb->transfer_buffer, purb->actual_length / 188);
Expand All @@ -138,14 +151,13 @@ static int stop_urb_transfer(struct au0828_dev *dev)

dprintk(2, "%s()\n", __func__);

dev->urb_streaming = 0;
for (i = 0; i < URB_COUNT; i++) {
usb_kill_urb(dev->urbs[i]);
kfree(dev->urbs[i]->transfer_buffer);
usb_free_urb(dev->urbs[i]);
}

dev->urb_streaming = 0;

return 0;
}

Expand Down Expand Up @@ -246,25 +258,55 @@ static int au0828_dvb_stop_feed(struct dvb_demux_feed *feed)
mutex_lock(&dvb->lock);
if (--dvb->feeding == 0) {
/* Stop transport */
au0828_write(dev, 0x608, 0x00);
au0828_write(dev, 0x609, 0x00);
au0828_write(dev, 0x60a, 0x00);
au0828_write(dev, 0x60b, 0x00);
ret = stop_urb_transfer(dev);
au0828_write(dev, 0x60b, 0x00);
}
mutex_unlock(&dvb->lock);
}

return ret;
}

static void au0828_restart_dvb_streaming(struct work_struct *work)
{
struct au0828_dev *dev = container_of(work, struct au0828_dev,
restart_streaming);
struct au0828_dvb *dvb = &dev->dvb;
int ret;

if (dev->urb_streaming == 0)
return;

dprintk(1, "Restarting streaming...!\n");

mutex_lock(&dvb->lock);

/* Stop transport */
ret = stop_urb_transfer(dev);
au0828_write(dev, 0x608, 0x00);
au0828_write(dev, 0x609, 0x00);
au0828_write(dev, 0x60a, 0x00);
au0828_write(dev, 0x60b, 0x00);

/* Start transport */
au0828_write(dev, 0x608, 0x90);
au0828_write(dev, 0x609, 0x72);
au0828_write(dev, 0x60a, 0x71);
au0828_write(dev, 0x60b, 0x01);
ret = start_urb_transfer(dev);

mutex_unlock(&dvb->lock);
}

static int dvb_register(struct au0828_dev *dev)
{
struct au0828_dvb *dvb = &dev->dvb;
int result;

dprintk(1, "%s()\n", __func__);

INIT_WORK(&dev->restart_streaming, au0828_restart_dvb_streaming);

/* register adapter */
result = dvb_register_adapter(&dvb->adapter, DRIVER_NAME, THIS_MODULE,
&dev->usbdev->dev, adapter_nr);
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/media/video/au0828/au0828.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ struct au0828_dev {

/* Digital */
struct au0828_dvb dvb;
struct work_struct restart_streaming;

/* Analog */
struct v4l2_device v4l2_dev;
Expand Down

0 comments on commit f930048

Please sign in to comment.