Merge branch 'v4l_for_2.6.35' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'v4l_for_2.6.35' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: V4L/DVB: uvc: Fix multiple symbols definitions with UVC gadget and host drivers V4L/DVB: v4l: mem2mem_testdev: fix g_fmt NULL pointer dereference V4L/DVB: uvcvideo: Power line frequency control doesn't support GET_MIN/MAX/RES V4L/DVB: ivtv: Add delay to ensure the decoder always restarts with a blank screen V4L/DVB: Documentation: Add the Philips FQ1236 MK5 to video4linux/CARDLIST.tuner V4L/DVB: tveeprom: Add an entry for tuner code 168: a TCL M30WTP-4N-E tuner V4L/DVB: tuner: Add a definition for the Philips FQ1236 MK5 NTSC tuner V4L/DVB: OMAP_VOUT: fix: Module params were not working through bootargs V4L/DVB: OMAP_VOUT: fix: Replaced dma-sg with dma-contig V4L/DVB: OMAP_VOUT:Build FIX: Rebased against latest DSS2 changes
This commit is contained in:
commit
9f71963702
18 changed files with 169 additions and 163 deletions
|
@ -82,3 +82,4 @@ tuner=81 - Partsnic (Daewoo) PTI-5NF05
|
|||
tuner=82 - Philips CU1216L
|
||||
tuner=83 - NXP TDA18271
|
||||
tuner=84 - Sony BTF-Pxn01Z
|
||||
tuner=85 - Philips FQ1236 MK5
|
||||
|
|
|
@ -524,6 +524,7 @@ static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer)
|
|||
buffer[3] = 0x39;
|
||||
break;
|
||||
case TUNER_PHILIPS_FQ1216LME_MK3:
|
||||
case TUNER_PHILIPS_FQ1236_MK5:
|
||||
tuner_err("This tuner doesn't have FM\n");
|
||||
/* Set the low band for sanity, since it covers 88-108 MHz */
|
||||
buffer[3] = 0x01;
|
||||
|
|
|
@ -1353,6 +1353,17 @@ static struct tuner_params tuner_sony_btf_pxn01z_params[] = {
|
|||
},
|
||||
};
|
||||
|
||||
/* ------------ TUNER_PHILIPS_FQ1236_MK5 - Philips NTSC ------------ */
|
||||
|
||||
static struct tuner_params tuner_philips_fq1236_mk5_params[] = {
|
||||
{
|
||||
.type = TUNER_PARAM_TYPE_NTSC,
|
||||
.ranges = tuner_fm1236_mk3_ntsc_ranges,
|
||||
.count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
|
||||
.has_tda9887 = 1, /* TDA9885, no FM radio */
|
||||
},
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
struct tunertype tuners[] = {
|
||||
|
@ -1826,6 +1837,11 @@ struct tunertype tuners[] = {
|
|||
.params = tuner_sony_btf_pxn01z_params,
|
||||
.count = ARRAY_SIZE(tuner_sony_btf_pxn01z_params),
|
||||
},
|
||||
[TUNER_PHILIPS_FQ1236_MK5] = { /* NTSC, TDA9885, no FM radio */
|
||||
.name = "Philips FQ1236 MK5",
|
||||
.params = tuner_philips_fq1236_mk5_params,
|
||||
.count = ARRAY_SIZE(tuner_philips_fq1236_mk5_params),
|
||||
},
|
||||
};
|
||||
EXPORT_SYMBOL(tuners);
|
||||
|
||||
|
|
|
@ -912,6 +912,9 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
|
|||
clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
|
||||
ivtv_flush_queues(s);
|
||||
|
||||
/* decoder needs time to settle */
|
||||
ivtv_msleep_timeout(40, 0);
|
||||
|
||||
/* decrement decoding */
|
||||
atomic_dec(&itv->decoding);
|
||||
|
||||
|
|
|
@ -988,6 +988,9 @@ static int m2mtest_probe(struct platform_device *pdev)
|
|||
goto err_m2m;
|
||||
}
|
||||
|
||||
q_data[V4L2_M2M_SRC].fmt = &formats[0];
|
||||
q_data[V4L2_M2M_DST].fmt = &formats[0];
|
||||
|
||||
return 0;
|
||||
|
||||
err_m2m:
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
config VIDEO_OMAP2_VOUT
|
||||
tristate "OMAP2/OMAP3 V4L2-Display driver"
|
||||
depends on ARCH_OMAP24XX || ARCH_OMAP34XX
|
||||
depends on ARCH_OMAP2 || ARCH_OMAP3
|
||||
select VIDEOBUF_GEN
|
||||
select VIDEOBUF_DMA_SG
|
||||
select VIDEOBUF_DMA_CONTIG
|
||||
select OMAP2_DSS
|
||||
select OMAP2_VRAM
|
||||
select OMAP2_VRFB
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
#
|
||||
|
||||
# OMAP2/3 Display driver
|
||||
omap-vout-mod-objs := omap_vout.o omap_voutlib.o
|
||||
obj-$(CONFIG_VIDEO_OMAP2_VOUT) += omap-vout-mod.o
|
||||
omap-vout-y := omap_vout.o omap_voutlib.o
|
||||
obj-$(CONFIG_VIDEO_OMAP2_VOUT) += omap-vout.o
|
||||
|
|
|
@ -38,8 +38,9 @@
|
|||
#include <linux/dma-mapping.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <media/videobuf-dma-sg.h>
|
||||
#include <media/videobuf-dma-contig.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-ioctl.h>
|
||||
|
||||
|
@ -1053,9 +1054,9 @@ static int omap_vout_buffer_prepare(struct videobuf_queue *q,
|
|||
struct videobuf_buffer *vb,
|
||||
enum v4l2_field field)
|
||||
{
|
||||
dma_addr_t dmabuf;
|
||||
struct vid_vrfb_dma *tx;
|
||||
enum dss_rotation rotation;
|
||||
struct videobuf_dmabuf *dmabuf = NULL;
|
||||
struct omap_vout_device *vout = q->priv_data;
|
||||
u32 dest_frame_index = 0, src_element_index = 0;
|
||||
u32 dest_element_index = 0, src_frame_index = 0;
|
||||
|
@ -1074,24 +1075,17 @@ static int omap_vout_buffer_prepare(struct videobuf_queue *q,
|
|||
if (V4L2_MEMORY_USERPTR == vb->memory) {
|
||||
if (0 == vb->baddr)
|
||||
return -EINVAL;
|
||||
/* Virtual address */
|
||||
/* priv points to struct videobuf_pci_sg_memory. But we went
|
||||
* pointer to videobuf_dmabuf, which is member of
|
||||
* videobuf_pci_sg_memory */
|
||||
dmabuf = videobuf_to_dma(q->bufs[vb->i]);
|
||||
dmabuf->vmalloc = (void *) vb->baddr;
|
||||
|
||||
/* Physical address */
|
||||
dmabuf->bus_addr =
|
||||
(dma_addr_t) omap_vout_uservirt_to_phys(vb->baddr);
|
||||
vout->queued_buf_addr[vb->i] = (u8 *)
|
||||
omap_vout_uservirt_to_phys(vb->baddr);
|
||||
} else {
|
||||
vout->queued_buf_addr[vb->i] = (u8 *)vout->buf_phy_addr[vb->i];
|
||||
}
|
||||
|
||||
if (!rotation_enabled(vout)) {
|
||||
dmabuf = videobuf_to_dma(q->bufs[vb->i]);
|
||||
vout->queued_buf_addr[vb->i] = (u8 *) dmabuf->bus_addr;
|
||||
if (!rotation_enabled(vout))
|
||||
return 0;
|
||||
}
|
||||
dmabuf = videobuf_to_dma(q->bufs[vb->i]);
|
||||
|
||||
dmabuf = vout->buf_phy_addr[vb->i];
|
||||
/* If rotation is enabled, copy input buffer into VRFB
|
||||
* memory space using DMA. We are copying input buffer
|
||||
* into VRFB memory space of desired angle and DSS will
|
||||
|
@ -1120,7 +1114,7 @@ static int omap_vout_buffer_prepare(struct videobuf_queue *q,
|
|||
tx->dev_id, 0x0);
|
||||
/* src_port required only for OMAP1 */
|
||||
omap_set_dma_src_params(tx->dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
|
||||
dmabuf->bus_addr, src_element_index, src_frame_index);
|
||||
dmabuf, src_element_index, src_frame_index);
|
||||
/*set dma source burst mode for VRFB */
|
||||
omap_set_dma_src_burst_mode(tx->dma_ch, OMAP_DMA_DATA_BURST_16);
|
||||
rotation = calc_rotation(vout);
|
||||
|
@ -1211,7 +1205,6 @@ static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma)
|
|||
void *pos;
|
||||
unsigned long start = vma->vm_start;
|
||||
unsigned long size = (vma->vm_end - vma->vm_start);
|
||||
struct videobuf_dmabuf *dmabuf = NULL;
|
||||
struct omap_vout_device *vout = file->private_data;
|
||||
struct videobuf_queue *q = &vout->vbq;
|
||||
|
||||
|
@ -1241,8 +1234,7 @@ static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma)
|
|||
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
|
||||
vma->vm_ops = &omap_vout_vm_ops;
|
||||
vma->vm_private_data = (void *) vout;
|
||||
dmabuf = videobuf_to_dma(q->bufs[i]);
|
||||
pos = dmabuf->vmalloc;
|
||||
pos = (void *)vout->buf_virt_addr[i];
|
||||
vma->vm_pgoff = virt_to_phys((void *)pos) >> PAGE_SHIFT;
|
||||
while (size > 0) {
|
||||
unsigned long pfn;
|
||||
|
@ -1347,8 +1339,8 @@ static int omap_vout_open(struct file *file)
|
|||
video_vbq_ops.buf_queue = omap_vout_buffer_queue;
|
||||
spin_lock_init(&vout->vbq_lock);
|
||||
|
||||
videobuf_queue_sg_init(q, &video_vbq_ops, NULL, &vout->vbq_lock,
|
||||
vout->type, V4L2_FIELD_NONE,
|
||||
videobuf_queue_dma_contig_init(q, &video_vbq_ops, q->dev,
|
||||
&vout->vbq_lock, vout->type, V4L2_FIELD_NONE,
|
||||
sizeof(struct videobuf_buffer), vout);
|
||||
|
||||
v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
|
||||
|
@ -1799,7 +1791,6 @@ static int vidioc_reqbufs(struct file *file, void *fh,
|
|||
unsigned int i, num_buffers = 0;
|
||||
struct omap_vout_device *vout = fh;
|
||||
struct videobuf_queue *q = &vout->vbq;
|
||||
struct videobuf_dmabuf *dmabuf = NULL;
|
||||
|
||||
if ((req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) || (req->count < 0))
|
||||
return -EINVAL;
|
||||
|
@ -1825,8 +1816,7 @@ static int vidioc_reqbufs(struct file *file, void *fh,
|
|||
num_buffers = (vout->vid == OMAP_VIDEO1) ?
|
||||
video1_numbuffers : video2_numbuffers;
|
||||
for (i = num_buffers; i < vout->buffer_allocated; i++) {
|
||||
dmabuf = videobuf_to_dma(q->bufs[i]);
|
||||
omap_vout_free_buffer((u32)dmabuf->vmalloc,
|
||||
omap_vout_free_buffer(vout->buf_virt_addr[i],
|
||||
vout->buffer_size);
|
||||
vout->buf_virt_addr[i] = 0;
|
||||
vout->buf_phy_addr[i] = 0;
|
||||
|
@ -1855,12 +1845,7 @@ static int vidioc_reqbufs(struct file *file, void *fh,
|
|||
goto reqbuf_err;
|
||||
|
||||
vout->buffer_allocated = req->count;
|
||||
for (i = 0; i < req->count; i++) {
|
||||
dmabuf = videobuf_to_dma(q->bufs[i]);
|
||||
dmabuf->vmalloc = (void *) vout->buf_virt_addr[i];
|
||||
dmabuf->bus_addr = (dma_addr_t) vout->buf_phy_addr[i];
|
||||
dmabuf->sglen = 1;
|
||||
}
|
||||
|
||||
reqbuf_err:
|
||||
mutex_unlock(&vout->lock);
|
||||
return ret;
|
||||
|
@ -2488,7 +2473,7 @@ static int omap_vout_remove(struct platform_device *pdev)
|
|||
|
||||
for (k = 0; k < vid_dev->num_displays; k++) {
|
||||
if (vid_dev->displays[k]->state != OMAP_DSS_DISPLAY_DISABLED)
|
||||
vid_dev->displays[k]->disable(vid_dev->displays[k]);
|
||||
vid_dev->displays[k]->driver->disable(vid_dev->displays[k]);
|
||||
|
||||
omap_dss_put_device(vid_dev->displays[k]);
|
||||
}
|
||||
|
@ -2545,7 +2530,9 @@ static int __init omap_vout_probe(struct platform_device *pdev)
|
|||
def_display = NULL;
|
||||
}
|
||||
if (def_display) {
|
||||
ret = def_display->enable(def_display);
|
||||
struct omap_dss_driver *dssdrv = def_display->driver;
|
||||
|
||||
ret = dssdrv->enable(def_display);
|
||||
if (ret) {
|
||||
/* Here we are not considering a error
|
||||
* as display may be enabled by frame
|
||||
|
@ -2559,21 +2546,21 @@ static int __init omap_vout_probe(struct platform_device *pdev)
|
|||
if (def_display->caps &
|
||||
OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
|
||||
#ifdef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE
|
||||
if (def_display->enable_te)
|
||||
def_display->enable_te(def_display, 1);
|
||||
if (def_display->set_update_mode)
|
||||
def_display->set_update_mode(def_display,
|
||||
if (dssdrv->enable_te)
|
||||
dssdrv->enable_te(def_display, 1);
|
||||
if (dssdrv->set_update_mode)
|
||||
dssdrv->set_update_mode(def_display,
|
||||
OMAP_DSS_UPDATE_AUTO);
|
||||
#else /* MANUAL_UPDATE */
|
||||
if (def_display->enable_te)
|
||||
def_display->enable_te(def_display, 0);
|
||||
if (def_display->set_update_mode)
|
||||
def_display->set_update_mode(def_display,
|
||||
if (dssdrv->enable_te)
|
||||
dssdrv->enable_te(def_display, 0);
|
||||
if (dssdrv->set_update_mode)
|
||||
dssdrv->set_update_mode(def_display,
|
||||
OMAP_DSS_UPDATE_MANUAL);
|
||||
#endif
|
||||
} else {
|
||||
if (def_display->set_update_mode)
|
||||
def_display->set_update_mode(def_display,
|
||||
if (dssdrv->set_update_mode)
|
||||
dssdrv->set_update_mode(def_display,
|
||||
OMAP_DSS_UPDATE_AUTO);
|
||||
}
|
||||
}
|
||||
|
@ -2592,8 +2579,8 @@ static int __init omap_vout_probe(struct platform_device *pdev)
|
|||
for (i = 0; i < vid_dev->num_displays; i++) {
|
||||
struct omap_dss_device *display = vid_dev->displays[i];
|
||||
|
||||
if (display->update)
|
||||
display->update(display, 0, 0,
|
||||
if (display->driver->update)
|
||||
display->driver->update(display, 0, 0,
|
||||
display->panel.timings.x_res,
|
||||
display->panel.timings.y_res);
|
||||
}
|
||||
|
@ -2608,8 +2595,8 @@ static int __init omap_vout_probe(struct platform_device *pdev)
|
|||
if (ovl->manager && ovl->manager->device)
|
||||
def_display = ovl->manager->device;
|
||||
|
||||
if (def_display)
|
||||
def_display->disable(def_display);
|
||||
if (def_display && def_display->driver)
|
||||
def_display->driver->disable(def_display);
|
||||
}
|
||||
probe_err0:
|
||||
kfree(vid_dev);
|
||||
|
|
|
@ -267,6 +267,21 @@ hauppauge_tuner[] =
|
|||
{ TUNER_ABSENT, "Xceive XC4000"},
|
||||
{ TUNER_ABSENT, "Dibcom 7070"},
|
||||
{ TUNER_PHILIPS_TDA8290, "NXP 18271C2"},
|
||||
{ TUNER_ABSENT, "unknown"},
|
||||
{ TUNER_ABSENT, "unknown"},
|
||||
{ TUNER_ABSENT, "unknown"},
|
||||
{ TUNER_ABSENT, "unknown"},
|
||||
/* 160-169 */
|
||||
{ TUNER_ABSENT, "unknown"},
|
||||
{ TUNER_ABSENT, "unknown"},
|
||||
{ TUNER_ABSENT, "unknown"},
|
||||
{ TUNER_ABSENT, "unknown"},
|
||||
{ TUNER_ABSENT, "unknown"},
|
||||
{ TUNER_ABSENT, "unknown"},
|
||||
{ TUNER_ABSENT, "unknown"},
|
||||
{ TUNER_ABSENT, "unknown"},
|
||||
{ TUNER_PHILIPS_FQ1236_MK5, "TCL M30WTP-4N-E"},
|
||||
{ TUNER_ABSENT, "unknown"},
|
||||
};
|
||||
|
||||
/* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are
|
||||
|
|
|
@ -122,8 +122,8 @@ static struct uvc_control_info uvc_ctrls[] = {
|
|||
.selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
|
||||
.index = 10,
|
||||
.size = 1,
|
||||
.flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
|
||||
| UVC_CONTROL_RESTORE,
|
||||
.flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
|
||||
| UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
|
||||
},
|
||||
{
|
||||
.entity = UVC_GUID_UVC_PROCESSING,
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include "uvc.h"
|
||||
|
||||
unsigned int uvc_trace_param;
|
||||
unsigned int uvc_gadget_trace_param;
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* Function descriptors
|
||||
|
@ -656,6 +656,6 @@ uvc_bind_config(struct usb_configuration *c,
|
|||
return ret;
|
||||
}
|
||||
|
||||
module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR);
|
||||
module_param_named(trace, uvc_gadget_trace_param, uint, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(trace, "Trace level bitmask");
|
||||
|
||||
|
|
|
@ -107,11 +107,11 @@ struct uvc_streaming_control {
|
|||
#define UVC_WARN_MINMAX 0
|
||||
#define UVC_WARN_PROBE_DEF 1
|
||||
|
||||
extern unsigned int uvc_trace_param;
|
||||
extern unsigned int uvc_gadget_trace_param;
|
||||
|
||||
#define uvc_trace(flag, msg...) \
|
||||
do { \
|
||||
if (uvc_trace_param & flag) \
|
||||
if (uvc_gadget_trace_param & flag) \
|
||||
printk(KERN_DEBUG "uvcvideo: " msg); \
|
||||
} while (0)
|
||||
|
||||
|
@ -220,16 +220,10 @@ struct uvc_file_handle
|
|||
#define to_uvc_file_handle(handle) \
|
||||
container_of(handle, struct uvc_file_handle, vfh)
|
||||
|
||||
extern struct v4l2_file_operations uvc_v4l2_fops;
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
* Functions
|
||||
*/
|
||||
|
||||
extern int uvc_video_enable(struct uvc_video *video, int enable);
|
||||
extern int uvc_video_init(struct uvc_video *video);
|
||||
extern int uvc_video_pump(struct uvc_video *video);
|
||||
|
||||
extern void uvc_endpoint_stream(struct uvc_device *dev);
|
||||
|
||||
extern void uvc_function_connect(struct uvc_device *uvc);
|
||||
|
|
|
@ -78,7 +78,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
|
||||
static void
|
||||
uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
|
||||
{
|
||||
mutex_init(&queue->mutex);
|
||||
spin_lock_init(&queue->irqlock);
|
||||
|
@ -87,6 +88,28 @@ void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
|
|||
queue->type = type;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the video buffers.
|
||||
*
|
||||
* This function must be called with the queue lock held.
|
||||
*/
|
||||
static int uvc_free_buffers(struct uvc_video_queue *queue)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < queue->count; ++i) {
|
||||
if (queue->buffer[i].vma_use_count != 0)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (queue->count) {
|
||||
vfree(queue->mem);
|
||||
queue->count = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate the video buffers.
|
||||
*
|
||||
|
@ -95,8 +118,9 @@ void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
|
|||
*
|
||||
* Buffers will be individually mapped, so they must all be page aligned.
|
||||
*/
|
||||
int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers,
|
||||
unsigned int buflength)
|
||||
static int
|
||||
uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers,
|
||||
unsigned int buflength)
|
||||
{
|
||||
unsigned int bufsize = PAGE_ALIGN(buflength);
|
||||
unsigned int i;
|
||||
|
@ -150,28 +174,6 @@ int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the video buffers.
|
||||
*
|
||||
* This function must be called with the queue lock held.
|
||||
*/
|
||||
int uvc_free_buffers(struct uvc_video_queue *queue)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < queue->count; ++i) {
|
||||
if (queue->buffer[i].vma_use_count != 0)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (queue->count) {
|
||||
vfree(queue->mem);
|
||||
queue->count = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __uvc_query_buffer(struct uvc_buffer *buf,
|
||||
struct v4l2_buffer *v4l2_buf)
|
||||
{
|
||||
|
@ -195,8 +197,8 @@ static void __uvc_query_buffer(struct uvc_buffer *buf,
|
|||
}
|
||||
}
|
||||
|
||||
int uvc_query_buffer(struct uvc_video_queue *queue,
|
||||
struct v4l2_buffer *v4l2_buf)
|
||||
static int
|
||||
uvc_query_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *v4l2_buf)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
@ -217,8 +219,8 @@ int uvc_query_buffer(struct uvc_video_queue *queue,
|
|||
* Queue a video buffer. Attempting to queue a buffer that has already been
|
||||
* queued will return -EINVAL.
|
||||
*/
|
||||
int uvc_queue_buffer(struct uvc_video_queue *queue,
|
||||
struct v4l2_buffer *v4l2_buf)
|
||||
static int
|
||||
uvc_queue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *v4l2_buf)
|
||||
{
|
||||
struct uvc_buffer *buf;
|
||||
unsigned long flags;
|
||||
|
@ -298,8 +300,9 @@ static int uvc_queue_waiton(struct uvc_buffer *buf, int nonblocking)
|
|||
* Dequeue a video buffer. If nonblocking is false, block until a buffer is
|
||||
* available.
|
||||
*/
|
||||
int uvc_dequeue_buffer(struct uvc_video_queue *queue,
|
||||
struct v4l2_buffer *v4l2_buf, int nonblocking)
|
||||
static int
|
||||
uvc_dequeue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *v4l2_buf,
|
||||
int nonblocking)
|
||||
{
|
||||
struct uvc_buffer *buf;
|
||||
int ret = 0;
|
||||
|
@ -359,8 +362,9 @@ int uvc_dequeue_buffer(struct uvc_video_queue *queue,
|
|||
* This function implements video queue polling and is intended to be used by
|
||||
* the device poll handler.
|
||||
*/
|
||||
unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file,
|
||||
poll_table *wait)
|
||||
static unsigned int
|
||||
uvc_queue_poll(struct uvc_video_queue *queue, struct file *file,
|
||||
poll_table *wait)
|
||||
{
|
||||
struct uvc_buffer *buf;
|
||||
unsigned int mask = 0;
|
||||
|
@ -407,7 +411,8 @@ static struct vm_operations_struct uvc_vm_ops = {
|
|||
* This function implements video buffer memory mapping and is intended to be
|
||||
* used by the device mmap handler.
|
||||
*/
|
||||
int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
|
||||
static int
|
||||
uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
|
||||
{
|
||||
struct uvc_buffer *uninitialized_var(buffer);
|
||||
struct page *page;
|
||||
|
@ -457,6 +462,42 @@ int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cancel the video buffers queue.
|
||||
*
|
||||
* Cancelling the queue marks all buffers on the irq queue as erroneous,
|
||||
* wakes them up and removes them from the queue.
|
||||
*
|
||||
* If the disconnect parameter is set, further calls to uvc_queue_buffer will
|
||||
* fail with -ENODEV.
|
||||
*
|
||||
* This function acquires the irq spinlock and can be called from interrupt
|
||||
* context.
|
||||
*/
|
||||
static void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect)
|
||||
{
|
||||
struct uvc_buffer *buf;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&queue->irqlock, flags);
|
||||
while (!list_empty(&queue->irqqueue)) {
|
||||
buf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
|
||||
queue);
|
||||
list_del(&buf->queue);
|
||||
buf->state = UVC_BUF_STATE_ERROR;
|
||||
wake_up(&buf->wait);
|
||||
}
|
||||
/* This must be protected by the irqlock spinlock to avoid race
|
||||
* conditions between uvc_queue_buffer and the disconnection event that
|
||||
* could result in an interruptible wait in uvc_dequeue_buffer. Do not
|
||||
* blindly replace this logic by checking for the UVC_DEV_DISCONNECTED
|
||||
* state outside the queue code.
|
||||
*/
|
||||
if (disconnect)
|
||||
queue->flags |= UVC_QUEUE_DISCONNECTED;
|
||||
spin_unlock_irqrestore(&queue->irqlock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable or disable the video buffers queue.
|
||||
*
|
||||
|
@ -474,7 +515,7 @@ int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
|
|||
* This function can't be called from interrupt context. Use
|
||||
* uvc_queue_cancel() instead.
|
||||
*/
|
||||
int uvc_queue_enable(struct uvc_video_queue *queue, int enable)
|
||||
static int uvc_queue_enable(struct uvc_video_queue *queue, int enable)
|
||||
{
|
||||
unsigned int i;
|
||||
int ret = 0;
|
||||
|
@ -503,44 +544,8 @@ int uvc_queue_enable(struct uvc_video_queue *queue, int enable)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cancel the video buffers queue.
|
||||
*
|
||||
* Cancelling the queue marks all buffers on the irq queue as erroneous,
|
||||
* wakes them up and removes them from the queue.
|
||||
*
|
||||
* If the disconnect parameter is set, further calls to uvc_queue_buffer will
|
||||
* fail with -ENODEV.
|
||||
*
|
||||
* This function acquires the irq spinlock and can be called from interrupt
|
||||
* context.
|
||||
*/
|
||||
void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect)
|
||||
{
|
||||
struct uvc_buffer *buf;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&queue->irqlock, flags);
|
||||
while (!list_empty(&queue->irqqueue)) {
|
||||
buf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
|
||||
queue);
|
||||
list_del(&buf->queue);
|
||||
buf->state = UVC_BUF_STATE_ERROR;
|
||||
wake_up(&buf->wait);
|
||||
}
|
||||
/* This must be protected by the irqlock spinlock to avoid race
|
||||
* conditions between uvc_queue_buffer and the disconnection event that
|
||||
* could result in an interruptible wait in uvc_dequeue_buffer. Do not
|
||||
* blindly replace this logic by checking for the UVC_DEV_DISCONNECTED
|
||||
* state outside the queue code.
|
||||
*/
|
||||
if (disconnect)
|
||||
queue->flags |= UVC_QUEUE_DISCONNECTED;
|
||||
spin_unlock_irqrestore(&queue->irqlock, flags);
|
||||
}
|
||||
|
||||
struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
|
||||
struct uvc_buffer *buf)
|
||||
static struct uvc_buffer *
|
||||
uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf)
|
||||
{
|
||||
struct uvc_buffer *nextbuf;
|
||||
unsigned long flags;
|
||||
|
@ -568,7 +573,7 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
|
|||
return nextbuf;
|
||||
}
|
||||
|
||||
struct uvc_buffer *uvc_queue_head(struct uvc_video_queue *queue)
|
||||
static struct uvc_buffer *uvc_queue_head(struct uvc_video_queue *queue)
|
||||
{
|
||||
struct uvc_buffer *buf = NULL;
|
||||
|
||||
|
|
|
@ -58,30 +58,10 @@ struct uvc_video_queue {
|
|||
struct list_head irqqueue;
|
||||
};
|
||||
|
||||
extern void uvc_queue_init(struct uvc_video_queue *queue,
|
||||
enum v4l2_buf_type type);
|
||||
extern int uvc_alloc_buffers(struct uvc_video_queue *queue,
|
||||
unsigned int nbuffers, unsigned int buflength);
|
||||
extern int uvc_free_buffers(struct uvc_video_queue *queue);
|
||||
extern int uvc_query_buffer(struct uvc_video_queue *queue,
|
||||
struct v4l2_buffer *v4l2_buf);
|
||||
extern int uvc_queue_buffer(struct uvc_video_queue *queue,
|
||||
struct v4l2_buffer *v4l2_buf);
|
||||
extern int uvc_dequeue_buffer(struct uvc_video_queue *queue,
|
||||
struct v4l2_buffer *v4l2_buf, int nonblocking);
|
||||
extern int uvc_queue_enable(struct uvc_video_queue *queue, int enable);
|
||||
extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect);
|
||||
extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
|
||||
struct uvc_buffer *buf);
|
||||
extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue,
|
||||
struct file *file, poll_table *wait);
|
||||
extern int uvc_queue_mmap(struct uvc_video_queue *queue,
|
||||
struct vm_area_struct *vma);
|
||||
static inline int uvc_queue_streaming(struct uvc_video_queue *queue)
|
||||
{
|
||||
return queue->flags & UVC_QUEUE_STREAMING;
|
||||
}
|
||||
extern struct uvc_buffer *uvc_queue_head(struct uvc_video_queue *queue);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
|
|
@ -363,7 +363,7 @@ uvc_v4l2_poll(struct file *file, poll_table *wait)
|
|||
return mask;
|
||||
}
|
||||
|
||||
struct v4l2_file_operations uvc_v4l2_fops = {
|
||||
static struct v4l2_file_operations uvc_v4l2_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = uvc_v4l2_open,
|
||||
.release = uvc_v4l2_release,
|
||||
|
|
|
@ -271,7 +271,7 @@ uvc_video_alloc_requests(struct uvc_video *video)
|
|||
* This function fills the available USB requests (listed in req_free) with
|
||||
* video data from the queued buffers.
|
||||
*/
|
||||
int
|
||||
static int
|
||||
uvc_video_pump(struct uvc_video *video)
|
||||
{
|
||||
struct usb_request *req;
|
||||
|
@ -328,7 +328,7 @@ uvc_video_pump(struct uvc_video *video)
|
|||
/*
|
||||
* Enable or disable the video stream.
|
||||
*/
|
||||
int
|
||||
static int
|
||||
uvc_video_enable(struct uvc_video *video, int enable)
|
||||
{
|
||||
unsigned int i;
|
||||
|
@ -367,7 +367,7 @@ uvc_video_enable(struct uvc_video *video, int enable)
|
|||
/*
|
||||
* Initialize the UVC video stream.
|
||||
*/
|
||||
int
|
||||
static int
|
||||
uvc_video_init(struct uvc_video *video)
|
||||
{
|
||||
INIT_LIST_HEAD(&video->req_free);
|
||||
|
|
|
@ -28,10 +28,10 @@
|
|||
#include "config.c"
|
||||
#include "epautoconf.c"
|
||||
|
||||
#include "f_uvc.c"
|
||||
#include "uvc_queue.c"
|
||||
#include "uvc_v4l2.c"
|
||||
#include "uvc_video.c"
|
||||
#include "uvc_v4l2.c"
|
||||
#include "f_uvc.c"
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* Device descriptor
|
||||
|
|
|
@ -130,6 +130,7 @@
|
|||
#define TUNER_PHILIPS_CU1216L 82
|
||||
#define TUNER_NXP_TDA18271 83
|
||||
#define TUNER_SONY_BTF_PXN01Z 84
|
||||
#define TUNER_PHILIPS_FQ1236_MK5 85 /* NTSC, TDA9885, no FM radio */
|
||||
|
||||
/* tv card specific */
|
||||
#define TDA9887_PRESENT (1<<0)
|
||||
|
|
Loading…
Reference in a new issue