V4L/DVB (7602): em28xx: generalise URB setup code
Move the URB setup and management code to em28xx-core.c and generalise it slighlty so that the DVB code can use it. Signed-off-by: Aidan Thornton <makosoft@googlemail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
committed by
Mauro Carvalho Chehab
parent
7e6388a1b9
commit
579f72e44f
@@ -53,6 +53,12 @@ static int alt = EM28XX_PINOUT;
|
|||||||
module_param(alt, int, 0644);
|
module_param(alt, int, 0644);
|
||||||
MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
|
MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
|
||||||
|
|
||||||
|
/* FIXME */
|
||||||
|
#define em28xx_isocdbg(fmt, arg...) do {\
|
||||||
|
if (core_debug) \
|
||||||
|
printk(KERN_INFO "%s %s :"fmt, \
|
||||||
|
dev->name, __func__ , ##arg); } while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* em28xx_read_reg_req()
|
* em28xx_read_reg_req()
|
||||||
* reads data from the usb device specifying bRequest
|
* reads data from the usb device specifying bRequest
|
||||||
@@ -455,3 +461,178 @@ int em28xx_set_alternate(struct em28xx *dev)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------
|
||||||
|
URB control
|
||||||
|
------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IRQ callback, called by URB callback
|
||||||
|
*/
|
||||||
|
static void em28xx_irq_callback(struct urb *urb)
|
||||||
|
{
|
||||||
|
struct em28xx_dmaqueue *dma_q = urb->context;
|
||||||
|
struct em28xx *dev = container_of(dma_q, struct em28xx, vidq);
|
||||||
|
int rc, i;
|
||||||
|
|
||||||
|
/* Copy data from URB */
|
||||||
|
spin_lock(&dev->slock);
|
||||||
|
rc = dev->isoc_ctl.isoc_copy(dev, urb);
|
||||||
|
spin_unlock(&dev->slock);
|
||||||
|
|
||||||
|
/* Reset urb buffers */
|
||||||
|
for (i = 0; i < urb->number_of_packets; i++) {
|
||||||
|
urb->iso_frame_desc[i].status = 0;
|
||||||
|
urb->iso_frame_desc[i].actual_length = 0;
|
||||||
|
}
|
||||||
|
urb->status = 0;
|
||||||
|
|
||||||
|
urb->status = usb_submit_urb(urb, GFP_ATOMIC);
|
||||||
|
if (urb->status) {
|
||||||
|
em28xx_err("urb resubmit failed (error=%i)\n",
|
||||||
|
urb->status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stop and Deallocate URBs
|
||||||
|
*/
|
||||||
|
void em28xx_uninit_isoc(struct em28xx *dev)
|
||||||
|
{
|
||||||
|
struct urb *urb;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
em28xx_isocdbg("em28xx: called em28xx_uninit_isoc\n");
|
||||||
|
|
||||||
|
dev->isoc_ctl.nfields = -1;
|
||||||
|
for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
|
||||||
|
urb = dev->isoc_ctl.urb[i];
|
||||||
|
if (urb) {
|
||||||
|
usb_kill_urb(urb);
|
||||||
|
usb_unlink_urb(urb);
|
||||||
|
if (dev->isoc_ctl.transfer_buffer[i]) {
|
||||||
|
usb_buffer_free(dev->udev,
|
||||||
|
urb->transfer_buffer_length,
|
||||||
|
dev->isoc_ctl.transfer_buffer[i],
|
||||||
|
urb->transfer_dma);
|
||||||
|
}
|
||||||
|
usb_free_urb(urb);
|
||||||
|
dev->isoc_ctl.urb[i] = NULL;
|
||||||
|
}
|
||||||
|
dev->isoc_ctl.transfer_buffer[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(dev->isoc_ctl.urb);
|
||||||
|
kfree(dev->isoc_ctl.transfer_buffer);
|
||||||
|
|
||||||
|
dev->isoc_ctl.urb = NULL;
|
||||||
|
dev->isoc_ctl.transfer_buffer = NULL;
|
||||||
|
dev->isoc_ctl.num_bufs = 0;
|
||||||
|
|
||||||
|
em28xx_capture_start(dev, 0);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(em28xx_uninit_isoc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate URBs and start IRQ
|
||||||
|
*/
|
||||||
|
int em28xx_init_isoc(struct em28xx *dev, int max_packets,
|
||||||
|
int num_bufs, int max_pkt_size,
|
||||||
|
int (*isoc_copy) (struct em28xx *dev, struct urb *urb),
|
||||||
|
int cap_type)
|
||||||
|
{
|
||||||
|
struct em28xx_dmaqueue *dma_q = &dev->vidq;
|
||||||
|
int i;
|
||||||
|
int sb_size, pipe;
|
||||||
|
struct urb *urb;
|
||||||
|
int j, k;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
em28xx_isocdbg("em28xx: called em28xx_prepare_isoc\n");
|
||||||
|
|
||||||
|
/* De-allocates all pending stuff */
|
||||||
|
em28xx_uninit_isoc(dev);
|
||||||
|
|
||||||
|
dev->isoc_ctl.isoc_copy = isoc_copy;
|
||||||
|
dev->isoc_ctl.num_bufs = num_bufs;
|
||||||
|
|
||||||
|
dev->isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL);
|
||||||
|
if (!dev->isoc_ctl.urb) {
|
||||||
|
em28xx_errdev("cannot alloc memory for usb buffers\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs,
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!dev->isoc_ctl.urb) {
|
||||||
|
em28xx_errdev("cannot allocate memory for usbtransfer\n");
|
||||||
|
kfree(dev->isoc_ctl.urb);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->isoc_ctl.max_pkt_size = max_pkt_size;
|
||||||
|
dev->isoc_ctl.buf = NULL;
|
||||||
|
|
||||||
|
sb_size = max_packets * dev->isoc_ctl.max_pkt_size;
|
||||||
|
|
||||||
|
/* allocate urbs and transfer buffers */
|
||||||
|
for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
|
||||||
|
urb = usb_alloc_urb(max_packets, GFP_KERNEL);
|
||||||
|
if (!urb) {
|
||||||
|
em28xx_err("cannot alloc isoc_ctl.urb %i\n", i);
|
||||||
|
em28xx_uninit_isoc(dev);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
dev->isoc_ctl.urb[i] = urb;
|
||||||
|
|
||||||
|
dev->isoc_ctl.transfer_buffer[i] = usb_buffer_alloc(dev->udev,
|
||||||
|
sb_size, GFP_KERNEL, &urb->transfer_dma);
|
||||||
|
if (!dev->isoc_ctl.transfer_buffer[i]) {
|
||||||
|
em28xx_err("unable to allocate %i bytes for transfer"
|
||||||
|
" buffer %i%s\n",
|
||||||
|
sb_size, i,
|
||||||
|
in_interrupt()?" while in int":"");
|
||||||
|
em28xx_uninit_isoc(dev);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);
|
||||||
|
|
||||||
|
/* FIXME: this is a hack - should be
|
||||||
|
'desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK'
|
||||||
|
should also be using 'desc.bInterval'
|
||||||
|
*/
|
||||||
|
pipe = usb_rcvisocpipe(dev->udev, cap_type == EM28XX_ANALOG_CAPTURE ? 0x82 : 0x84);
|
||||||
|
usb_fill_int_urb(urb, dev->udev, pipe,
|
||||||
|
dev->isoc_ctl.transfer_buffer[i], sb_size,
|
||||||
|
em28xx_irq_callback, dma_q, 1);
|
||||||
|
|
||||||
|
urb->number_of_packets = max_packets;
|
||||||
|
urb->transfer_flags = URB_ISO_ASAP;
|
||||||
|
|
||||||
|
k = 0;
|
||||||
|
for (j = 0; j < max_packets; j++) {
|
||||||
|
urb->iso_frame_desc[j].offset = k;
|
||||||
|
urb->iso_frame_desc[j].length =
|
||||||
|
dev->isoc_ctl.max_pkt_size;
|
||||||
|
k += dev->isoc_ctl.max_pkt_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init_waitqueue_head(&dma_q->wq);
|
||||||
|
|
||||||
|
em28xx_capture_start(dev, cap_type);
|
||||||
|
|
||||||
|
/* submit urbs and enables IRQ */
|
||||||
|
for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
|
||||||
|
rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC);
|
||||||
|
if (rc) {
|
||||||
|
em28xx_err("submit of urb %i failed (error=%i)\n", i,
|
||||||
|
rc);
|
||||||
|
em28xx_uninit_isoc(dev);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(em28xx_init_isoc);
|
||||||
|
@@ -285,11 +285,10 @@ static inline void get_next_buf(struct em28xx_dmaqueue *dma_q,
|
|||||||
/*
|
/*
|
||||||
* Controls the isoc copy of each urb packet
|
* Controls the isoc copy of each urb packet
|
||||||
*/
|
*/
|
||||||
static inline int em28xx_isoc_copy(struct urb *urb)
|
static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
|
||||||
{
|
{
|
||||||
struct em28xx_buffer *buf;
|
struct em28xx_buffer *buf;
|
||||||
struct em28xx_dmaqueue *dma_q = urb->context;
|
struct em28xx_dmaqueue *dma_q = urb->context;
|
||||||
struct em28xx *dev = container_of(dma_q, struct em28xx, vidq);
|
|
||||||
unsigned char *outp = NULL;
|
unsigned char *outp = NULL;
|
||||||
int i, len = 0, rc = 1;
|
int i, len = 0, rc = 1;
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
@@ -370,188 +369,6 @@ static inline int em28xx_isoc_copy(struct urb *urb)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------
|
|
||||||
URB control
|
|
||||||
------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* IRQ callback, called by URB callback
|
|
||||||
*/
|
|
||||||
static void em28xx_irq_callback(struct urb *urb)
|
|
||||||
{
|
|
||||||
struct em28xx_dmaqueue *dma_q = urb->context;
|
|
||||||
struct em28xx *dev = container_of(dma_q, struct em28xx, vidq);
|
|
||||||
int rc, i;
|
|
||||||
|
|
||||||
/* Copy data from URB */
|
|
||||||
spin_lock(&dev->slock);
|
|
||||||
rc = em28xx_isoc_copy(urb);
|
|
||||||
spin_unlock(&dev->slock);
|
|
||||||
|
|
||||||
/* Reset urb buffers */
|
|
||||||
for (i = 0; i < urb->number_of_packets; i++) {
|
|
||||||
urb->iso_frame_desc[i].status = 0;
|
|
||||||
urb->iso_frame_desc[i].actual_length = 0;
|
|
||||||
}
|
|
||||||
urb->status = 0;
|
|
||||||
|
|
||||||
urb->status = usb_submit_urb(urb, GFP_ATOMIC);
|
|
||||||
if (urb->status) {
|
|
||||||
em28xx_err("urb resubmit failed (error=%i)\n",
|
|
||||||
urb->status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Stop and Deallocate URBs
|
|
||||||
*/
|
|
||||||
static void em28xx_uninit_isoc(struct em28xx *dev)
|
|
||||||
{
|
|
||||||
struct urb *urb;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
em28xx_isocdbg("em28xx: called em28xx_uninit_isoc\n");
|
|
||||||
|
|
||||||
dev->isoc_ctl.nfields = -1;
|
|
||||||
for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
|
|
||||||
urb = dev->isoc_ctl.urb[i];
|
|
||||||
if (urb) {
|
|
||||||
usb_kill_urb(urb);
|
|
||||||
usb_unlink_urb(urb);
|
|
||||||
if (dev->isoc_ctl.transfer_buffer[i]) {
|
|
||||||
usb_buffer_free(dev->udev,
|
|
||||||
urb->transfer_buffer_length,
|
|
||||||
dev->isoc_ctl.transfer_buffer[i],
|
|
||||||
urb->transfer_dma);
|
|
||||||
}
|
|
||||||
usb_free_urb(urb);
|
|
||||||
dev->isoc_ctl.urb[i] = NULL;
|
|
||||||
}
|
|
||||||
dev->isoc_ctl.transfer_buffer[i] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
kfree(dev->isoc_ctl.urb);
|
|
||||||
kfree(dev->isoc_ctl.transfer_buffer);
|
|
||||||
dev->isoc_ctl.urb = NULL;
|
|
||||||
dev->isoc_ctl.transfer_buffer = NULL;
|
|
||||||
|
|
||||||
dev->isoc_ctl.num_bufs = 0;
|
|
||||||
|
|
||||||
em28xx_capture_start(dev, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allocate URBs and start IRQ
|
|
||||||
*/
|
|
||||||
static int em28xx_prepare_isoc(struct em28xx *dev, int max_packets,
|
|
||||||
int num_bufs)
|
|
||||||
{
|
|
||||||
struct em28xx_dmaqueue *dma_q = &dev->vidq;
|
|
||||||
int i;
|
|
||||||
int sb_size, pipe;
|
|
||||||
struct urb *urb;
|
|
||||||
int j, k;
|
|
||||||
|
|
||||||
em28xx_isocdbg("em28xx: called em28xx_prepare_isoc\n");
|
|
||||||
|
|
||||||
/* De-allocates all pending stuff */
|
|
||||||
em28xx_uninit_isoc(dev);
|
|
||||||
|
|
||||||
dev->isoc_ctl.num_bufs = num_bufs;
|
|
||||||
|
|
||||||
dev->isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL);
|
|
||||||
if (!dev->isoc_ctl.urb) {
|
|
||||||
em28xx_errdev("cannot alloc memory for usb buffers\n");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs,
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!dev->isoc_ctl.urb) {
|
|
||||||
em28xx_errdev("cannot allocate memory for usbtransfer\n");
|
|
||||||
kfree(dev->isoc_ctl.urb);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev->isoc_ctl.max_pkt_size = dev->max_pkt_size;
|
|
||||||
dev->isoc_ctl.buf = NULL;
|
|
||||||
|
|
||||||
sb_size = max_packets * dev->isoc_ctl.max_pkt_size;
|
|
||||||
|
|
||||||
/* allocate urbs and transfer buffers */
|
|
||||||
for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
|
|
||||||
urb = usb_alloc_urb(max_packets, GFP_KERNEL);
|
|
||||||
if (!urb) {
|
|
||||||
em28xx_err("cannot alloc isoc_ctl.urb %i\n", i);
|
|
||||||
em28xx_uninit_isoc(dev);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
dev->isoc_ctl.urb[i] = urb;
|
|
||||||
|
|
||||||
dev->isoc_ctl.transfer_buffer[i] = usb_buffer_alloc(dev->udev,
|
|
||||||
sb_size, GFP_KERNEL, &urb->transfer_dma);
|
|
||||||
if (!dev->isoc_ctl.transfer_buffer[i]) {
|
|
||||||
em28xx_err("unable to allocate %i bytes for transfer"
|
|
||||||
" buffer %i%s\n",
|
|
||||||
sb_size, i,
|
|
||||||
in_interrupt()?" while in int":"");
|
|
||||||
em28xx_uninit_isoc(dev);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);
|
|
||||||
|
|
||||||
/* FIXME: this is a hack - should be
|
|
||||||
'desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK'
|
|
||||||
should also be using 'desc.bInterval'
|
|
||||||
*/
|
|
||||||
pipe = usb_rcvisocpipe(dev->udev, 0x82);
|
|
||||||
usb_fill_int_urb(urb, dev->udev, pipe,
|
|
||||||
dev->isoc_ctl.transfer_buffer[i], sb_size,
|
|
||||||
em28xx_irq_callback, dma_q, 1);
|
|
||||||
|
|
||||||
urb->number_of_packets = max_packets;
|
|
||||||
urb->transfer_flags = URB_ISO_ASAP;
|
|
||||||
|
|
||||||
k = 0;
|
|
||||||
for (j = 0; j < max_packets; j++) {
|
|
||||||
urb->iso_frame_desc[j].offset = k;
|
|
||||||
urb->iso_frame_desc[j].length =
|
|
||||||
dev->isoc_ctl.max_pkt_size;
|
|
||||||
k += dev->isoc_ctl.max_pkt_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int em28xx_start_thread(struct em28xx_dmaqueue *dma_q)
|
|
||||||
{
|
|
||||||
struct em28xx *dev = container_of(dma_q, struct em28xx, vidq);
|
|
||||||
int i, rc = 0;
|
|
||||||
|
|
||||||
em28xx_videodbg("Called em28xx_start_thread\n");
|
|
||||||
|
|
||||||
init_waitqueue_head(&dma_q->wq);
|
|
||||||
|
|
||||||
em28xx_capture_start(dev, 1);
|
|
||||||
|
|
||||||
/* submit urbs and enables IRQ */
|
|
||||||
for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
|
|
||||||
rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC);
|
|
||||||
if (rc) {
|
|
||||||
em28xx_err("submit of urb %i failed (error=%i)\n", i,
|
|
||||||
rc);
|
|
||||||
em28xx_uninit_isoc(dev);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rc < 0)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------
|
/* ------------------------------------------------------------------
|
||||||
Videobuf operations
|
Videobuf operations
|
||||||
------------------------------------------------------------------*/
|
------------------------------------------------------------------*/
|
||||||
@@ -615,7 +432,6 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
|
|||||||
struct em28xx_fh *fh = vq->priv_data;
|
struct em28xx_fh *fh = vq->priv_data;
|
||||||
struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
|
struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
|
||||||
struct em28xx *dev = fh->dev;
|
struct em28xx *dev = fh->dev;
|
||||||
struct em28xx_dmaqueue *vidq = &dev->vidq;
|
|
||||||
int rc = 0, urb_init = 0;
|
int rc = 0, urb_init = 0;
|
||||||
|
|
||||||
/* FIXME: It assumes depth = 16 */
|
/* FIXME: It assumes depth = 16 */
|
||||||
@@ -639,12 +455,9 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
|
|||||||
urb_init = 1;
|
urb_init = 1;
|
||||||
|
|
||||||
if (urb_init) {
|
if (urb_init) {
|
||||||
rc = em28xx_prepare_isoc(dev, EM28XX_NUM_PACKETS,
|
rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS,
|
||||||
EM28XX_NUM_BUFS);
|
EM28XX_NUM_BUFS, dev->max_pkt_size,
|
||||||
if (rc < 0)
|
em28xx_isoc_copy, EM28XX_ANALOG_CAPTURE);
|
||||||
goto fail;
|
|
||||||
|
|
||||||
rc = em28xx_start_thread(vidq);
|
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@@ -119,6 +119,8 @@ enum em28xx_stream_state {
|
|||||||
STREAM_ON,
|
STREAM_ON,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct em28xx;
|
||||||
|
|
||||||
struct em28xx_usb_isoc_ctl {
|
struct em28xx_usb_isoc_ctl {
|
||||||
/* max packet size of isoc transaction */
|
/* max packet size of isoc transaction */
|
||||||
int max_pkt_size;
|
int max_pkt_size;
|
||||||
@@ -148,6 +150,10 @@ struct em28xx_usb_isoc_ctl {
|
|||||||
|
|
||||||
/* Stores the number of received fields */
|
/* Stores the number of received fields */
|
||||||
int nfields;
|
int nfields;
|
||||||
|
|
||||||
|
/* isoc urb callback */
|
||||||
|
int (*isoc_copy) (struct em28xx *dev, struct urb *urb);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct em28xx_fmt {
|
struct em28xx_fmt {
|
||||||
@@ -279,6 +285,12 @@ enum em28xx_dev_state {
|
|||||||
DEV_MISCONFIGURED = 0x04,
|
DEV_MISCONFIGURED = 0x04,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum em28xx_capture_mode {
|
||||||
|
EM28XX_CAPTURE_OFF = 0,
|
||||||
|
EM28XX_ANALOG_CAPTURE,
|
||||||
|
EM28XX_DIGITAL_CAPTURE,
|
||||||
|
};
|
||||||
|
|
||||||
#define EM28XX_AUDIO_BUFS 5
|
#define EM28XX_AUDIO_BUFS 5
|
||||||
#define EM28XX_NUM_AUDIO_PACKETS 64
|
#define EM28XX_NUM_AUDIO_PACKETS 64
|
||||||
#define EM28XX_AUDIO_MAX_PACKET_SIZE 196 /* static value */
|
#define EM28XX_AUDIO_MAX_PACKET_SIZE 196 /* static value */
|
||||||
@@ -452,6 +464,11 @@ int em28xx_capture_start(struct em28xx *dev, int start);
|
|||||||
int em28xx_outfmt_set_yuv422(struct em28xx *dev);
|
int em28xx_outfmt_set_yuv422(struct em28xx *dev);
|
||||||
int em28xx_resolution_set(struct em28xx *dev);
|
int em28xx_resolution_set(struct em28xx *dev);
|
||||||
int em28xx_set_alternate(struct em28xx *dev);
|
int em28xx_set_alternate(struct em28xx *dev);
|
||||||
|
int em28xx_init_isoc(struct em28xx *dev, int max_packets,
|
||||||
|
int num_bufs, int max_pkt_size,
|
||||||
|
int (*isoc_copy) (struct em28xx *dev, struct urb *urb),
|
||||||
|
int cap_type);
|
||||||
|
void em28xx_uninit_isoc(struct em28xx *dev);
|
||||||
|
|
||||||
/* Provided by em28xx-video.c */
|
/* Provided by em28xx-video.c */
|
||||||
int em28xx_register_extension(struct em28xx_ops *dev);
|
int em28xx_register_extension(struct em28xx_ops *dev);
|
||||||
|
Reference in New Issue
Block a user