summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-07-24 16:19:39 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-07-24 16:19:39 -0300
commit2fd774d86f3c8fe4d2653967fbb2e292fe1ef581 (patch)
tree8ba8e2b482f16d305ca75211df2531f0cdcaa2ac /linux/drivers/media/video
parent54a9310128f01c9c97607d99f52ced91e050e834 (diff)
parentd35fd05efa549e444999c3cc2260906c51b0d4b9 (diff)
downloadmediapointer-dvb-s2-2fd774d86f3c8fe4d2653967fbb2e292fe1ef581.tar.gz
mediapointer-dvb-s2-2fd774d86f3c8fe4d2653967fbb2e292fe1ef581.tar.bz2
merge: http://linuxtv.org/hg/~awalls/v4l-dvb
From: Mauro Carvalho Chehab <mchehab@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'linux/drivers/media/video')
-rw-r--r--linux/drivers/media/video/pxa_camera.c2
-rw-r--r--linux/drivers/media/video/uvc/uvc_driver.c25
-rw-r--r--linux/drivers/media/video/uvc/uvc_video.c3
-rw-r--r--linux/drivers/media/video/uvc/uvcvideo.h1
-rw-r--r--linux/drivers/media/video/zr364xx.c126
5 files changed, 114 insertions, 43 deletions
diff --git a/linux/drivers/media/video/pxa_camera.c b/linux/drivers/media/video/pxa_camera.c
index 8964d60cd..3f1b63e4e 100644
--- a/linux/drivers/media/video/pxa_camera.c
+++ b/linux/drivers/media/video/pxa_camera.c
@@ -1591,6 +1591,7 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev)
pcdev->mclk = 20000000;
}
+ pcdev->soc_host.dev = &pdev->dev;
pcdev->mclk_divisor = mclk_get_divisor(pcdev);
INIT_LIST_HEAD(&pcdev->capture);
@@ -1656,7 +1657,6 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev)
pcdev->soc_host.drv_name = PXA_CAM_DRV_NAME;
pcdev->soc_host.ops = &pxa_soc_camera_host_ops;
pcdev->soc_host.priv = pcdev;
- pcdev->soc_host.dev = &pdev->dev;
pcdev->soc_host.nr = pdev->id;
err = soc_camera_host_register(&pcdev->soc_host);
diff --git a/linux/drivers/media/video/uvc/uvc_driver.c b/linux/drivers/media/video/uvc/uvc_driver.c
index f7b76884d..1d09751a3 100644
--- a/linux/drivers/media/video/uvc/uvc_driver.c
+++ b/linux/drivers/media/video/uvc/uvc_driver.c
@@ -1851,11 +1851,29 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_STREAM_NO_FID },
- /* ViMicro */
+ /* ViMicro Vega */
{ .match_flags = USB_DEVICE_ID_MATCH_VENDOR
| USB_DEVICE_ID_MATCH_INT_INFO,
.idVendor = 0x0ac8,
- .idProduct = 0x0000,
+ .idProduct = 0x332d,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
+ /* ViMicro - Minoru3D */
+ { .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x0ac8,
+ .idProduct = 0x3410,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
+ /* ViMicro Venus - Minoru3D */
+ { .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x0ac8,
+ .idProduct = 0x3420,
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
@@ -1868,7 +1886,8 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ .driver_info = UVC_QUIRK_PROBE_MINMAX
+ | UVC_QUIRK_PROBE_DEF },
/* Syntek (HP Spartan) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/linux/drivers/media/video/uvc/uvc_video.c b/linux/drivers/media/video/uvc/uvc_video.c
index c833e984e..f4f4e1bb3 100644
--- a/linux/drivers/media/video/uvc/uvc_video.c
+++ b/linux/drivers/media/video/uvc/uvc_video.c
@@ -128,6 +128,9 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
if (data == NULL)
return -ENOMEM;
+ if ((video->dev->quirks & UVC_QUIRK_PROBE_DEF) && query == UVC_GET_DEF)
+ return -EIO;
+
ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum,
probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data,
size, UVC_CTRL_STREAMING_TIMEOUT);
diff --git a/linux/drivers/media/video/uvc/uvcvideo.h b/linux/drivers/media/video/uvc/uvcvideo.h
index 4887650c9..e700bdc20 100644
--- a/linux/drivers/media/video/uvc/uvcvideo.h
+++ b/linux/drivers/media/video/uvc/uvcvideo.h
@@ -157,6 +157,7 @@ struct uvc_xu_control {
#define UVC_QUIRK_STREAM_NO_FID 0x00000010
#define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020
#define UVC_QUIRK_FIX_BANDWIDTH 0x00000080
+#define UVC_QUIRK_PROBE_DEF 0x00000100
/* Format flags */
#define UVC_FMT_FLAG_COMPRESSED 0x00000001
diff --git a/linux/drivers/media/video/zr364xx.c b/linux/drivers/media/video/zr364xx.c
index 084f97f6a..c298ce625 100644
--- a/linux/drivers/media/video/zr364xx.c
+++ b/linux/drivers/media/video/zr364xx.c
@@ -44,14 +44,14 @@
/* Version Information */
#define DRIVER_VERSION "v0.73"
-#define ZR364_VERSION_CODE KERNEL_VERSION(0, 7, 3)
+#define ZR364XX_VERSION_CODE KERNEL_VERSION(0, 7, 3)
#define DRIVER_AUTHOR "Antoine Jacquet, http://royale.zerezo.com/"
#define DRIVER_DESC "Zoran 364xx"
/* Camera */
#define FRAMES 1
-#define MAX_FRAME_SIZE 100000
+#define MAX_FRAME_SIZE 200000
#define BUFFER_SIZE 0x1000
#define CTRL_TIMEOUT 500
@@ -67,6 +67,13 @@
} \
} while (0)
+/*#define FULL_DEBUG 1*/
+#ifdef FULL_DEBUG
+#define _DBG DBG
+#else
+#define _DBG(fmt, args...)
+#endif
+
/* Init methods, need to find nicer names for these
* the exact names of the chipsets would be the best if someone finds it */
#define METHOD0 0
@@ -376,7 +383,7 @@ static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
static void free_buffer(struct videobuf_queue *vq, struct zr364xx_buffer *buf)
{
- DBG("%s\n", __func__);
+ _DBG("%s\n", __func__);
if (in_interrupt())
BUG();
@@ -429,7 +436,7 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
vb);
struct zr364xx_camera *cam = vq->priv_data;
- DBG("%s\n", __func__);
+ _DBG("%s\n", __func__);
buf->vb.state = VIDEOBUF_QUEUED;
list_add_tail(&buf->vb.queue, &cam->vidq.active);
@@ -441,7 +448,7 @@ static void buffer_release(struct videobuf_queue *vq,
struct zr364xx_buffer *buf = container_of(vb, struct zr364xx_buffer,
vb);
- DBG("%s\n", __func__);
+ _DBG("%s\n", __func__);
free_buffer(vq, buf);
}
@@ -463,7 +470,7 @@ static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t count,
{
struct zr364xx_camera *cam = video_drvdata(file);
- DBG("%s\n", __func__);
+ _DBG("%s\n", __func__);
if (!buf)
return -EINVAL;
@@ -583,7 +590,7 @@ static int zr364xx_read_video_callback(struct zr364xx_camera *cam,
int i = 0;
unsigned char *ptr = NULL;
- /*DBG("buffer to user\n");*/
+ _DBG("buffer to user\n");
idx = cam->cur_frame;
frm = &cam->buffer.frame[idx];
@@ -601,12 +608,6 @@ static int zr364xx_read_video_callback(struct zr364xx_camera *cam,
return -EINVAL;
}
- if (frm->lpvbits == NULL) {
- DBG("%s: frame buffer == NULL.%p %p %d\n", __func__,
- frm, cam, idx);
- return -ENOMEM;
- }
-
psrc = (u8 *)pipe_info->transfer_buffer;
ptr = pdest = frm->lpvbits;
@@ -614,7 +615,7 @@ static int zr364xx_read_video_callback(struct zr364xx_camera *cam,
frm->ulState = ZR364XX_READ_FRAME;
frm->cur_size = 0;
- DBG("jpeg header, ");
+ _DBG("jpeg header, ");
memcpy(ptr, header1, sizeof(header1));
ptr += sizeof(header1);
header3 = 0;
@@ -632,21 +633,28 @@ static int zr364xx_read_video_callback(struct zr364xx_camera *cam,
memcpy(ptr, psrc + 128,
purb->actual_length - 128);
ptr += purb->actual_length - 128;
- DBG("header : %d %d %d %d %d %d %d %d %d\n",
+ _DBG("header : %d %d %d %d %d %d %d %d %d\n",
psrc[0], psrc[1], psrc[2],
psrc[3], psrc[4], psrc[5],
psrc[6], psrc[7], psrc[8]);
frm->cur_size = ptr - pdest;
} else {
- pdest += frm->cur_size;
- memcpy(pdest, psrc, purb->actual_length);
- frm->cur_size += purb->actual_length;
+ if (frm->cur_size + purb->actual_length > MAX_FRAME_SIZE) {
+ dev_info(&cam->udev->dev,
+ "%s: buffer (%d bytes) too small to hold "
+ "frame data. Discarding frame data.\n",
+ __func__, MAX_FRAME_SIZE);
+ } else {
+ pdest += frm->cur_size;
+ memcpy(pdest, psrc, purb->actual_length);
+ frm->cur_size += purb->actual_length;
+ }
}
- /*DBG("cur_size %lu urb size %d\n", frm->cur_size,
+ /*_DBG("cur_size %lu urb size %d\n", frm->cur_size,
purb->actual_length);*/
if (purb->actual_length < pipe_info->transfer_size) {
- DBG("****************Buffer[%d]full*************\n", idx);
+ _DBG("****************Buffer[%d]full*************\n", idx);
cam->last_frame = cam->cur_frame;
cam->cur_frame++;
/* end of system frame ring buffer, start at zero */
@@ -681,7 +689,7 @@ static int zr364xx_read_video_callback(struct zr364xx_camera *cam,
if (cam->skip)
cam->skip--;
else {
- DBG("jpeg(%lu): %d %d %d %d %d %d %d %d\n",
+ _DBG("jpeg(%lu): %d %d %d %d %d %d %d %d\n",
frm->cur_size,
pdest[0], pdest[1], pdest[2], pdest[3],
pdest[4], pdest[5], pdest[6], pdest[7]);
@@ -708,7 +716,7 @@ static int res_get(struct zr364xx_camera *cam)
}
/* it's free, grab it */
cam->resources = 1;
- DBG("res: get\n");
+ _DBG("res: get\n");
mutex_unlock(&cam->lock);
return 1;
}
@@ -723,7 +731,7 @@ static void res_free(struct zr364xx_camera *cam)
mutex_lock(&cam->lock);
cam->resources = 0;
mutex_unlock(&cam->lock);
- DBG("res: put\n");
+ _DBG("res: put\n");
}
static int zr364xx_vidioc_querycap(struct file *file, void *priv,
@@ -735,7 +743,7 @@ static int zr364xx_vidioc_querycap(struct file *file, void *priv,
strlcpy(cap->card, cam->udev->product, sizeof(cap->card));
strlcpy(cap->bus_info, dev_name(&cam->udev->dev),
sizeof(cap->bus_info));
- cap->version = ZR364_VERSION_CODE;
+ cap->version = ZR364XX_VERSION_CODE;
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_READWRITE |
V4L2_CAP_STREAMING;
@@ -875,9 +883,13 @@ static int zr364xx_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
return -EINVAL;
}
+ if (!(f->fmt.pix.width == 160 && f->fmt.pix.height == 120) &&
+ !(f->fmt.pix.width == 640 && f->fmt.pix.height == 480)) {
+ f->fmt.pix.width = 320;
+ f->fmt.pix.height = 240;
+ }
+
f->fmt.pix.field = V4L2_FIELD_NONE;
- f->fmt.pix.width = cam->width;
- f->fmt.pix.height = cam->height;
f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
f->fmt.pix.colorspace = 0;
@@ -908,7 +920,6 @@ static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
return 0;
}
-/* Lamarque TODO: implement changing resolution on the fly */
static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
@@ -916,6 +927,7 @@ static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct videobuf_queue *q = &cam->vb_vidq;
char pixelformat_name[5];
int ret = zr364xx_vidioc_try_fmt_vid_cap(file, cam, f);
+ int i;
if (ret < 0)
return ret;
@@ -928,15 +940,55 @@ static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
goto out;
}
- f->fmt.pix.field = V4L2_FIELD_NONE;
- f->fmt.pix.width = cam->width;
- f->fmt.pix.height = cam->height;
+ if (res_check(cam)) {
+ DBG("%s can't change format after started\n", __func__);
+ ret = -EBUSY;
+ goto out;
+ }
+
+ cam->width = f->fmt.pix.width;
+ cam->height = f->fmt.pix.height;
+ dev_info(&cam->udev->dev, "%s: %dx%d mode selected\n", __func__,
+ cam->width, cam->height);
f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
f->fmt.pix.colorspace = 0;
f->fmt.pix.priv = 0;
cam->vb_vidq.field = f->fmt.pix.field;
cam->mode.color = V4L2_PIX_FMT_JPEG;
+
+ if (f->fmt.pix.width == 160 && f->fmt.pix.height == 120)
+ mode = 1;
+ else if (f->fmt.pix.width == 640 && f->fmt.pix.height == 480)
+ mode = 2;
+ else
+ mode = 0;
+
+ m0d1[0] = mode;
+ m1[2].value = 0xf000 + mode;
+ m2[1].value = 0xf000 + mode;
+ header2[437] = cam->height / 256;
+ header2[438] = cam->height % 256;
+ header2[439] = cam->width / 256;
+ header2[440] = cam->width % 256;
+
+ for (i = 0; init[cam->method][i].size != -1; i++) {
+ ret =
+ send_control_msg(cam->udev, 1, init[cam->method][i].value,
+ 0, init[cam->method][i].bytes,
+ init[cam->method][i].size);
+ if (ret < 0) {
+ dev_err(&cam->udev->dev,
+ "error during resolution change sequence: %d\n", i);
+ goto out;
+ }
+ }
+
+ /* Added some delay here, since opening/closing the camera quickly,
+ * like Ekiga does during its startup, can crash the webcam
+ */
+ mdelay(100);
+ cam->skip = 2;
ret = 0;
out:
@@ -973,7 +1025,7 @@ static int zr364xx_vidioc_qbuf(struct file *file,
{
int rc;
struct zr364xx_camera *cam = video_drvdata(file);
- DBG("%s\n", __func__);
+ _DBG("%s\n", __func__);
rc = videobuf_qbuf(&cam->vb_vidq, p);
return rc;
}
@@ -984,7 +1036,7 @@ static int zr364xx_vidioc_dqbuf(struct file *file,
{
int rc;
struct zr364xx_camera *cam = video_drvdata(file);
- DBG("%s\n", __func__);
+ _DBG("%s\n", __func__);
rc = videobuf_dqbuf(&cam->vb_vidq, p, file->f_flags & O_NONBLOCK);
return rc;
}
@@ -996,7 +1048,7 @@ static void read_pipe_completion(struct urb *purb)
int pipe;
pipe_info = purb->context;
- /*DBG("%s %p, status %d\n", __func__, purb, purb->status);*/
+ _DBG("%s %p, status %d\n", __func__, purb, purb->status);
if (pipe_info == NULL) {
printk(KERN_ERR KBUILD_MODNAME ": no context!\n");
return;
@@ -1107,7 +1159,6 @@ static void zr364xx_stop_readpipe(struct zr364xx_camera *cam)
pipe_info->stream_urb = NULL;
}
}
- DBG("stop read pipe\n");
return;
}
@@ -1124,6 +1175,7 @@ static int zr364xx_start_acquire(struct zr364xx_camera *cam)
cam->buffer.frame[j].ulState = ZR364XX_READ_IDLE;
cam->buffer.frame[j].cur_size = 0;
}
+ cam->b_acquire = 1;
return 0;
}
@@ -1166,11 +1218,9 @@ static int zr364xx_vidioc_streamon(struct file *file, void *priv,
res = videobuf_streamon(&cam->vb_vidq);
if (res == 0) {
zr364xx_start_acquire(cam);
- cam->b_acquire = 1;
} else {
res_free(cam);
}
- DBG("%s: %d\n", __func__, res);
return res;
}
@@ -1282,8 +1332,6 @@ static void zr364xx_destroy(struct zr364xx_camera *cam)
/* release transfer buffer */
kfree(cam->pipe->transfer_buffer);
cam->pipe->transfer_buffer = NULL;
-
- DBG("%s\n", __func__);
mutex_unlock(&cam->open_lock);
kfree(cam);
cam = NULL;
@@ -1364,7 +1412,7 @@ static unsigned int zr364xx_poll(struct file *file,
{
struct zr364xx_camera *cam = video_drvdata(file);
struct videobuf_queue *q = &cam->vb_vidq;
- DBG("%s\n", __func__);
+ _DBG("%s\n", __func__);
if (cam->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return POLLERR;