From 24c3c41584b9331be5e0d18d46943729a5bd2d4e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 7 Jan 2009 22:49:25 -0300 Subject: V4L/DVB (10192): em28xx: fix input selection em28xx were trying to access the third input entry, even for boards that don't support it. This patch reviews the input mux selection fixing this bug and a few other troubles, like not validating the input on one userspace ioctl. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-video.c | 41 +++++++++++++++++-------------- 1 file changed, 23 insertions(+), 18 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 416b691c33c..d40650655f7 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -886,10 +886,10 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) if (0 == INPUT(i)->type) return -EINVAL; - mutex_lock(&dev->lock); - - video_mux(dev, i); + dev->ctl_input = i; + mutex_lock(&dev->lock); + video_mux(dev, dev->ctl_input); mutex_unlock(&dev->lock); return 0; } @@ -939,6 +939,12 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; + + if (a->index >= MAX_EM28XX_INPUT) + return -EINVAL; + if (0 == INPUT(a->index)->type) + return -EINVAL; + mutex_lock(&dev->lock); dev->ctl_ainput = INPUT(a->index)->amux; @@ -1957,9 +1963,22 @@ int em28xx_register_analog_devices(struct em28xx *dev) (EM28XX_VERSION_CODE >> 16) & 0xff, (EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff); + /* set default norm */ + dev->norm = em28xx_video_template.current_norm; + dev->width = norm_maxw(dev); + dev->height = norm_maxh(dev); + dev->interlaced = EM28XX_INTERLACED_DEFAULT; + dev->hscale = 0; + dev->vscale = 0; + dev->ctl_input = 0; + /* Analog specific initialization */ dev->format = &format[0]; - video_mux(dev, 0); + video_mux(dev, dev->ctl_input); + + /* Audio defaults */ + dev->mute = 1; + dev->volume = 0x1f; /* enable vbi capturing */ @@ -1967,24 +1986,10 @@ int em28xx_register_analog_devices(struct em28xx *dev) /* em28xx_write_reg(dev, EM28XX_R0F_XCLK, 0x80); clk register */ em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51); - dev->mute = 1; /* maybe not the right place... */ - dev->volume = 0x1f; - em28xx_set_outfmt(dev); em28xx_colorlevels_set_default(dev); em28xx_compression_disable(dev); - /* set default norm */ - dev->norm = em28xx_video_template.current_norm; - dev->width = norm_maxw(dev); - dev->height = norm_maxh(dev); - dev->interlaced = EM28XX_INTERLACED_DEFAULT; - dev->hscale = 0; - dev->vscale = 0; - - /* FIXME: This is a very bad hack! Not all devices have TV on input 2 */ - dev->ctl_input = 2; - /* allocate and fill video video_device struct */ dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video"); if (!dev->vdev) { -- cgit v1.2.3 From 16e68d7cb8eb1c671867d2a0ecd4aa2e17124364 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Tue, 6 Jan 2009 22:40:56 -0300 Subject: V4L/DVB (10193): removed unused #include 's Removed unused #include 's in files below, drivers/media/video/cs5345.c drivers/media/video/pwc/pwc-if.c drivers/media/video/saa717x.c drivers/media/video/upd64031a.c drivers/media/video/upd64083.c drivers/media/video/uvc/uvc_ctrl.c drivers/media/video/uvc/uvc_driver.c drivers/media/video/uvc/uvc_queue.c drivers/media/video/uvc/uvc_video.c drivers/media/video/uvc/uvc_status.c Signed-off-by: Huang Weiyi Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cs5345.c | 1 - drivers/media/video/pwc/pwc-if.c | 1 - drivers/media/video/saa717x.c | 1 - drivers/media/video/upd64031a.c | 1 - drivers/media/video/upd64083.c | 1 - drivers/media/video/uvc/uvc_ctrl.c | 1 - drivers/media/video/uvc/uvc_driver.c | 1 - drivers/media/video/uvc/uvc_queue.c | 1 - drivers/media/video/uvc/uvc_status.c | 1 - drivers/media/video/uvc/uvc_video.c | 1 - 10 files changed, 10 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c index 14bebf8a116..87e91072627 100644 --- a/drivers/media/video/cs5345.c +++ b/drivers/media/video/cs5345.c @@ -18,7 +18,6 @@ */ -#include #include #include #include diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 39fbc970f43..0d810189dd8 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -62,7 +62,6 @@ #include #include #include -#include #include #include "pwc.h" diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c index 454ad1dd750..88c5e942f75 100644 --- a/drivers/media/video/saa717x.c +++ b/drivers/media/video/saa717x.c @@ -30,7 +30,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include #include #include diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c index 4f16effb530..f4522bb0891 100644 --- a/drivers/media/video/upd64031a.c +++ b/drivers/media/video/upd64031a.c @@ -21,7 +21,6 @@ */ -#include #include #include #include diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c index 4b712f69d1b..a5fb74bf240 100644 --- a/drivers/media/video/upd64083.c +++ b/drivers/media/video/upd64083.c @@ -21,7 +21,6 @@ * 02110-1301, USA. */ -#include #include #include #include diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index 2208165aa6f..c506068bec6 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c @@ -12,7 +12,6 @@ */ #include -#include #include #include #include diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 89d8bd10a85..a0537464987 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -24,7 +24,6 @@ */ #include -#include #include #include #include diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index 42546342e97..8f676f9d9e3 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c @@ -12,7 +12,6 @@ */ #include -#include #include #include #include diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c index 5d60b264d59..b482f4fc7b3 100644 --- a/drivers/media/video/uvc/uvc_status.c +++ b/drivers/media/video/uvc/uvc_status.c @@ -12,7 +12,6 @@ */ #include -#include #include #include #include diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index e7c31995527..6e9e30f174a 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -12,7 +12,6 @@ */ #include -#include #include #include #include -- cgit v1.2.3 From 2c2d264bb951c1a846b86431d3e784edfb79ab39 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 3 Jan 2009 19:12:40 -0300 Subject: V4L/DVB (10197): uvcvideo: Whitespace and comments cleanup, copyright updates. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_ctrl.c | 6 +- drivers/media/video/uvc/uvc_driver.c | 52 ++++---- drivers/media/video/uvc/uvc_isight.c | 2 + drivers/media/video/uvc/uvc_queue.c | 30 ++--- drivers/media/video/uvc/uvc_status.c | 2 +- drivers/media/video/uvc/uvc_v4l2.c | 10 +- drivers/media/video/uvc/uvc_video.c | 28 +++-- drivers/media/video/uvc/uvcvideo.h | 232 +++++++++++++++++------------------ 8 files changed, 184 insertions(+), 178 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index c506068bec6..d2576f6391c 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c @@ -1,7 +1,7 @@ /* * uvc_ctrl.c -- USB Video Class driver - Controls * - * Copyright (C) 2005-2008 + * Copyright (C) 2005-2009 * Laurent Pinchart (laurent.pinchart@skynet.be) * * This program is free software; you can redistribute it and/or modify @@ -28,7 +28,7 @@ #define UVC_CTRL_DATA_BACKUP 1 /* ------------------------------------------------------------------------ - * Control, formats, ... + * Controls */ static struct uvc_control_info uvc_ctrls[] = { @@ -634,7 +634,7 @@ static __s32 uvc_get_le_value(struct uvc_control_mapping *mapping, mask = (1 << bits) - 1; } - /* Sign-extend the value if needed */ + /* Sign-extend the value if needed. */ if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED) value |= -(value & (1 << (mapping->size - 1))); diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index a0537464987..20c16c4a62d 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -1,7 +1,7 @@ /* * uvc_driver.c -- USB Video Class driver * - * Copyright (C) 2005-2008 + * Copyright (C) 2005-2009 * Laurent Pinchart (laurent.pinchart@skynet.be) * * This program is free software; you can redistribute it and/or modify @@ -48,7 +48,7 @@ static unsigned int uvc_quirks_param; unsigned int uvc_trace_param; /* ------------------------------------------------------------------------ - * Control, formats, ... + * Video formats */ static struct uvc_format_desc uvc_fmts[] = { @@ -473,7 +473,7 @@ static int uvc_parse_format(struct uvc_device *dev, /* Several UVC chipsets screw up dwMaxVideoFrameBufferSize * completely. Observed behaviours range from setting the - * value to 1.1x the actual frame size of hardwiring the + * value to 1.1x the actual frame size to hardwiring the * 16 low bits to 0. This results in a higher than necessary * memory usage as well as a wrong image size information. For * uncompressed formats this can be fixed by computing the @@ -486,7 +486,7 @@ static int uvc_parse_format(struct uvc_device *dev, /* Some bogus devices report dwMinFrameInterval equal to * dwMaxFrameInterval and have dwFrameIntervalStep set to * zero. Setting all null intervals to 1 fixes the problem and - * some other divisions by zero which could happen. + * some other divisions by zero that could happen. */ for (i = 0; i < n; ++i) { interval = get_unaligned_le32(&buffer[26+4*i]); @@ -1199,13 +1199,13 @@ static void uvc_unregister_video(struct uvc_device *dev) * Scan the UVC descriptors to locate a chain starting at an Output Terminal * and containing the following units: * - * - a USB Streaming Output Terminal + * - one Output Terminal (USB Streaming or Display) * - zero or one Processing Unit * - zero, one or mode single-input Selector Units * - zero or one multiple-input Selector Units, provided all inputs are * connected to input terminals * - zero, one or mode single-input Extension Units - * - one Camera Input Terminal, or one or more External terminals. + * - one or more Input Terminals (Camera, External or USB Streaming) * * A side forward scan is made on each detected entity to check for additional * extension units. @@ -1530,10 +1530,6 @@ static int uvc_register_video(struct uvc_device *dev) /* Set the driver data before calling video_register_device, otherwise * uvc_v4l2_open might race us. - * - * FIXME: usb_set_intfdata hasn't been called so far. Is that a - * problem ? Does any function which could be called here get - * a pointer to the usb_interface ? */ dev->video.vdev = vdev; video_set_drvdata(vdev, &dev->video); @@ -1568,7 +1564,7 @@ void uvc_delete(struct kref *kref) struct uvc_device *dev = container_of(kref, struct uvc_device, kref); struct list_head *p, *n; - /* Unregister the video device */ + /* Unregister the video device. */ uvc_unregister_video(dev); usb_put_intf(dev->intf); usb_put_dev(dev->udev); @@ -1611,7 +1607,7 @@ static int uvc_probe(struct usb_interface *intf, uvc_trace(UVC_TRACE_PROBE, "Probing generic UVC device %s\n", udev->devpath); - /* Allocate memory for the device and initialize it */ + /* Allocate memory for the device and initialize it. */ if ((dev = kzalloc(sizeof *dev, GFP_KERNEL)) == NULL) return -ENOMEM; @@ -1632,7 +1628,7 @@ static int uvc_probe(struct usb_interface *intf, le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct)); - /* Parse the Video Class control descriptor */ + /* Parse the Video Class control descriptor. */ if (uvc_parse_control(dev) < 0) { uvc_trace(UVC_TRACE_PROBE, "Unable to parse UVC " "descriptors.\n"); @@ -1652,18 +1648,18 @@ static int uvc_probe(struct usb_interface *intf, "linux-uvc-devel mailing list.\n"); } - /* Initialize controls */ + /* Initialize controls. */ if (uvc_ctrl_init_device(dev) < 0) goto error; - /* Register the video devices */ + /* Register the video devices. */ if (uvc_register_video(dev) < 0) goto error; - /* Save our data pointer in the interface data */ + /* Save our data pointer in the interface data. */ usb_set_intfdata(intf, dev); - /* Initialize the interrupt URB */ + /* Initialize the interrupt URB. */ if ((ret = uvc_status_init(dev)) < 0) { uvc_printk(KERN_INFO, "Unable to initialize the status " "endpoint (%d), status interrupt will not be " @@ -1838,24 +1834,24 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0 }, /* Apple Built-In iSight */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, .idVendor = 0x05ac, .idProduct = 0x8501, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_MINMAX | UVC_QUIRK_BUILTIN_ISIGHT }, /* Genesys Logic USB 2.0 PC Camera */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x05e3, - .idProduct = 0x0505, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_STREAM_NO_FID }, + .idVendor = 0x05e3, + .idProduct = 0x0505, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_STREAM_NO_FID }, /* MT6227 */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, diff --git a/drivers/media/video/uvc/uvc_isight.c b/drivers/media/video/uvc/uvc_isight.c index 37bdefdbead..436f462685a 100644 --- a/drivers/media/video/uvc/uvc_isight.c +++ b/drivers/media/video/uvc/uvc_isight.c @@ -3,6 +3,8 @@ * * Copyright (C) 2006-2007 * Ivan N. Zlatev + * Copyright (C) 2008-2009 + * Laurent Pinchart * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index 8f676f9d9e3..0155752e4a5 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c @@ -1,7 +1,7 @@ /* * uvc_queue.c -- USB Video Class driver - Buffers management * - * Copyright (C) 2005-2008 + * Copyright (C) 2005-2009 * Laurent Pinchart (laurent.pinchart@skynet.be) * * This program is free software; you can redistribute it and/or modify @@ -36,22 +36,22 @@ * to user space will return -EBUSY. * * Video buffers are managed using two queues. However, unlike most USB video - * drivers which use an in queue and an out queue, we use a main queue which - * holds all queued buffers (both 'empty' and 'done' buffers), and an irq - * queue which holds empty buffers. This design (copied from video-buf) - * minimizes locking in interrupt, as only one queue is shared between - * interrupt and user contexts. + * drivers that use an in queue and an out queue, we use a main queue to hold + * all queued buffers (both 'empty' and 'done' buffers), and an irq queue to + * hold empty buffers. This design (copied from video-buf) minimizes locking + * in interrupt, as only one queue is shared between interrupt and user + * contexts. * * Use cases * --------- * - * Unless stated otherwise, all operations which modify the irq buffers queue + * Unless stated otherwise, all operations that modify the irq buffers queue * are protected by the irq spinlock. * * 1. The user queues the buffers, starts streaming and dequeues a buffer. * * The buffers are added to the main and irq queues. Both operations are - * protected by the queue lock, and the latert is protected by the irq + * protected by the queue lock, and the later is protected by the irq * spinlock as well. * * The completion handler fetches a buffer from the irq queue and fills it @@ -59,7 +59,7 @@ * returns immediately. * * When the buffer is full, the completion handler removes it from the irq - * queue, marks it as ready (UVC_BUF_STATE_DONE) and wake its wait queue. + * queue, marks it as ready (UVC_BUF_STATE_DONE) and wakes its wait queue. * At that point, any process waiting on the buffer will be woken up. If a * process tries to dequeue a buffer after it has been marked ready, the * dequeing will succeed immediately. @@ -90,8 +90,8 @@ void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type) /* * Allocate the video buffers. * - * Pages are reserved to make sure they will not be swaped, as they will be - * filled in URB completion handler. + * Pages are reserved to make sure they will not be swapped, as they will be + * filled in the URB completion handler. * * Buffers will be individually mapped, so they must all be page aligned. */ @@ -209,8 +209,8 @@ int uvc_query_buffer(struct uvc_video_queue *queue, __uvc_query_buffer(&queue->buffer[v4l2_buf->index], v4l2_buf); done: - mutex_unlock(&queue->mutex); - return ret; + mutex_unlock(&queue->mutex); + return ret; } /* @@ -235,7 +235,7 @@ int uvc_queue_buffer(struct uvc_video_queue *queue, } mutex_lock(&queue->mutex); - if (v4l2_buf->index >= queue->count) { + if (v4l2_buf->index >= queue->count) { uvc_trace(UVC_TRACE_CAPTURE, "[E] Out of range index.\n"); ret = -EINVAL; goto done; @@ -428,7 +428,7 @@ done: * Cancel the video buffers queue. * * Cancelling the queue marks all buffers on the irq queue as erroneous, - * wakes them up and remove them from the queue. + * 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. diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c index b482f4fc7b3..c1e4ae27c61 100644 --- a/drivers/media/video/uvc/uvc_status.c +++ b/drivers/media/video/uvc/uvc_status.c @@ -1,7 +1,7 @@ /* * uvc_status.c -- USB Video Class driver - Status endpoint * - * Copyright (C) 2007-2008 + * Copyright (C) 2007-2009 * Laurent Pinchart (laurent.pinchart@skynet.be) * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index fa150fff2c1..d681519d0c8 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c @@ -1,7 +1,7 @@ /* * uvc_v4l2.c -- USB Video Class driver - V4L2 API * - * Copyright (C) 2005-2008 + * Copyright (C) 2005-2009 * Laurent Pinchart (laurent.pinchart@skynet.be) * * This program is free software; you can redistribute it and/or modify @@ -37,7 +37,7 @@ * must be grouped (for instance the Red Balance, Blue Balance and Do White * Balance V4L2 controls use the White Balance Component UVC control) or * otherwise translated. The approach we take here is to use a translation - * table for the controls which can be mapped directly, and handle the others + * table for the controls that can be mapped directly, and handle the others * manually. */ static int uvc_v4l2_query_menu(struct uvc_video_device *video, @@ -189,7 +189,7 @@ static int uvc_v4l2_try_format(struct uvc_video_device *video, probe->dwMaxVideoFrameSize = video->streaming->ctrl.dwMaxVideoFrameSize; - /* Probe the device */ + /* Probe the device. */ if ((ret = uvc_probe_video(video, probe)) < 0) goto done; @@ -354,11 +354,11 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video, * * Each open instance of a UVC device can either be in a privileged or * unprivileged state. Only a single instance can be in a privileged state at - * a given time. Trying to perform an operation which requires privileges will + * a given time. Trying to perform an operation that requires privileges will * automatically acquire the required privileges if possible, or return -EBUSY * otherwise. Privileges are dismissed when closing the instance. * - * Operations which require privileges are: + * Operations that require privileges are: * * - VIDIOC_S_INPUT * - VIDIOC_S_PARM diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 6e9e30f174a..f9eb0e97405 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -1,7 +1,7 @@ /* * uvc_video.c -- USB Video Class driver - Video handling * - * Copyright (C) 2005-2008 + * Copyright (C) 2005-2009 * Laurent Pinchart (laurent.pinchart@skynet.be) * * This program is free software; you can redistribute it and/or modify @@ -159,7 +159,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video, } /* Some broken devices return a null or wrong dwMaxVideoFrameSize. - * Try to get the value from the format and frame descriptor. + * Try to get the value from the format and frame descriptors. */ uvc_fixup_buffer_size(video, ctrl); ret = 0; @@ -190,9 +190,6 @@ static int uvc_set_video_ctrl(struct uvc_video_device *video, *(__le16 *)&data[12] = cpu_to_le16(ctrl->wCompQuality); *(__le16 *)&data[14] = cpu_to_le16(ctrl->wCompWindowSize); *(__le16 *)&data[16] = cpu_to_le16(ctrl->wDelay); - /* Note: Some of the fields below are not required for IN devices (see - * UVC spec, 4.3.1.1), but we still copy them in case support for OUT - * devices is added in the future. */ put_unaligned_le32(ctrl->dwMaxVideoFrameSize, &data[18]); put_unaligned_le32(ctrl->dwMaxPayloadTransferSize, &data[22]); @@ -399,7 +396,7 @@ static int uvc_video_decode_start(struct uvc_video_device *video, * * Empty buffers (bytesused == 0) don't trigger end of frame detection * as it doesn't make sense to return an empty buffer. This also - * avoids detecting and of frame conditions at FID toggling if the + * avoids detecting end of frame conditions at FID toggling if the * previous payload had the EOF bit set. */ if (fid != video->last_fid && buf->buf.bytesused != 0) { @@ -452,6 +449,17 @@ static void uvc_video_decode_end(struct uvc_video_device *video, } } +/* Video payload encoding is handled by uvc_video_encode_header() and + * uvc_video_encode_data(). Only bulk transfers are currently supported. + * + * uvc_video_encode_header is called at the start of a payload. It adds header + * data to the transfer buffer and returns the header size. As the only known + * UVC output device transfers a whole frame in a single payload, the EOF bit + * is always set in the header. + * + * uvc_video_encode_data is called for every URB and copies the data from the + * video buffer to the transfer buffer. + */ static int uvc_video_encode_header(struct uvc_video_device *video, struct uvc_buffer *buf, __u8 *data, int len) { @@ -952,7 +960,7 @@ int uvc_video_suspend(struct uvc_video_device *video) } /* - * Reconfigure the video interface and restart streaming if it was enable + * Reconfigure the video interface and restart streaming if it was enabled * before suspend. * * If an error occurs, disable the video queue. This will wake all pending @@ -984,8 +992,8 @@ int uvc_video_resume(struct uvc_video_device *video) */ /* - * Initialize the UVC video device by retrieving the default format and - * committing it. + * Initialize the UVC video device by switching to alternate setting 0 and + * retrieve the default format. * * Some cameras (namely the Fuji Finepix) set the format and frame * indexes to zero. The UVC standard doesn't clearly make this a spec @@ -1013,7 +1021,7 @@ int uvc_video_init(struct uvc_video_device *video) */ usb_set_interface(video->dev->udev, video->streaming->intfnum, 0); - /* Some webcams don't suport GET_DEF request on the probe control. We + /* Some webcams don't suport GET_DEF requests on the probe control. We * fall back to GET_CUR if GET_DEF fails. */ if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_DEF)) < 0 && diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index bcf4361dc1b..027947ea9b6 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h @@ -72,149 +72,149 @@ struct uvc_xu_control { * UVC constants */ -#define SC_UNDEFINED 0x00 -#define SC_VIDEOCONTROL 0x01 -#define SC_VIDEOSTREAMING 0x02 -#define SC_VIDEO_INTERFACE_COLLECTION 0x03 +#define SC_UNDEFINED 0x00 +#define SC_VIDEOCONTROL 0x01 +#define SC_VIDEOSTREAMING 0x02 +#define SC_VIDEO_INTERFACE_COLLECTION 0x03 -#define PC_PROTOCOL_UNDEFINED 0x00 +#define PC_PROTOCOL_UNDEFINED 0x00 -#define CS_UNDEFINED 0x20 -#define CS_DEVICE 0x21 -#define CS_CONFIGURATION 0x22 -#define CS_STRING 0x23 -#define CS_INTERFACE 0x24 -#define CS_ENDPOINT 0x25 +#define CS_UNDEFINED 0x20 +#define CS_DEVICE 0x21 +#define CS_CONFIGURATION 0x22 +#define CS_STRING 0x23 +#define CS_INTERFACE 0x24 +#define CS_ENDPOINT 0x25 /* VideoControl class specific interface descriptor */ -#define VC_DESCRIPTOR_UNDEFINED 0x00 -#define VC_HEADER 0x01 -#define VC_INPUT_TERMINAL 0x02 -#define VC_OUTPUT_TERMINAL 0x03 -#define VC_SELECTOR_UNIT 0x04 -#define VC_PROCESSING_UNIT 0x05 -#define VC_EXTENSION_UNIT 0x06 +#define VC_DESCRIPTOR_UNDEFINED 0x00 +#define VC_HEADER 0x01 +#define VC_INPUT_TERMINAL 0x02 +#define VC_OUTPUT_TERMINAL 0x03 +#define VC_SELECTOR_UNIT 0x04 +#define VC_PROCESSING_UNIT 0x05 +#define VC_EXTENSION_UNIT 0x06 /* VideoStreaming class specific interface descriptor */ -#define VS_UNDEFINED 0x00 -#define VS_INPUT_HEADER 0x01 -#define VS_OUTPUT_HEADER 0x02 -#define VS_STILL_IMAGE_FRAME 0x03 -#define VS_FORMAT_UNCOMPRESSED 0x04 -#define VS_FRAME_UNCOMPRESSED 0x05 -#define VS_FORMAT_MJPEG 0x06 -#define VS_FRAME_MJPEG 0x07 -#define VS_FORMAT_MPEG2TS 0x0a -#define VS_FORMAT_DV 0x0c -#define VS_COLORFORMAT 0x0d -#define VS_FORMAT_FRAME_BASED 0x10 -#define VS_FRAME_FRAME_BASED 0x11 -#define VS_FORMAT_STREAM_BASED 0x12 +#define VS_UNDEFINED 0x00 +#define VS_INPUT_HEADER 0x01 +#define VS_OUTPUT_HEADER 0x02 +#define VS_STILL_IMAGE_FRAME 0x03 +#define VS_FORMAT_UNCOMPRESSED 0x04 +#define VS_FRAME_UNCOMPRESSED 0x05 +#define VS_FORMAT_MJPEG 0x06 +#define VS_FRAME_MJPEG 0x07 +#define VS_FORMAT_MPEG2TS 0x0a +#define VS_FORMAT_DV 0x0c +#define VS_COLORFORMAT 0x0d +#define VS_FORMAT_FRAME_BASED 0x10 +#define VS_FRAME_FRAME_BASED 0x11 +#define VS_FORMAT_STREAM_BASED 0x12 /* Endpoint type */ -#define EP_UNDEFINED 0x00 -#define EP_GENERAL 0x01 -#define EP_ENDPOINT 0x02 -#define EP_INTERRUPT 0x03 +#define EP_UNDEFINED 0x00 +#define EP_GENERAL 0x01 +#define EP_ENDPOINT 0x02 +#define EP_INTERRUPT 0x03 /* Request codes */ -#define RC_UNDEFINED 0x00 -#define SET_CUR 0x01 -#define GET_CUR 0x81 -#define GET_MIN 0x82 -#define GET_MAX 0x83 -#define GET_RES 0x84 -#define GET_LEN 0x85 -#define GET_INFO 0x86 -#define GET_DEF 0x87 +#define RC_UNDEFINED 0x00 +#define SET_CUR 0x01 +#define GET_CUR 0x81 +#define GET_MIN 0x82 +#define GET_MAX 0x83 +#define GET_RES 0x84 +#define GET_LEN 0x85 +#define GET_INFO 0x86 +#define GET_DEF 0x87 /* VideoControl interface controls */ -#define VC_CONTROL_UNDEFINED 0x00 -#define VC_VIDEO_POWER_MODE_CONTROL 0x01 -#define VC_REQUEST_ERROR_CODE_CONTROL 0x02 +#define VC_CONTROL_UNDEFINED 0x00 +#define VC_VIDEO_POWER_MODE_CONTROL 0x01 +#define VC_REQUEST_ERROR_CODE_CONTROL 0x02 /* Terminal controls */ -#define TE_CONTROL_UNDEFINED 0x00 +#define TE_CONTROL_UNDEFINED 0x00 /* Selector Unit controls */ -#define SU_CONTROL_UNDEFINED 0x00 -#define SU_INPUT_SELECT_CONTROL 0x01 +#define SU_CONTROL_UNDEFINED 0x00 +#define SU_INPUT_SELECT_CONTROL 0x01 /* Camera Terminal controls */ -#define CT_CONTROL_UNDEFINED 0x00 -#define CT_SCANNING_MODE_CONTROL 0x01 -#define CT_AE_MODE_CONTROL 0x02 -#define CT_AE_PRIORITY_CONTROL 0x03 -#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04 -#define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05 -#define CT_FOCUS_ABSOLUTE_CONTROL 0x06 -#define CT_FOCUS_RELATIVE_CONTROL 0x07 -#define CT_FOCUS_AUTO_CONTROL 0x08 -#define CT_IRIS_ABSOLUTE_CONTROL 0x09 -#define CT_IRIS_RELATIVE_CONTROL 0x0a -#define CT_ZOOM_ABSOLUTE_CONTROL 0x0b -#define CT_ZOOM_RELATIVE_CONTROL 0x0c -#define CT_PANTILT_ABSOLUTE_CONTROL 0x0d -#define CT_PANTILT_RELATIVE_CONTROL 0x0e -#define CT_ROLL_ABSOLUTE_CONTROL 0x0f -#define CT_ROLL_RELATIVE_CONTROL 0x10 -#define CT_PRIVACY_CONTROL 0x11 +#define CT_CONTROL_UNDEFINED 0x00 +#define CT_SCANNING_MODE_CONTROL 0x01 +#define CT_AE_MODE_CONTROL 0x02 +#define CT_AE_PRIORITY_CONTROL 0x03 +#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04 +#define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05 +#define CT_FOCUS_ABSOLUTE_CONTROL 0x06 +#define CT_FOCUS_RELATIVE_CONTROL 0x07 +#define CT_FOCUS_AUTO_CONTROL 0x08 +#define CT_IRIS_ABSOLUTE_CONTROL 0x09 +#define CT_IRIS_RELATIVE_CONTROL 0x0a +#define CT_ZOOM_ABSOLUTE_CONTROL 0x0b +#define CT_ZOOM_RELATIVE_CONTROL 0x0c +#define CT_PANTILT_ABSOLUTE_CONTROL 0x0d +#define CT_PANTILT_RELATIVE_CONTROL 0x0e +#define CT_ROLL_ABSOLUTE_CONTROL 0x0f +#define CT_ROLL_RELATIVE_CONTROL 0x10 +#define CT_PRIVACY_CONTROL 0x11 /* Processing Unit controls */ -#define PU_CONTROL_UNDEFINED 0x00 -#define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01 -#define PU_BRIGHTNESS_CONTROL 0x02 -#define PU_CONTRAST_CONTROL 0x03 -#define PU_GAIN_CONTROL 0x04 -#define PU_POWER_LINE_FREQUENCY_CONTROL 0x05 -#define PU_HUE_CONTROL 0x06 -#define PU_SATURATION_CONTROL 0x07 -#define PU_SHARPNESS_CONTROL 0x08 -#define PU_GAMMA_CONTROL 0x09 -#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0a -#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0b -#define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0c -#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0d -#define PU_DIGITAL_MULTIPLIER_CONTROL 0x0e -#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0f -#define PU_HUE_AUTO_CONTROL 0x10 -#define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11 -#define PU_ANALOG_LOCK_STATUS_CONTROL 0x12 +#define PU_CONTROL_UNDEFINED 0x00 +#define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01 +#define PU_BRIGHTNESS_CONTROL 0x02 +#define PU_CONTRAST_CONTROL 0x03 +#define PU_GAIN_CONTROL 0x04 +#define PU_POWER_LINE_FREQUENCY_CONTROL 0x05 +#define PU_HUE_CONTROL 0x06 +#define PU_SATURATION_CONTROL 0x07 +#define PU_SHARPNESS_CONTROL 0x08 +#define PU_GAMMA_CONTROL 0x09 +#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0a +#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0b +#define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0c +#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0d +#define PU_DIGITAL_MULTIPLIER_CONTROL 0x0e +#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0f +#define PU_HUE_AUTO_CONTROL 0x10 +#define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11 +#define PU_ANALOG_LOCK_STATUS_CONTROL 0x12 #define LXU_MOTOR_PANTILT_RELATIVE_CONTROL 0x01 #define LXU_MOTOR_PANTILT_RESET_CONTROL 0x02 #define LXU_MOTOR_FOCUS_MOTOR_CONTROL 0x03 /* VideoStreaming interface controls */ -#define VS_CONTROL_UNDEFINED 0x00 -#define VS_PROBE_CONTROL 0x01 -#define VS_COMMIT_CONTROL 0x02 -#define VS_STILL_PROBE_CONTROL 0x03 -#define VS_STILL_COMMIT_CONTROL 0x04 -#define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05 -#define VS_STREAM_ERROR_CODE_CONTROL 0x06 -#define VS_GENERATE_KEY_FRAME_CONTROL 0x07 -#define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08 -#define VS_SYNC_DELAY_CONTROL 0x09 - -#define TT_VENDOR_SPECIFIC 0x0100 -#define TT_STREAMING 0x0101 +#define VS_CONTROL_UNDEFINED 0x00 +#define VS_PROBE_CONTROL 0x01 +#define VS_COMMIT_CONTROL 0x02 +#define VS_STILL_PROBE_CONTROL 0x03 +#define VS_STILL_COMMIT_CONTROL 0x04 +#define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05 +#define VS_STREAM_ERROR_CODE_CONTROL 0x06 +#define VS_GENERATE_KEY_FRAME_CONTROL 0x07 +#define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08 +#define VS_SYNC_DELAY_CONTROL 0x09 + +#define TT_VENDOR_SPECIFIC 0x0100 +#define TT_STREAMING 0x0101 /* Input Terminal types */ -#define ITT_VENDOR_SPECIFIC 0x0200 -#define ITT_CAMERA 0x0201 -#define ITT_MEDIA_TRANSPORT_INPUT 0x0202 +#define ITT_VENDOR_SPECIFIC 0x0200 +#define ITT_CAMERA 0x0201 +#define ITT_MEDIA_TRANSPORT_INPUT 0x0202 /* Output Terminal types */ -#define OTT_VENDOR_SPECIFIC 0x0300 -#define OTT_DISPLAY 0x0301 -#define OTT_MEDIA_TRANSPORT_OUTPUT 0x0302 +#define OTT_VENDOR_SPECIFIC 0x0300 +#define OTT_DISPLAY 0x0301 +#define OTT_MEDIA_TRANSPORT_OUTPUT 0x0302 /* External Terminal types */ -#define EXTERNAL_VENDOR_SPECIFIC 0x0400 -#define COMPOSITE_CONNECTOR 0x0401 -#define SVIDEO_CONNECTOR 0x0402 -#define COMPONENT_CONNECTOR 0x0403 +#define EXTERNAL_VENDOR_SPECIFIC 0x0400 +#define COMPOSITE_CONNECTOR 0x0401 +#define SVIDEO_CONNECTOR 0x0402 +#define COMPONENT_CONNECTOR 0x0403 #define UVC_TERM_INPUT 0x0000 #define UVC_TERM_OUTPUT 0x8000 @@ -541,11 +541,11 @@ struct uvc_streaming { }; enum uvc_buffer_state { - UVC_BUF_STATE_IDLE = 0, - UVC_BUF_STATE_QUEUED = 1, - UVC_BUF_STATE_ACTIVE = 2, - UVC_BUF_STATE_DONE = 3, - UVC_BUF_STATE_ERROR = 4, + UVC_BUF_STATE_IDLE = 0, + UVC_BUF_STATE_QUEUED = 1, + UVC_BUF_STATE_ACTIVE = 2, + UVC_BUF_STATE_DONE = 3, + UVC_BUF_STATE_ERROR = 4, }; struct uvc_buffer { -- cgit v1.2.3 From fba4578ee925110587ef9b8b6ddfabf2ce288071 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 3 Jan 2009 19:24:38 -0300 Subject: V4L/DVB (10198): uvcvideo: Print the UVC version number in binary-coded decimal. The UVC specification release number is a binary-coded decimal number, print it as such. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 20c16c4a62d..b12873265cc 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -1635,7 +1635,7 @@ static int uvc_probe(struct usb_interface *intf, goto error; } - uvc_printk(KERN_INFO, "Found UVC %u.%02u device %s (%04x:%04x)\n", + uvc_printk(KERN_INFO, "Found UVC %u.%02x device %s (%04x:%04x)\n", dev->uvc_version >> 8, dev->uvc_version & 0xff, udev->product ? udev->product : "", le16_to_cpu(udev->descriptor.idVendor), -- cgit v1.2.3 From 51cac8ada5caaade4eca0023042ceb01edd82840 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 3 Jan 2009 20:08:26 -0300 Subject: V4L/DVB (10199): uvcvideo: Fix GET_DEF failure detection. Commit 44f0079ec74330b457d990072c13cbe28b0f1abf erroneously considers all GET_DEF requests as unsuccessful. Fix this by checking the request return value. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index f9eb0e97405..9bc4705be78 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -114,7 +114,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video, ctrl->wCompQuality = le16_to_cpup((__le16 *)data); ret = 0; goto out; - } else if (query == GET_DEF && probe == 1) { + } else if (query == GET_DEF && probe == 1 && ret != size) { /* Many cameras don't support the GET_DEF request on their * video probe control. Warn once and return, the caller will * fall back to GET_CUR. -- cgit v1.2.3 From 77f56279f75b3c1decb4f8a3251b155bb791059e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 8 Jan 2009 17:13:53 -0300 Subject: V4L/DVB (10201): Fixes cx88 compilation bug Randy Dunlap wrote: > linux-next-20090108/drivers/media/video/cx88/cx88-i2c.c: In function 'cx88_call_i2c_clients': > linux-next-20090108/drivers/media/video/cx88/cx88-i2c.c:122: error: 'struct cx88_core' has no member named 'gate_ctrl' > linux-next-20090108/drivers/media/video/cx88/cx88-i2c.c:123: error: 'struct cx88_core' has no member named 'gate_ctrl' > linux-next-20090108/drivers/media/video/cx88/cx88-i2c.c:127: error: 'struct cx88_core' has no member named 'gate_ctrl' > linux-next-20090108/drivers/media/video/cx88/cx88-i2c.c:128: error: 'struct cx88_core' has no member named 'gate_ctrl' Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx88/cx88.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 60a8b3187f1..6025fdd2334 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h @@ -336,8 +336,8 @@ struct cx88_core { /* config info -- dvb */ #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) int (*prev_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage); - void (*gate_ctrl)(struct cx88_core *core, int open); #endif + void (*gate_ctrl)(struct cx88_core *core, int open); /* state info */ struct task_struct *kthread; -- cgit v1.2.3 From 0c37dd7a9052529cd9346b04530be7878c03e429 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 8 Jan 2009 12:49:17 -0300 Subject: V4L/DVB (10202): [PATCH] v4l/tvp514x: Don't write after line end to avoid: | tvp514x 0-005c: No platform data | !!<3>tvp514x 0-005d: No platform data Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tvp514x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c index ac9aa40d09f..8e23aa53c29 100644 --- a/drivers/media/video/tvp514x.c +++ b/drivers/media/video/tvp514x.c @@ -1401,7 +1401,7 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id) decoder->pdata = client->dev.platform_data; if (!decoder->pdata) { - v4l_err(client, "No platform data\n!!"); + v4l_err(client, "No platform data!!\n"); return -ENODEV; } /* -- cgit v1.2.3 From dbdf03b48bd32150b4023ea0dd22f566958b6294 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 8 Jan 2009 23:27:32 -0300 Subject: V4L/DVB (10208): zoran: Re-adds udev entry removed by changeset 60b4bde4 Changeset 60b4bde48b36c0315ef41fd38c339b9c7e68c46f removed an unused struct on zoran driver, when compiled with "Y". However, as pointed by Jean Delvare , this is neeeded when the driver is compiled as a module, since udev relies on it to auto-load the module. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/zoran/zoran_card.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/media/video') diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c index 05f39195372..4e8ecf356ad 100644 --- a/drivers/media/video/zoran/zoran_card.c +++ b/drivers/media/video/zoran/zoran_card.c @@ -153,6 +153,14 @@ MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver"); MODULE_AUTHOR("Serguei Miridonov"); MODULE_LICENSE("GPL"); +#if (defined(CONFIG_VIDEO_ZORAN_MODULE) && defined(MODULE)) +static struct pci_device_id zr36067_pci_tbl[] = { + {PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0} +}; +MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl); +#endif int zoran_num; /* number of Buzs in use */ struct zoran *zoran[BUZ_MAX]; -- cgit v1.2.3 From 3e478c06e83efc365e8351bff7b4c569f22e642d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 9 Jan 2009 08:38:47 -0300 Subject: V4L/DVB (10209): tveeprom: Properly initialize tuner type (BZ#11367) If Hauppauge eeprom is corrupted, the driver returns tuner = 0, instead of TUNER_ABSENT. This makes the drivers to initialize tuner, instead of handling the manual parameter. Since the tuner core rejects that a tuner to have their type changed, this breaks the manual tuner override. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tveeprom.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/media/video') diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index 3b0b84c2e45..78277abb733 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c @@ -427,6 +427,9 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" }; memset(tvee, 0, sizeof(*tvee)); + tvee->tuner_type = TUNER_ABSENT; + tvee->tuner2_type = TUNER_ABSENT; + done = len = beenhere = 0; /* Different eeprom start offsets for em28xx, cx2388x and cx23418 */ -- cgit v1.2.3 From 66aa66ea31371daad562bf22ff245caf707d5d40 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Sun, 11 Jan 2009 12:02:54 -0300 Subject: V4L/DVB (10212): Convert to be a pci driver This is a really old and crufty driver that wasn't using the long established pci driver framework. Signed-off-by: Trent Piepho Acked-by: Jean Delvare [mchehab@redhat.com: Cleaned up a few CodingStyle issues] Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/zoran/zoran_card.c | 596 +++++++++++++++---------------- drivers/media/video/zoran/zoran_card.h | 2 +- drivers/media/video/zoran/zoran_driver.c | 2 +- 3 files changed, 296 insertions(+), 304 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c index 4e8ecf356ad..e987d53c294 100644 --- a/drivers/media/video/zoran/zoran_card.c +++ b/drivers/media/video/zoran/zoran_card.c @@ -153,16 +153,13 @@ MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver"); MODULE_AUTHOR("Serguei Miridonov"); MODULE_LICENSE("GPL"); -#if (defined(CONFIG_VIDEO_ZORAN_MODULE) && defined(MODULE)) static struct pci_device_id zr36067_pci_tbl[] = { - {PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_DEVICE(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057), }, {0} }; MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl); -#endif -int zoran_num; /* number of Buzs in use */ +atomic_t zoran_num = ATOMIC_INIT(0); /* number of Buzs in use */ struct zoran *zoran[BUZ_MAX]; /* videocodec bus functions ZR36060 */ @@ -1146,7 +1143,7 @@ zr36057_init (struct zoran *zr) strcpy(zr->video_dev->name, ZR_DEVNAME(zr)); err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]); if (err < 0) - goto exit_unregister; + goto exit_free; zoran_init_hardware(zr); if (zr36067_debug > 2) @@ -1161,19 +1158,19 @@ zr36057_init (struct zoran *zr) zr->initialized = 1; return 0; -exit_unregister: - zoran_unregister_i2c(zr); exit_free: kfree(zr->stat_com); kfree(zr->video_dev); return err; } -static void -zoran_release (struct zoran *zr) +static void __devexit zoran_remove(struct pci_dev *pdev) { + struct zoran *zr = pci_get_drvdata(pdev); + if (!zr->initialized) goto exit_free; + /* unregister videocodec bus */ if (zr->codec) { struct videocodec_master *master = zr->codec->master_data; @@ -1202,6 +1199,7 @@ zoran_release (struct zoran *zr) pci_disable_device(zr->pci_dev); video_unregister_device(zr->video_dev); exit_free: + pci_set_drvdata(pdev, NULL); kfree(zr); } @@ -1264,338 +1262,347 @@ zoran_setup_videocodec (struct zoran *zr, * Scan for a Buz card (actually for the PCI controller ZR36057), * request the irq and map the io memory */ -static int __devinit -find_zr36057 (void) +static int __devinit zoran_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) { unsigned char latency, need_latency; struct zoran *zr; - struct pci_dev *dev = NULL; int result; struct videocodec_master *master_vfe = NULL; struct videocodec_master *master_codec = NULL; int card_num; char *i2c_enc_name, *i2c_dec_name, *codec_name, *vfe_name; + unsigned int nr; - zoran_num = 0; - while (zoran_num < BUZ_MAX && - (dev = pci_get_device(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, dev)) != NULL) { - card_num = card[zoran_num]; - zr = kzalloc(sizeof(struct zoran), GFP_KERNEL); - if (!zr) { - dprintk(1, - KERN_ERR - "%s: find_zr36057() - kzalloc failed\n", - ZORAN_NAME); - continue; - } - zr->pci_dev = dev; - //zr->zr36057_mem = NULL; - zr->id = zoran_num; - snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id); - spin_lock_init(&zr->spinlock); - mutex_init(&zr->resource_lock); - if (pci_enable_device(dev)) - goto zr_free_mem; - zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0); - pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, - &zr->revision); - if (zr->revision < 2) { - dprintk(1, - KERN_INFO - "%s: Zoran ZR36057 (rev %d) irq: %d, memory: 0x%08x.\n", - ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq, - zr->zr36057_adr); - if (card_num == -1) { - dprintk(1, - KERN_ERR - "%s: find_zr36057() - no card specified, please use the card=X insmod option\n", - ZR_DEVNAME(zr)); - goto zr_free_mem; - } - } else { - int i; - unsigned short ss_vendor, ss_device; - - ss_vendor = zr->pci_dev->subsystem_vendor; - ss_device = zr->pci_dev->subsystem_device; - dprintk(1, - KERN_INFO - "%s: Zoran ZR36067 (rev %d) irq: %d, memory: 0x%08x\n", - ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq, - zr->zr36057_adr); - dprintk(1, - KERN_INFO - "%s: subsystem vendor=0x%04x id=0x%04x\n", - ZR_DEVNAME(zr), ss_vendor, ss_device); - if (card_num == -1) { - dprintk(3, - KERN_DEBUG - "%s: find_zr36057() - trying to autodetect card type\n", - ZR_DEVNAME(zr)); - for (i=0;i= BUZ_MAX) { + dprintk(1, + KERN_ERR + "%s: driver limited to %d card(s) maximum\n", + ZORAN_NAME, BUZ_MAX); + return -ENOENT; + } - if (card_num < 0 || card_num >= NUM_CARDS) { - dprintk(2, - KERN_ERR - "%s: find_zr36057() - invalid cardnum %d\n", - ZR_DEVNAME(zr), card_num); - goto zr_free_mem; - } + card_num = card[nr]; + zr = kzalloc(sizeof(struct zoran), GFP_KERNEL); + if (!zr) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() - kzalloc failed\n", + ZORAN_NAME); + /* The entry in zoran[] gets leaked */ + return -ENOMEM; + } + zr->pci_dev = pdev; + zr->id = nr; + snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id); + spin_lock_init(&zr->spinlock); + mutex_init(&zr->resource_lock); + if (pci_enable_device(pdev)) + goto zr_free_mem; + zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0); + pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision); + if (zr->revision < 2) { + dprintk(1, + KERN_INFO + "%s: Zoran ZR36057 (rev %d) irq: %d, memory: 0x%08x.\n", + ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq, + zr->zr36057_adr); - /* even though we make this a non pointer and thus - * theoretically allow for making changes to this struct - * on a per-individual card basis at runtime, this is - * strongly discouraged. This structure is intended to - * keep general card information, no settings or anything */ - zr->card = zoran_cards[card_num]; - snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), - "%s[%u]", zr->card.name, zr->id); - - zr->zr36057_mem = ioremap_nocache(zr->zr36057_adr, 0x1000); - if (!zr->zr36057_mem) { + if (card_num == -1) { dprintk(1, KERN_ERR - "%s: find_zr36057() - ioremap failed\n", + "%s: find_zr36057() - no card specified, please use the card=X insmod option\n", ZR_DEVNAME(zr)); goto zr_free_mem; } + } else { + int i; + unsigned short ss_vendor, ss_device; - result = request_irq(zr->pci_dev->irq, - zoran_irq, - IRQF_SHARED | IRQF_DISABLED, - ZR_DEVNAME(zr), - (void *) zr); - if (result < 0) { - if (result == -EINVAL) { + ss_vendor = zr->pci_dev->subsystem_vendor; + ss_device = zr->pci_dev->subsystem_device; + dprintk(1, + KERN_INFO + "%s: Zoran ZR36067 (rev %d) irq: %d, memory: 0x%08x\n", + ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq, + zr->zr36057_adr); + dprintk(1, + KERN_INFO + "%s: subsystem vendor=0x%04x id=0x%04x\n", + ZR_DEVNAME(zr), ss_vendor, ss_device); + if (card_num == -1) { + dprintk(3, + KERN_DEBUG + "%s: find_zr36057() - trying to autodetect card type\n", + ZR_DEVNAME(zr)); + for (i = 0; i < NUM_CARDS; i++) { + if (ss_vendor == zoran_cards[i].vendor_id && + ss_device == zoran_cards[i].device_id) { + dprintk(3, + KERN_DEBUG + "%s: find_zr36057() - card %s detected\n", + ZR_DEVNAME(zr), + zoran_cards[i].name); + card_num = i; + break; + } + } + if (i == NUM_CARDS) { dprintk(1, KERN_ERR - "%s: find_zr36057() - bad irq number or handler\n", + "%s: find_zr36057() - unknown card\n", ZR_DEVNAME(zr)); - } else if (result == -EBUSY) { - dprintk(1, - KERN_ERR - "%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n", - ZR_DEVNAME(zr), zr->pci_dev->irq); - } else { - dprintk(1, - KERN_ERR - "%s: find_zr36057() - can't assign irq, error code %d\n", - ZR_DEVNAME(zr), result); + goto zr_free_mem; } - goto zr_unmap; } + } - /* set PCI latency timer */ - pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, - &latency); - need_latency = zr->revision > 1 ? 32 : 48; - if (latency != need_latency) { - dprintk(2, - KERN_INFO - "%s: Changing PCI latency from %d to %d.\n", - ZR_DEVNAME(zr), latency, need_latency); - pci_write_config_byte(zr->pci_dev, - PCI_LATENCY_TIMER, - need_latency); - } + if (card_num < 0 || card_num >= NUM_CARDS) { + dprintk(2, + KERN_ERR + "%s: find_zr36057() - invalid cardnum %d\n", + ZR_DEVNAME(zr), card_num); + goto zr_free_mem; + } - zr36057_restart(zr); - /* i2c */ - dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n", + /* even though we make this a non pointer and thus + * theoretically allow for making changes to this struct + * on a per-individual card basis at runtime, this is + * strongly discouraged. This structure is intended to + * keep general card information, no settings or anything */ + zr->card = zoran_cards[card_num]; + snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), + "%s[%u]", zr->card.name, zr->id); + + zr->zr36057_mem = ioremap_nocache(zr->zr36057_adr, 0x1000); + if (!zr->zr36057_mem) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() - ioremap failed\n", ZR_DEVNAME(zr)); + goto zr_free_mem; + } - /* i2c decoder */ - if (decoder[zr->id] != -1) { - i2c_dec_name = i2cid_to_modulename(decoder[zr->id]); - zr->card.i2c_decoder = decoder[zr->id]; - } else if (zr->card.i2c_decoder != 0) { - i2c_dec_name = - i2cid_to_modulename(zr->card.i2c_decoder); + result = request_irq(zr->pci_dev->irq, zoran_irq, + IRQF_SHARED | IRQF_DISABLED, ZR_DEVNAME(zr), zr); + if (result < 0) { + if (result == -EINVAL) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() - bad irq number or handler\n", + ZR_DEVNAME(zr)); + } else if (result == -EBUSY) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n", + ZR_DEVNAME(zr), zr->pci_dev->irq); } else { - i2c_dec_name = NULL; + dprintk(1, + KERN_ERR + "%s: find_zr36057() - can't assign irq, error code %d\n", + ZR_DEVNAME(zr), result); } + goto zr_unmap; + } - if (i2c_dec_name) { - if ((result = request_module(i2c_dec_name)) < 0) { - dprintk(1, - KERN_ERR - "%s: failed to load module %s: %d\n", - ZR_DEVNAME(zr), i2c_dec_name, result); - } - } + /* set PCI latency timer */ + pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, + &latency); + need_latency = zr->revision > 1 ? 32 : 48; + if (latency != need_latency) { + dprintk(2, + KERN_INFO + "%s: Changing PCI latency from %d to %d\n", + ZR_DEVNAME(zr), latency, need_latency); + pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, + need_latency); + } - /* i2c encoder */ - if (encoder[zr->id] != -1) { - i2c_enc_name = i2cid_to_modulename(encoder[zr->id]); - zr->card.i2c_encoder = encoder[zr->id]; - } else if (zr->card.i2c_encoder != 0) { - i2c_enc_name = - i2cid_to_modulename(zr->card.i2c_encoder); - } else { - i2c_enc_name = NULL; - } + zr36057_restart(zr); + /* i2c */ + dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n", + ZR_DEVNAME(zr)); + + /* i2c decoder */ + if (decoder[zr->id] != -1) { + i2c_dec_name = i2cid_to_modulename(decoder[zr->id]); + zr->card.i2c_decoder = decoder[zr->id]; + } else if (zr->card.i2c_decoder != 0) { + i2c_dec_name = i2cid_to_modulename(zr->card.i2c_decoder); + } else { + i2c_dec_name = NULL; + } - if (i2c_enc_name) { - if ((result = request_module(i2c_enc_name)) < 0) { - dprintk(1, - KERN_ERR - "%s: failed to load module %s: %d\n", - ZR_DEVNAME(zr), i2c_enc_name, result); - } + if (i2c_dec_name) { + result = request_module(i2c_dec_name); + if (result < 0) { + dprintk(1, + KERN_ERR + "%s: failed to load module %s: %d\n", + ZR_DEVNAME(zr), i2c_dec_name, result); } + } - if (zoran_register_i2c(zr) < 0) { + /* i2c encoder */ + if (encoder[zr->id] != -1) { + i2c_enc_name = i2cid_to_modulename(encoder[zr->id]); + zr->card.i2c_encoder = encoder[zr->id]; + } else if (zr->card.i2c_encoder != 0) { + i2c_enc_name = i2cid_to_modulename(zr->card.i2c_encoder); + } else { + i2c_enc_name = NULL; + } + + if (i2c_enc_name) { + result = request_module(i2c_enc_name); + if (result < 0) { dprintk(1, KERN_ERR - "%s: find_zr36057() - can't initialize i2c bus\n", - ZR_DEVNAME(zr)); - goto zr_free_irq; + "%s: failed to load module %s: %d\n", + ZR_DEVNAME(zr), i2c_enc_name, result); } + } - dprintk(2, - KERN_INFO "%s: Initializing videocodec bus...\n", + if (zoran_register_i2c(zr) < 0) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() - can't initialize i2c bus\n", ZR_DEVNAME(zr)); + goto zr_free_irq; + } - if (zr->card.video_codec != 0 && - (codec_name = - codecid_to_modulename(zr->card.video_codec)) != NULL) { - if ((result = request_module(codec_name)) < 0) { + dprintk(2, + KERN_INFO "%s: Initializing videocodec bus...\n", + ZR_DEVNAME(zr)); + + if (zr->card.video_codec) { + codec_name = codecid_to_modulename(zr->card.video_codec); + if (codec_name) { + result = request_module(codec_name); + if (result) { dprintk(1, KERN_ERR "%s: failed to load modules %s: %d\n", ZR_DEVNAME(zr), codec_name, result); } } - if (zr->card.video_vfe != 0 && - (vfe_name = - codecid_to_modulename(zr->card.video_vfe)) != NULL) { - if ((result = request_module(vfe_name)) < 0) { + } + if (zr->card.video_vfe) { + vfe_name = codecid_to_modulename(zr->card.video_vfe); + if (vfe_name) { + result = request_module(vfe_name); + if (result < 0) { dprintk(1, KERN_ERR "%s: failed to load modules %s: %d\n", ZR_DEVNAME(zr), vfe_name, result); } } + } - /* reset JPEG codec */ - jpeg_codec_sleep(zr, 1); - jpeg_codec_reset(zr); - /* video bus enabled */ - /* display codec revision */ - if (zr->card.video_codec != 0) { - master_codec = zoran_setup_videocodec(zr, - zr->card.video_codec); - if (!master_codec) - goto zr_unreg_i2c; - zr->codec = videocodec_attach(master_codec); - if (!zr->codec) { - dprintk(1, - KERN_ERR - "%s: find_zr36057() - no codec found\n", - ZR_DEVNAME(zr)); - goto zr_free_codec; - } - if (zr->codec->type != zr->card.video_codec) { - dprintk(1, - KERN_ERR - "%s: find_zr36057() - wrong codec\n", - ZR_DEVNAME(zr)); - goto zr_detach_codec; - } + /* reset JPEG codec */ + jpeg_codec_sleep(zr, 1); + jpeg_codec_reset(zr); + /* video bus enabled */ + /* display codec revision */ + if (zr->card.video_codec != 0) { + master_codec = zoran_setup_videocodec(zr, zr->card.video_codec); + if (!master_codec) + goto zr_unreg_i2c; + zr->codec = videocodec_attach(master_codec); + if (!zr->codec) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() - no codec found\n", + ZR_DEVNAME(zr)); + goto zr_free_codec; } - if (zr->card.video_vfe != 0) { - master_vfe = zoran_setup_videocodec(zr, - zr->card.video_vfe); - if (!master_vfe) - goto zr_detach_codec; - zr->vfe = videocodec_attach(master_vfe); - if (!zr->vfe) { - dprintk(1, - KERN_ERR - "%s: find_zr36057() - no VFE found\n", - ZR_DEVNAME(zr)); - goto zr_free_vfe; - } - if (zr->vfe->type != zr->card.video_vfe) { - dprintk(1, - KERN_ERR - "%s: find_zr36057() = wrong VFE\n", - ZR_DEVNAME(zr)); - goto zr_detach_vfe; - } + if (zr->codec->type != zr->card.video_codec) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() - wrong codec\n", + ZR_DEVNAME(zr)); + goto zr_detach_codec; } - /* Success so keep the pci_dev referenced */ - pci_dev_get(zr->pci_dev); - zoran[zoran_num++] = zr; - continue; - - // Init errors - zr_detach_vfe: - videocodec_detach(zr->vfe); - zr_free_vfe: - kfree(master_vfe); - zr_detach_codec: - videocodec_detach(zr->codec); - zr_free_codec: - kfree(master_codec); - zr_unreg_i2c: - zoran_unregister_i2c(zr); - zr_free_irq: - btwrite(0, ZR36057_SPGPPCR); - free_irq(zr->pci_dev->irq, zr); - zr_unmap: - iounmap(zr->zr36057_mem); - zr_free_mem: - kfree(zr); - continue; } - if (dev) /* Clean up ref count on early exit */ - pci_dev_put(dev); + if (zr->card.video_vfe != 0) { + master_vfe = zoran_setup_videocodec(zr, zr->card.video_vfe); + if (!master_vfe) + goto zr_detach_codec; + zr->vfe = videocodec_attach(master_vfe); + if (!zr->vfe) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() - no VFE found\n", + ZR_DEVNAME(zr)); + goto zr_free_vfe; + } + if (zr->vfe->type != zr->card.video_vfe) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() = wrong VFE\n", + ZR_DEVNAME(zr)); + goto zr_detach_vfe; + } + } + zoran[nr] = zr; - if (zoran_num == 0) { - dprintk(1, KERN_INFO "No known MJPEG cards found.\n"); + /* take care of Natoma chipset and a revision 1 zr36057 */ + if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) { + zr->jpg_buffers.need_contiguous = 1; + dprintk(1, + KERN_INFO + "%s: ZR36057/Natoma bug, max. buffer size is 128K\n", + ZR_DEVNAME(zr)); } - return zoran_num; + + if (zr36057_init(zr) < 0) + goto zr_detach_vfe; + + zoran_proc_init(zr); + + pci_set_drvdata(pdev, zr); + + return 0; + +zr_detach_vfe: + videocodec_detach(zr->vfe); +zr_free_vfe: + kfree(master_vfe); +zr_detach_codec: + videocodec_detach(zr->codec); +zr_free_codec: + kfree(master_codec); +zr_unreg_i2c: + zoran_unregister_i2c(zr); +zr_free_irq: + btwrite(0, ZR36057_SPGPPCR); + free_irq(zr->pci_dev->irq, zr); +zr_unmap: + iounmap(zr->zr36057_mem); +zr_free_mem: + kfree(zr); + + return -ENODEV; } -static int __init -init_dc10_cards (void) +static struct pci_driver zoran_driver = { + .name = "zr36067", + .id_table = zr36067_pci_tbl, + .probe = zoran_probe, + .remove = zoran_remove, +}; + +static int __init zoran_init(void) { - int i; + int res; memset(zoran, 0, sizeof(zoran)); printk(KERN_INFO "Zoran MJPEG board driver version %d.%d.%d\n", MAJOR_VERSION, MINOR_VERSION, RELEASE_VERSION); - /* Look for cards */ - if (find_zr36057() < 0) { - return -EIO; - } - if (zoran_num == 0) - return -ENODEV; - dprintk(1, KERN_INFO "%s: %d card(s) found\n", ZORAN_NAME, - zoran_num); /* check the parameters we have been given, adjust if necessary */ if (v4l_nbufs < 2) v4l_nbufs = 2; @@ -1637,37 +1644,22 @@ init_dc10_cards (void) ZORAN_NAME); } - /* take care of Natoma chipset and a revision 1 zr36057 */ - for (i = 0; i < zoran_num; i++) { - struct zoran *zr = zoran[i]; - - if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) { - zr->jpg_buffers.need_contiguous = 1; - dprintk(1, - KERN_INFO - "%s: ZR36057/Natoma bug, max. buffer size is 128K\n", - ZR_DEVNAME(zr)); - } - - if (zr36057_init(zr) < 0) { - for (i = 0; i < zoran_num; i++) - zoran_release(zoran[i]); - return -EIO; - } - zoran_proc_init(zr); + res = pci_register_driver(&zoran_driver); + if (res) { + dprintk(1, + KERN_ERR + "%s: Unable to register ZR36057 driver\n", + ZORAN_NAME); + return res; } return 0; } -static void __exit -unload_dc10_cards (void) +static void __exit zoran_exit(void) { - int i; - - for (i = 0; i < zoran_num; i++) - zoran_release(zoran[i]); + pci_unregister_driver(&zoran_driver); } -module_init(init_dc10_cards); -module_exit(unload_dc10_cards); +module_init(zoran_init); +module_exit(zoran_exit); diff --git a/drivers/media/video/zoran/zoran_card.h b/drivers/media/video/zoran/zoran_card.h index e4dc9d29b40..c989448a77d 100644 --- a/drivers/media/video/zoran/zoran_card.h +++ b/drivers/media/video/zoran/zoran_card.h @@ -40,7 +40,7 @@ extern int zr36067_debug; /* Anybody who uses more than four? */ #define BUZ_MAX 4 -extern int zoran_num; +extern atomic_t zoran_num; extern struct zoran *zoran[BUZ_MAX]; extern struct video_device zoran_template; diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index b58b9dda715..5e667fd7272 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/drivers/media/video/zoran/zoran_driver.c @@ -1206,7 +1206,7 @@ zoran_open(struct file *file) lock_kernel(); /* find the device */ - for (i = 0; i < zoran_num; i++) { + for (i = 0; i < atomic_read(&zoran_num); i++) { if (zoran[i]->video_dev->minor == minor) { zr = zoran[i]; break; -- cgit v1.2.3 From 0f3559ef17362a7dd5017521a4dd4cad31263395 Mon Sep 17 00:00:00 2001 From: Martin Dauskardt Date: Sat, 10 Jan 2009 10:16:16 -0300 Subject: V4L/DVB (10216): saa7127: fix broken S-Video with saa7129 Register 0x2d has to be set differently in the saa7129 compared to the saa7127. This was not done correctly, so S-Video was broken in certain circumstances. This fixes a regression introduced in 2.6.28. Signed-off-by: Martin Dauskardt Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7127.c | 52 +++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 22 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c index d6848f7a503..05221d47dd4 100644 --- a/drivers/media/video/saa7127.c +++ b/drivers/media/video/saa7127.c @@ -149,7 +149,7 @@ static const struct i2c_reg_value saa7127_init_config_common[] = { { SAA7127_REG_COPYGEN_0, 0x77 }, { SAA7127_REG_COPYGEN_1, 0x41 }, { SAA7127_REG_COPYGEN_2, 0x00 }, /* Macrovision enable/disable */ - { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x9e }, + { SAA7127_REG_OUTPUT_PORT_CONTROL, 0xbf }, { SAA7127_REG_GAIN_LUMINANCE_RGB, 0x00 }, { SAA7127_REG_GAIN_COLORDIFF_RGB, 0x00 }, { SAA7127_REG_INPUT_PORT_CONTROL_1, 0x80 }, /* for color bars */ @@ -488,12 +488,18 @@ static int saa7127_set_output_type(struct v4l2_subdev *sd, int output) break; case SAA7127_OUTPUT_TYPE_COMPOSITE: - state->reg_2d = 0x08; /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */ + if (state->ident == V4L2_IDENT_SAA7129) + state->reg_2d = 0x20; /* CVBS only */ + else + state->reg_2d = 0x08; /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */ state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */ break; case SAA7127_OUTPUT_TYPE_SVIDEO: - state->reg_2d = 0xff; /* 11111111 croma -> R, luma -> CVBS + G + B */ + if (state->ident == V4L2_IDENT_SAA7129) + state->reg_2d = 0x18; /* Y + C */ + else + state->reg_2d = 0xff; /*11111111 croma -> R, luma -> CVBS + G + B */ state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */ break; @@ -508,7 +514,10 @@ static int saa7127_set_output_type(struct v4l2_subdev *sd, int output) break; case SAA7127_OUTPUT_TYPE_BOTH: - state->reg_2d = 0xbf; + if (state->ident == V4L2_IDENT_SAA7129) + state->reg_2d = 0x38; + else + state->reg_2d = 0xbf; state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */ break; @@ -731,24 +740,6 @@ static int saa7127_probe(struct i2c_client *client, return -ENODEV; } - /* Configure Encoder */ - - v4l2_dbg(1, debug, sd, "Configuring encoder\n"); - saa7127_write_inittab(sd, saa7127_init_config_common); - saa7127_set_std(sd, V4L2_STD_NTSC); - saa7127_set_output_type(sd, SAA7127_OUTPUT_TYPE_BOTH); - saa7127_set_vps(sd, &vbi); - saa7127_set_wss(sd, &vbi); - saa7127_set_cc(sd, &vbi); - saa7127_set_xds(sd, &vbi); - if (test_image == 1) - /* The Encoder has an internal Colorbar generator */ - /* This can be used for debugging */ - saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_TEST_IMAGE); - else - saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL); - saa7127_set_video_enable(sd, 1); - if (id->driver_data) { /* Chip type is already known */ state->ident = id->driver_data; } else { /* Needs detection */ @@ -770,6 +761,23 @@ static int saa7127_probe(struct i2c_client *client, v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name, client->addr << 1, client->adapter->name); + + v4l2_dbg(1, debug, sd, "Configuring encoder\n"); + saa7127_write_inittab(sd, saa7127_init_config_common); + saa7127_set_std(sd, V4L2_STD_NTSC); + saa7127_set_output_type(sd, SAA7127_OUTPUT_TYPE_BOTH); + saa7127_set_vps(sd, &vbi); + saa7127_set_wss(sd, &vbi); + saa7127_set_cc(sd, &vbi); + saa7127_set_xds(sd, &vbi); + if (test_image == 1) + /* The Encoder has an internal Colorbar generator */ + /* This can be used for debugging */ + saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_TEST_IMAGE); + else + saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL); + saa7127_set_video_enable(sd, 1); + if (state->ident == V4L2_IDENT_SAA7129) saa7127_write_inittab(sd, saa7129_init_config_extra); return 0; -- cgit v1.2.3 From cd8f894eacf13996d920fdd2aef1afc55156b191 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Fri, 9 Jan 2009 22:59:27 -0300 Subject: V4L/DVB (10218): cx23885: Fix Oops for mixed install of analog and digital only cards Analog support for HVR-1250 has not been completed, but does exist for the HVR-1800. Since both cards use the same driver, it tries to create the analog dev for both devices, which is not possible. This causes a NULL error to show up in video_open and mpeg_open. -Mark Iterations through the cx23885_devlist must check for NULL pointers as some supported devices only have DVB support at the moment. Mark Jenks encoutered an Oops in a system with both an HVR-1250 and HVR-1800 installed. -Andy Reported-by: Mark Jenks Tested-by: Mark Jenks Signed-off-by: Mark Jenks Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-417.c | 3 ++- drivers/media/video/cx23885/cx23885-video.c | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index 8f1db57bd1d..bfe25841dbf 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c @@ -1586,7 +1586,8 @@ static int mpeg_open(struct file *file) lock_kernel(); list_for_each(list, &cx23885_devlist) { h = list_entry(list, struct cx23885_dev, devlist); - if (h->v4l_device->minor == minor) { + if (h->v4l_device && + h->v4l_device->minor == minor) { dev = h; break; } diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 2d81c4d0434..eaa11893bfe 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -730,12 +730,13 @@ static int video_open(struct file *file) lock_kernel(); list_for_each(list, &cx23885_devlist) { h = list_entry(list, struct cx23885_dev, devlist); - if (h->video_dev->minor == minor) { + if (h->video_dev && + h->video_dev->minor == minor) { dev = h; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; } if (h->vbi_dev && - h->vbi_dev->minor == minor) { + h->vbi_dev->minor == minor) { dev = h; type = V4L2_BUF_TYPE_VBI_CAPTURE; } -- cgit v1.2.3 From 7ef5e025535ee220d7ba45dcd82f05ddce8c3e4c Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sat, 10 Jan 2009 18:04:45 -0300 Subject: V4L/DVB (10219): saa7134: Prevent Oops due to stale IRQ status when enabling interrupts When enabling a shared IRQ line, then saa7134_irq handler could be invoked before the driver had completely set up internal structures, due to a shared interrupt line firing. Clear the saa7134 interrupt status reg, before requesting the irq line, so that stale IRQ status isn't processed before the internal structures are set up. Marcin Slusarz recently brought this Oops to the attention of the v4l-dvb lists and provided an initial analysis by investigating reports found here: http://kerneloops.org/guilty.php?guilty=mute_input_7133&version=2.6.27-release&start=1802240&end=1835007&class=oops Reported-by: Marcin Slusarz Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-core.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/media/video') diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index dfbe08a9ad9..99221d726ed 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -660,6 +660,10 @@ static int saa7134_hwinit1(struct saa7134_dev *dev) saa_writel(SAA7134_IRQ1, 0); saa_writel(SAA7134_IRQ2, 0); + + /* Clear any stale IRQ reports */ + saa_writel(SAA7134_IRQ_REPORT, saa_readl(SAA7134_IRQ_REPORT)); + mutex_init(&dev->lock); spin_lock_init(&dev->slock); -- cgit v1.2.3 From 45bdcefea25cad2d7443f5b45a5319e2bd201048 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Mon, 12 Jan 2009 13:09:46 -0300 Subject: V4L/DVB (10222): zoran: Better syntax for initializing array module params When initializing a module parameter that is a per-card array, use "{ [0 ... (BUZ_MAX-1)] = -1 }" instead of "{ -1, -1, -1, -1 }". This way all of the entries will be correctly set to -1 if someone changes BUZ_MAX to a value other than 4. Adjust some of the parameter help text too. Signed-off-by: Trent Piepho Acked-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/zoran/zoran_card.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c index e987d53c294..ae96de08759 100644 --- a/drivers/media/video/zoran/zoran_card.c +++ b/drivers/media/video/zoran/zoran_card.c @@ -61,17 +61,17 @@ extern const struct zoran_format zoran_formats[]; -static int card[BUZ_MAX] = { -1, -1, -1, -1 }; +static int card[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 }; module_param_array(card, int, NULL, 0444); -MODULE_PARM_DESC(card, "The type of card"); +MODULE_PARM_DESC(card, "Card type"); -static int encoder[BUZ_MAX] = { -1, -1, -1, -1 }; +static int encoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 }; module_param_array(encoder, int, NULL, 0444); -MODULE_PARM_DESC(encoder, "i2c TV encoder"); +MODULE_PARM_DESC(encoder, "Video encoder chip"); -static int decoder[BUZ_MAX] = { -1, -1, -1, -1 }; +static int decoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 }; module_param_array(decoder, int, NULL, 0444); -MODULE_PARM_DESC(decoder, "i2c TV decoder"); +MODULE_PARM_DESC(decoder, "Video decoder chip"); /* The video mem address of the video card. @@ -104,9 +104,9 @@ module_param(default_norm, int, 0444); MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)"); /* /dev/videoN, -1 for autodetect */ -static int video_nr[BUZ_MAX] = {-1, -1, -1, -1}; +static int video_nr[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 }; module_param_array(video_nr, int, NULL, 0444); -MODULE_PARM_DESC(video_nr, "video device number (-1=Auto)"); +MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)"); /* Number and size of grab buffers for Video 4 Linux -- cgit v1.2.3 From 601139e08339b15997c6ae638dc5bf42c51ea204 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Mon, 12 Jan 2009 13:09:46 -0300 Subject: V4L/DVB (10223): zoran: Remove global device array The driver was keeping a global array with an entry for each zoran device probed. It was a leftover from when the driver didn't dynamically allocate the driver data for each device. There was only one use left, in the video device's ->open() method, looking up the struct zoran for the opened device from the minor number. This can be done better with video_get_drvdata(). Since zoran_num is now only used in the pci driver's ->probe() method, it doesn't need to be an atomic_t and be static. There is a race if multiple zoran cards could be probed at the same time, but currently the probe method for a given driver is single threaded. Signed-off-by: Trent Piepho Acked-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/zoran/zoran_card.c | 9 +++------ drivers/media/video/zoran/zoran_card.h | 2 -- drivers/media/video/zoran/zoran_driver.c | 25 +++---------------------- 3 files changed, 6 insertions(+), 30 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c index ae96de08759..117650fecd8 100644 --- a/drivers/media/video/zoran/zoran_card.c +++ b/drivers/media/video/zoran/zoran_card.c @@ -159,8 +159,7 @@ static struct pci_device_id zr36067_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl); -atomic_t zoran_num = ATOMIC_INIT(0); /* number of Buzs in use */ -struct zoran *zoran[BUZ_MAX]; +static unsigned int zoran_num; /* number of cards found */ /* videocodec bus functions ZR36060 */ static u32 @@ -1144,6 +1143,7 @@ zr36057_init (struct zoran *zr) err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]); if (err < 0) goto exit_free; + video_set_drvdata(zr->video_dev, zr); zoran_init_hardware(zr); if (zr36067_debug > 2) @@ -1275,7 +1275,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev, unsigned int nr; - nr = atomic_inc_return(&zoran_num) - 1; + nr = zoran_num++; if (nr >= BUZ_MAX) { dprintk(1, KERN_ERR @@ -1291,7 +1291,6 @@ static int __devinit zoran_probe(struct pci_dev *pdev, KERN_ERR "%s: find_zr36057() - kzalloc failed\n", ZORAN_NAME); - /* The entry in zoran[] gets leaked */ return -ENOMEM; } zr->pci_dev = pdev; @@ -1547,7 +1546,6 @@ static int __devinit zoran_probe(struct pci_dev *pdev, goto zr_detach_vfe; } } - zoran[nr] = zr; /* take care of Natoma chipset and a revision 1 zr36057 */ if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) { @@ -1599,7 +1597,6 @@ static int __init zoran_init(void) { int res; - memset(zoran, 0, sizeof(zoran)); printk(KERN_INFO "Zoran MJPEG board driver version %d.%d.%d\n", MAJOR_VERSION, MINOR_VERSION, RELEASE_VERSION); diff --git a/drivers/media/video/zoran/zoran_card.h b/drivers/media/video/zoran/zoran_card.h index c989448a77d..4507bdc5e33 100644 --- a/drivers/media/video/zoran/zoran_card.h +++ b/drivers/media/video/zoran/zoran_card.h @@ -40,8 +40,6 @@ extern int zr36067_debug; /* Anybody who uses more than four? */ #define BUZ_MAX 4 -extern atomic_t zoran_num; -extern struct zoran *zoran[BUZ_MAX]; extern struct video_device zoran_template; diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index 5e667fd7272..21f37a68714 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/drivers/media/video/zoran/zoran_driver.c @@ -1196,28 +1196,13 @@ zoran_close_end_session (struct file *file) * Open a zoran card. Right now the flags stuff is just playing */ -static int -zoran_open(struct file *file) +static int zoran_open(struct file *file) { - unsigned int minor = video_devdata(file)->minor; - struct zoran *zr = NULL; + struct zoran *zr = video_drvdata(file); struct zoran_fh *fh; - int i, res, first_open = 0, have_module_locks = 0; + int res, first_open = 0, have_module_locks = 0; lock_kernel(); - /* find the device */ - for (i = 0; i < atomic_read(&zoran_num); i++) { - if (zoran[i]->video_dev->minor == minor) { - zr = zoran[i]; - break; - } - } - - if (!zr) { - dprintk(1, KERN_ERR "%s: device not found!\n", ZORAN_NAME); - res = -ENODEV; - goto open_unlock_and_return; - } /* see fs/device.c - the kernel already locks during open(), * so locking ourselves only causes deadlocks */ @@ -1329,10 +1314,6 @@ open_unlock_and_return: module_put(THIS_MODULE); } - /* if there's no device found, we didn't obtain the lock either */ - if (zr) { - /*mutex_unlock(&zr->resource_lock);*/ - } unlock_kernel(); return res; -- cgit v1.2.3 From 17faeb20912af5d2a1422fdb606e785f9b1d88ba Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Mon, 12 Jan 2009 13:09:46 -0300 Subject: V4L/DVB (10224): zoran: Use pci device table to get card type Instead of using custom code, just let the device layer look it up for us from the pci device table. This requires extending the pci device table to list each known card, plus a catch-all entry for the cards that don't have sub-system vendor/device data. Improve some of the info and error messages too. Signed-off-by: Trent Piepho Acked-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/zoran/zoran.h | 1 - drivers/media/video/zoran/zoran_card.c | 110 ++++++++++++++------------------- 2 files changed, 47 insertions(+), 64 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h index 46b7ad477ce..7273abf5eb4 100644 --- a/drivers/media/video/zoran/zoran.h +++ b/drivers/media/video/zoran/zoran.h @@ -349,7 +349,6 @@ struct card_info { u16 i2c_decoder, i2c_encoder; /* I2C types */ u16 video_vfe, video_codec; /* videocodec types */ u16 audio_chip; /* audio type */ - u16 vendor_id, device_id; /* subsystem vendor/device ID */ int inputs; /* number of video inputs */ struct input { diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c index 117650fecd8..7b73d83e127 100644 --- a/drivers/media/video/zoran/zoran_card.c +++ b/drivers/media/video/zoran/zoran_card.c @@ -153,8 +153,16 @@ MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver"); MODULE_AUTHOR("Serguei Miridonov"); MODULE_LICENSE("GPL"); +#define ZR_DEVICE(subven, subdev, data) { \ + .vendor = PCI_VENDOR_ID_ZORAN, .device = PCI_DEVICE_ID_ZORAN_36057, \ + .subvendor = (subven), .subdevice = (subdev), .driver_data = (data) } + static struct pci_device_id zr36067_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057), }, + ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC10PLUS, DC10plus), + ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC30PLUS, DC30plus), + ZR_DEVICE(PCI_VENDOR_ID_ELECTRONICDESIGNGMBH, PCI_DEVICE_ID_LML_33R10, LML33R10), + ZR_DEVICE(PCI_VENDOR_ID_IOMEGA, PCI_DEVICE_ID_IOMEGA_BUZ, BUZ), + ZR_DEVICE(PCI_ANY_ID, PCI_ANY_ID, NUM_CARDS), {0} }; MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl); @@ -476,8 +484,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = DC10plus, .name = "DC10plus", - .vendor_id = PCI_VENDOR_ID_MIRO, - .device_id = PCI_DEVICE_ID_MIRO_DC10PLUS, .i2c_decoder = I2C_DRIVERID_SAA7110, .i2c_encoder = I2C_DRIVERID_ADV7175, .video_codec = CODEC_TYPE_ZR36060, @@ -535,8 +541,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = DC30plus, .name = "DC30plus", - .vendor_id = PCI_VENDOR_ID_MIRO, - .device_id = PCI_DEVICE_ID_MIRO_DC30PLUS, .i2c_decoder = I2C_DRIVERID_VPX3220, .i2c_encoder = I2C_DRIVERID_ADV7175, .video_codec = CODEC_TYPE_ZR36050, @@ -593,8 +597,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = LML33R10, .name = "LML33R10", - .vendor_id = PCI_VENDOR_ID_ELECTRONICDESIGNGMBH, - .device_id = PCI_DEVICE_ID_LML_33R10, .i2c_decoder = I2C_DRIVERID_SAA7114, .i2c_encoder = I2C_DRIVERID_ADV7170, .video_codec = CODEC_TYPE_ZR36060, @@ -622,8 +624,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = BUZ, .name = "Buz", - .vendor_id = PCI_VENDOR_ID_IOMEGA, - .device_id = PCI_DEVICE_ID_IOMEGA_BUZ, .i2c_decoder = I2C_DRIVERID_SAA7111A, .i2c_encoder = I2C_DRIVERID_SAA7185B, .video_codec = CODEC_TYPE_ZR36060, @@ -653,8 +653,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { .name = "6-Eyes", /* AverMedia chose not to brand the 6-Eyes. Thus it can't be autodetected, and requires card=x. */ - .vendor_id = -1, - .device_id = -1, .i2c_decoder = I2C_DRIVERID_KS0127, .i2c_encoder = I2C_DRIVERID_BT866, .video_codec = CODEC_TYPE_ZR36060, @@ -1284,7 +1282,6 @@ static int __devinit zoran_probe(struct pci_dev *pdev, return -ENOENT; } - card_num = card[nr]; zr = kzalloc(sizeof(struct zoran), GFP_KERNEL); if (!zr) { dprintk(1, @@ -1302,68 +1299,55 @@ static int __devinit zoran_probe(struct pci_dev *pdev, goto zr_free_mem; zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0); pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision); - if (zr->revision < 2) { + + dprintk(1, + KERN_INFO + "%s: Zoran ZR360%c7 (rev %d), irq: %d, memory: 0x%08x\n", + ZR_DEVNAME(zr), zr->revision < 2 ? '5' : '6', zr->revision, + zr->pci_dev->irq, zr->zr36057_adr); + if (zr->revision >= 2) { dprintk(1, KERN_INFO - "%s: Zoran ZR36057 (rev %d) irq: %d, memory: 0x%08x.\n", - ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq, - zr->zr36057_adr); + "%s: Subsystem vendor=0x%04x id=0x%04x\n", + ZR_DEVNAME(zr), zr->pci_dev->subsystem_vendor, + zr->pci_dev->subsystem_device); + } - if (card_num == -1) { + /* Use auto-detected card type? */ + if (card[nr] == -1) { + if (zr->revision < 2) { + dprintk(1, + KERN_ERR + "%s: No card type specified, please use the card=X module parameter\n", + ZR_DEVNAME(zr)); dprintk(1, KERN_ERR - "%s: find_zr36057() - no card specified, please use the card=X insmod option\n", + "%s: It is not possible to auto-detect ZR36057 based cards\n", ZR_DEVNAME(zr)); goto zr_free_mem; } - } else { - int i; - unsigned short ss_vendor, ss_device; - ss_vendor = zr->pci_dev->subsystem_vendor; - ss_device = zr->pci_dev->subsystem_device; - dprintk(1, - KERN_INFO - "%s: Zoran ZR36067 (rev %d) irq: %d, memory: 0x%08x\n", - ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq, - zr->zr36057_adr); - dprintk(1, - KERN_INFO - "%s: subsystem vendor=0x%04x id=0x%04x\n", - ZR_DEVNAME(zr), ss_vendor, ss_device); - if (card_num == -1) { - dprintk(3, - KERN_DEBUG - "%s: find_zr36057() - trying to autodetect card type\n", + card_num = ent->driver_data; + if (card_num >= NUM_CARDS) { + dprintk(1, + KERN_ERR + "%s: Unknown card, try specifying card=X module parameter\n", ZR_DEVNAME(zr)); - for (i = 0; i < NUM_CARDS; i++) { - if (ss_vendor == zoran_cards[i].vendor_id && - ss_device == zoran_cards[i].device_id) { - dprintk(3, - KERN_DEBUG - "%s: find_zr36057() - card %s detected\n", - ZR_DEVNAME(zr), - zoran_cards[i].name); - card_num = i; - break; - } - } - if (i == NUM_CARDS) { - dprintk(1, - KERN_ERR - "%s: find_zr36057() - unknown card\n", - ZR_DEVNAME(zr)); - goto zr_free_mem; - } + goto zr_free_mem; + } + dprintk(3, + KERN_DEBUG + "%s: %s() - card %s detected\n", + ZR_DEVNAME(zr), __func__, zoran_cards[card_num].name); + } else { + card_num = card[nr]; + if (card_num >= NUM_CARDS || card_num < 0) { + dprintk(1, + KERN_ERR + "%s: User specified card type %d out of range (0 .. %d)\n", + ZR_DEVNAME(zr), card_num, NUM_CARDS - 1); + goto zr_free_mem; } - } - - if (card_num < 0 || card_num >= NUM_CARDS) { - dprintk(2, - KERN_ERR - "%s: find_zr36057() - invalid cardnum %d\n", - ZR_DEVNAME(zr), card_num); - goto zr_free_mem; } /* even though we make this a non pointer and thus -- cgit v1.2.3 From 5e098b668977c85838af09005bd96c2e987654f0 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Mon, 12 Jan 2009 13:09:46 -0300 Subject: V4L/DVB (10225): zoran: Remove zr36057_adr field The driver should only use the kernel mapped io address, zr36057_mem, and not the PCI bus address, zr36057_adr. Since the latter is only printed out once, there is no need to save it in the driver data structure. There was some old code that looked like it was for the Alpha architecture which would use the PCI bus address. It probably no longer applies to modern kernels. Signed-off-by: Trent Piepho Acked-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/zoran/zoran.h | 11 ++--------- drivers/media/video/zoran/zoran_card.c | 11 +++++------ 2 files changed, 7 insertions(+), 15 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h index 7273abf5eb4..e873a916250 100644 --- a/drivers/media/video/zoran/zoran.h +++ b/drivers/media/video/zoran/zoran.h @@ -400,7 +400,6 @@ struct zoran { char name[32]; /* name of this device */ struct pci_dev *pci_dev; /* PCI device */ unsigned char revision; /* revision of zr36057 */ - unsigned int zr36057_adr; /* bus address of IO mem returned by PCI BIOS */ unsigned char __iomem *zr36057_mem;/* pointer to mapped IO memory */ spinlock_t spinlock; /* Spinlock */ @@ -489,16 +488,10 @@ struct zoran { wait_queue_head_t test_q; }; -/*The following should be done in more portable way. It depends on define - of _ALPHA_BUZ in the Makefile.*/ - -#ifdef _ALPHA_BUZ -#define btwrite(dat,adr) writel((dat), zr->zr36057_adr+(adr)) -#define btread(adr) readl(zr->zr36057_adr+(adr)) -#else +/* There was something called _ALPHA_BUZ that used the PCI address instead of + * the kernel iomapped address for btread/btwrite. */ #define btwrite(dat,adr) writel((dat), zr->zr36057_mem+(adr)) #define btread(adr) readl(zr->zr36057_mem+(adr)) -#endif #define btand(dat,adr) btwrite((dat) & btread(adr), adr) #define btor(dat,adr) btwrite((dat) | btread(adr), adr) diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c index 7b73d83e127..5d2f090aa0f 100644 --- a/drivers/media/video/zoran/zoran_card.c +++ b/drivers/media/video/zoran/zoran_card.c @@ -1297,14 +1297,13 @@ static int __devinit zoran_probe(struct pci_dev *pdev, mutex_init(&zr->resource_lock); if (pci_enable_device(pdev)) goto zr_free_mem; - zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0); pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision); dprintk(1, KERN_INFO - "%s: Zoran ZR360%c7 (rev %d), irq: %d, memory: 0x%08x\n", + "%s: Zoran ZR360%c7 (rev %d), irq: %d, memory: 0x%08llx\n", ZR_DEVNAME(zr), zr->revision < 2 ? '5' : '6', zr->revision, - zr->pci_dev->irq, zr->zr36057_adr); + zr->pci_dev->irq, (uint64_t)pci_resource_start(zr->pci_dev, 0)); if (zr->revision >= 2) { dprintk(1, KERN_INFO @@ -1359,12 +1358,12 @@ static int __devinit zoran_probe(struct pci_dev *pdev, snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "%s[%u]", zr->card.name, zr->id); - zr->zr36057_mem = ioremap_nocache(zr->zr36057_adr, 0x1000); + zr->zr36057_mem = pci_ioremap_bar(zr->pci_dev, 0); if (!zr->zr36057_mem) { dprintk(1, KERN_ERR - "%s: find_zr36057() - ioremap failed\n", - ZR_DEVNAME(zr)); + "%s: %s() - ioremap failed\n", + ZR_DEVNAME(zr), __func__); goto zr_free_mem; } -- cgit v1.2.3 From fc96ab730268b8b652ae2494088e8bd4572f58aa Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Mon, 12 Jan 2009 13:09:46 -0300 Subject: V4L/DVB (10226): zoran: Get rid of extra module ref count The zoran driver does a module_get/put of THIS_MODULE on device open/close. This isn't necessary as the kernel does this automatically. Clean up the failure path of zoran_open() somewhat. Make the dprintk()s on open/close a higher debug level and make the user count printed take the current open/close into account. Signed-off-by: Trent Piepho Acked-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/zoran/zoran_driver.c | 82 +++++++++++++------------------- 1 file changed, 33 insertions(+), 49 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index 21f37a68714..120ef235e63 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/drivers/media/video/zoran/zoran_driver.c @@ -1200,7 +1200,10 @@ static int zoran_open(struct file *file) { struct zoran *zr = video_drvdata(file); struct zoran_fh *fh; - int res, first_open = 0, have_module_locks = 0; + int res, first_open = 0; + + dprintk(2, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n", + ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user + 1); lock_kernel(); @@ -1208,56 +1211,39 @@ static int zoran_open(struct file *file) * so locking ourselves only causes deadlocks */ /*mutex_lock(&zr->resource_lock);*/ + if (zr->user >= 2048) { + dprintk(1, KERN_ERR "%s: too many users (%d) on device\n", + ZR_DEVNAME(zr), zr->user); + res = -EBUSY; + goto fail_unlock; + } + if (!zr->decoder) { dprintk(1, KERN_ERR "%s: no TV decoder loaded for device!\n", ZR_DEVNAME(zr)); res = -EIO; - goto open_unlock_and_return; + goto fail_unlock; } - /* try to grab a module lock */ - if (!try_module_get(THIS_MODULE)) { - dprintk(1, - KERN_ERR - "%s: failed to acquire my own lock! PANIC!\n", - ZR_DEVNAME(zr)); - res = -ENODEV; - goto open_unlock_and_return; - } if (!try_module_get(zr->decoder->driver->driver.owner)) { dprintk(1, KERN_ERR - "%s: failed to grab ownership of i2c decoder\n", + "%s: failed to grab ownership of video decoder\n", ZR_DEVNAME(zr)); res = -EIO; - module_put(THIS_MODULE); - goto open_unlock_and_return; + goto fail_unlock; } if (zr->encoder && !try_module_get(zr->encoder->driver->driver.owner)) { dprintk(1, KERN_ERR - "%s: failed to grab ownership of i2c encoder\n", + "%s: failed to grab ownership of video encoder\n", ZR_DEVNAME(zr)); res = -EIO; - module_put(zr->decoder->driver->driver.owner); - module_put(THIS_MODULE); - goto open_unlock_and_return; - } - - have_module_locks = 1; - - if (zr->user >= 2048) { - dprintk(1, KERN_ERR "%s: too many users (%d) on device\n", - ZR_DEVNAME(zr), zr->user); - res = -EBUSY; - goto open_unlock_and_return; + goto fail_decoder; } - dprintk(1, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n", - ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user); - /* now, create the open()-specific file_ops struct */ fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL); if (!fh) { @@ -1266,7 +1252,7 @@ static int zoran_open(struct file *file) "%s: zoran_open() - allocation of zoran_fh failed\n", ZR_DEVNAME(zr)); res = -ENOMEM; - goto open_unlock_and_return; + goto fail_encoder; } /* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows * on norm-change! */ @@ -1277,9 +1263,8 @@ static int zoran_open(struct file *file) KERN_ERR "%s: zoran_open() - allocation of overlay_mask failed\n", ZR_DEVNAME(zr)); - kfree(fh); res = -ENOMEM; - goto open_unlock_and_return; + goto fail_fh; } if (zr->user++ == 0) @@ -1304,18 +1289,19 @@ static int zoran_open(struct file *file) return 0; -open_unlock_and_return: - /* if we grabbed locks, release them accordingly */ - if (have_module_locks) { - module_put(zr->decoder->driver->driver.owner); - if (zr->encoder) { - module_put(zr->encoder->driver->driver.owner); - } - module_put(THIS_MODULE); - } - +fail_fh: + kfree(fh); +fail_encoder: + if (zr->encoder) + module_put(zr->encoder->driver->driver.owner); +fail_decoder: + module_put(zr->decoder->driver->driver.owner); +fail_unlock: unlock_kernel(); + dprintk(2, KERN_INFO "%s: open failed (%d), users(-)=%d\n", + ZR_DEVNAME(zr), res, zr->user); + return res; } @@ -1325,8 +1311,8 @@ zoran_close(struct file *file) struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; - dprintk(1, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n", - ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user); + dprintk(2, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n", + ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user - 1); /* kernel locks (fs/device.c), so don't do that ourselves * (prevents deadlocks) */ @@ -1372,10 +1358,8 @@ zoran_close(struct file *file) /* release locks on the i2c modules */ module_put(zr->decoder->driver->driver.owner); - if (zr->encoder) { - module_put(zr->encoder->driver->driver.owner); - } - module_put(THIS_MODULE); + if (zr->encoder) + module_put(zr->encoder->driver->driver.owner); /*mutex_unlock(&zr->resource_lock);*/ -- cgit v1.2.3 From 8866f9cf8d85f3614855a49b9d9056f265d0cd33 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 12 Jan 2009 21:50:52 -0300 Subject: V4L/DVB (10228): em28xx: fix audio output PCM IN selection Some em28xx devices use the PCM IN AC 97 PIN for digital audio. However, currently, the PCM IN selection is not set by the driver. This patch allows specifying the PCM IN expected output, via board description table. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-core.c | 9 +++++++++ drivers/media/video/em28xx/em28xx.h | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+) (limited to 'drivers/media/video') diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index eb5fb05fab2..69ce78867a4 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -454,6 +454,15 @@ int em28xx_audio_analog_set(struct em28xx *dev) em28xx_warn("couldn't setup AC97 register %d\n", outputs[i].reg); } + + if (dev->ctl_aoutput & EM28XX_AOUT_PCM_IN) { + int sel = ac97_return_record_select(dev->ctl_aoutput); + + /* Use the same input for both left and right channels */ + sel |= (sel << 8); + + em28xx_write_ac97(dev, AC97_RECORD_SELECT, sel); + } } return ret; diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 6c6b94aa05b..23d1482df2d 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -300,13 +300,32 @@ enum em28xx_amux { }; enum em28xx_aout { + /* AC97 outputs */ EM28XX_AOUT_MASTER = 1 << 0, EM28XX_AOUT_LINE = 1 << 1, EM28XX_AOUT_MONO = 1 << 2, EM28XX_AOUT_LFE = 1 << 3, EM28XX_AOUT_SURR = 1 << 4, + + /* PCM IN Mixer - used by AC97_RECORD_SELECT register */ + EM28XX_AOUT_PCM_IN = 1 << 7, + + /* Bits 10-8 are used to indicate the PCM IN record select */ + EM28XX_AOUT_PCM_MIC_PCM = 0 << 8, + EM28XX_AOUT_PCM_CD = 1 << 8, + EM28XX_AOUT_PCM_VIDEO = 2 << 8, + EM28XX_AOUT_PCM_AUX = 3 << 8, + EM28XX_AOUT_PCM_LINE = 4 << 8, + EM28XX_AOUT_PCM_STEREO = 5 << 8, + EM28XX_AOUT_PCM_MONO = 6 << 8, + EM28XX_AOUT_PCM_PHONE = 7 << 8, }; +static int ac97_return_record_select(int a_out) +{ + return (a_out & 0x700) >> 8; +} + struct em28xx_reg_seq { int reg; unsigned char val, mask; -- cgit v1.2.3 From 6e0e12f15a503b7096303d495247fbeaa2b12582 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 11 Jan 2009 21:18:04 -0300 Subject: V4L/DVB (10229): cx88-dvb: Fix order of frontend allocations On Fri, 2009-01-09 at 15:40 +0300, Goga777 wrote: > hI > > With today v4l-dvb I couldn't run my hvr4000 card on 2.6.27 kernel > [ 14.555162] cx88/2: cx2388x dvb driver version 0.0.6 loaded > [ 14.555231] cx88/2: registering cx8802 driver, type: dvb access: shared > [ 14.555303] cx88[0]/2: subsystem: 0070:6900, board: Hauppauge WinTV-HVR4000 DVB-S/S2/T/Hybrid [card=68] > [ 14.555374] cx88[0]/2: cx2388x based DVB/ATSC card > [ 14.555446] BUG: unable to handle kernel NULL pointer dereference at 00000000 > [ 14.555560] IP: [] __mutex_lock_common+0x3c/0xe4 > [ 14.555652] *pde = 00000000 > [ 14.555735] Oops: 0002 [#1] SMP > [ 14.555851] Modules linked in: cx88_dvb(+) cx88_vp3054_i2c videobuf_dvb wm8775 dvb_core tuner_simple tuner_types snd_seq_dummy tda9887 snd_seq_oss(+) snd_intel8x0(+) tda8290 snd_seq_midi snd_seq_midi_event snd_ac97_codec cx88_alsa(+) snd_seq ac97_bus snd_pcm_oss snd_mixer_oss snd_pcm snd_rawmidi snd_timer tuner snd_seq_device psmouse snd serio_raw ivtv(+) cx8800 cx8802 cx88xx soundcore cx2341x ir_common ns558 i2c_i801 v4l2_common videodev i2c_algo_bit gameport v4l1_compat snd_page_alloc tveeprom pcspkr floppy videobuf_dma_sg videobuf_core btcx_risc i2c_core parport_pc parport button intel_agp agpgart shpchp pci_hotplug rng_core iTCO_wdt sd_mod evdev usbhid hid ff_memless ext3 jbd mbcache ide_cd_mod cdrom ide_disk ata_piix libata dock 8139too usb_storage scsi_mod piix 8139cp mii ide_core uhci_hcd ehci_hcd usbcore thermal processor fan thermal_sys > [ 14.557013] > [ 14.557013] Pid: 2310, comm: modprobe Not tainted (2.6.27.1-custom-default1 #1) > [ 14.557013] EIP: 0060:[] EFLAGS: 00010246 CPU: 1 > [ 14.557013] EIP is at __mutex_lock_common+0x3c/0xe4 > [ 14.557013] EAX: de653e98 EBX: de739118 ECX: de739120 EDX: 00000000 > [ 14.557013] ESI: dd4209e0 EDI: de73911c EBP: de653eb0 ESP: de653e88 > [ 14.557013] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 > [ 14.557013] Process modprobe (pid: 2310, ti=de652000 task=dd4209e0 task.ti=de652000) > [ 14.557013] Stack: 3535352e 5d343733 00000002 de739120 de739120 00000000 c044a6c0 de739110 > [ 14.557013] de739118 00000001 de653ebc c02e6d38 c02e6b88 de653ec4 c02e6b88 de653ed8 > [ 14.557013] e1ac7115 de6a9000 00000001 00000000 de653f0c e1aeca62 de739004 de739000 > [ 14.557013] Call Trace: > [ 14.557013] [] ? __mutex_lock_slowpath+0x17/0x1a > [ 14.557013] [] ? mutex_lock+0x12/0x14 > [ 14.557013] [] ? mutex_lock+0x12/0x14 > [ 14.557013] [] ? videobuf_dvb_get_frontend+0x19/0x40 [videobuf_dvb] > [ 14.557013] [] ? cx8802_dvb_probe+0xc9/0x1945 [cx88_dvb] > [ 14.557013] [] ? cx8802_register_driver+0xbd/0x1ac [cx8802] > [ 14.557013] [] ? cx8802_register_driver+0x106/0x1ac [cx8802] > [ 14.557013] [] ? dvb_init+0x22/0x27 [cx88_dvb] > [ 14.557013] [] ? _stext+0x42/0x11a > [ 14.557013] [] ? dvb_init+0x0/0x27 [cx88_dvb] > [ 14.557013] [] ? __blocking_notifier_call_chain+0xe/0x51 > [ 14.557013] [] ? sys_init_module+0x8c/0x17d > [ 14.557013] [] ? syscall_call+0x7/0xb > [ 14.557013] [] ? round_jiffies_relative+0x14/0x16 > [ 14.557013] ======================= > [ 14.557013] Code: 78 04 89 f8 89 55 e0 64 8b 35 00 30 3f c0 e8 2e 0c 00 00 8d 43 08 89 45 e4 8b 53 0c 8d 45 e8 8b 4d e4 89 43 0c 89 4d e8 89 55 ec <89> 02 89 75 f0 83 c8 ff 87 03 48 74 55 8a 45 e0 8b 4d e0 83 e0 > [ 14.557013] EIP: [] __mutex_lock_common+0x3c/0xe4 SS:ESP 0068:de653e88 > [ 14.565211] ---[ end trace 94d8b014e067ac7b ]--- Tested and confirmed to work by several users at linux-media@vger.kernel.org Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx88/cx88-dvb.c | 72 +++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 34 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index 613dfea4ff3..aef5297534a 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c @@ -614,34 +614,41 @@ static struct stv0288_config tevii_tuner_earda_config = { .set_ts_params = cx24116_set_ts_param, }; -static int dvb_register(struct cx8802_dev *dev) +static int cx8802_alloc_frontends(struct cx8802_dev *dev) { struct cx88_core *core = dev->core; - struct videobuf_dvb_frontend *fe0, *fe1 = NULL; - int mfe_shared = 0; /* bus not shared by default */ + struct videobuf_dvb_frontend *fe = NULL; int i; - if (0 != core->i2c_rc) { - printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name); - goto frontend_detach; - } - - if (!core->board.num_frontends) - return -EINVAL; - mutex_init(&dev->frontends.lock); INIT_LIST_HEAD(&dev->frontends.felist); + if (!core->board.num_frontends) + return -ENODEV; + printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, core->board.num_frontends); for (i = 1; i <= core->board.num_frontends; i++) { - fe0 = videobuf_dvb_alloc_frontend(&dev->frontends, i); - if (!fe0) { + fe = videobuf_dvb_alloc_frontend(&dev->frontends, i); + if (!fe) { printk(KERN_ERR "%s() failed to alloc\n", __func__); videobuf_dvb_dealloc_frontends(&dev->frontends); - goto frontend_detach; + return -ENOMEM; } } + return 0; +} + +static int dvb_register(struct cx8802_dev *dev) +{ + struct cx88_core *core = dev->core; + struct videobuf_dvb_frontend *fe0, *fe1 = NULL; + int mfe_shared = 0; /* bus not shared by default */ + + if (0 != core->i2c_rc) { + printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name); + goto frontend_detach; + } /* Get the first frontend */ fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); @@ -1243,6 +1250,8 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) struct cx88_core *core = drv->core; struct cx8802_dev *dev = drv->core->dvbdev; int err; + struct videobuf_dvb_frontend *fe; + int i; dprintk( 1, "%s\n", __func__); dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", @@ -1258,39 +1267,34 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) /* If vp3054 isn't enabled, a stub will just return 0 */ err = vp3054_i2c_probe(dev); if (0 != err) - goto fail_probe; + goto fail_core; /* dvb stuff */ printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name); dev->ts_gen_cntrl = 0x0c; + err = cx8802_alloc_frontends(dev); + if (err) + goto fail_core; + err = -ENODEV; - if (core->board.num_frontends) { - struct videobuf_dvb_frontend *fe; - int i; - - for (i = 1; i <= core->board.num_frontends; i++) { - fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i); - if (fe == NULL) { - printk(KERN_ERR "%s() failed to get frontend(%d)\n", + for (i = 1; i <= core->board.num_frontends; i++) { + fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i); + if (fe == NULL) { + printk(KERN_ERR "%s() failed to get frontend(%d)\n", __func__, i); - goto fail_probe; - } - videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops, + goto fail_probe; + } + videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops, &dev->pci->dev, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, sizeof(struct cx88_buffer), dev); - /* init struct videobuf_dvb */ - fe->dvb.name = dev->core->name; - } - } else { - /* no frontends allocated */ - printk(KERN_ERR "%s/2 .num_frontends should be non-zero\n", - core->name); - goto fail_core; + /* init struct videobuf_dvb */ + fe->dvb.name = dev->core->name; } + err = dvb_register(dev); if (err) /* frontends/adapter de-allocated in dvb_register */ -- cgit v1.2.3 From aeaecaf8eba9efa6a0a623122abb8f61449e42ef Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Wed, 14 Jan 2009 04:58:36 -0300 Subject: V4L/DVB (10240): Fix obvious swapped names in v4l2_subdev logic The VIDIOC_QUERYCTRL command needs to actually do a queryctrl, not a querymenu. Similarly, the VIDIOC_QUERYMENU command needs to actually do a querymenu not a queryctrl. Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-subdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c index fbe9cc0d433..21208805ea9 100644 --- a/drivers/media/video/v4l2-subdev.c +++ b/drivers/media/video/v4l2-subdev.c @@ -28,13 +28,13 @@ int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg) { switch (cmd) { case VIDIOC_QUERYCTRL: - return v4l2_subdev_call(sd, core, querymenu, arg); + return v4l2_subdev_call(sd, core, queryctrl, arg); case VIDIOC_G_CTRL: return v4l2_subdev_call(sd, core, g_ctrl, arg); case VIDIOC_S_CTRL: return v4l2_subdev_call(sd, core, s_ctrl, arg); case VIDIOC_QUERYMENU: - return v4l2_subdev_call(sd, core, queryctrl, arg); + return v4l2_subdev_call(sd, core, querymenu, arg); case VIDIOC_LOG_STATUS: return v4l2_subdev_call(sd, core, log_status); case VIDIOC_DBG_G_CHIP_IDENT: -- cgit v1.2.3 From 32929fb4c7c4a693ed723253b21e7bf3c8cb4b1c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 17 Jan 2009 11:21:02 -0300 Subject: V4L/DVB (10243): em28xx: fix compile warning Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 23d1482df2d..e15ca2f0fb1 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -321,7 +321,7 @@ enum em28xx_aout { EM28XX_AOUT_PCM_PHONE = 7 << 8, }; -static int ac97_return_record_select(int a_out) +static inline int ac97_return_record_select(int a_out) { return (a_out & 0x700) >> 8; } -- cgit v1.2.3 From cf8e193a48879a02f55b53c0cf2ec98a784baaa5 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 17 Jan 2009 13:09:11 -0300 Subject: V4L/DVB (10248): v4l-dvb: fix a bunch of compile warnings. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tda9875.c | 2 +- drivers/media/video/usbvision/usbvision-i2c.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c index 56f0c0eb500..00c6cbe06ab 100644 --- a/drivers/media/video/tda9875.c +++ b/drivers/media/video/tda9875.c @@ -242,7 +242,7 @@ static int tda9875_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) static int tda9875_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { struct tda9875 *t = to_state(sd); - int chvol=0, volume, balance, left, right; + int chvol = 0, volume = 0, balance = 0, left, right; switch (ctrl->id) { case V4L2_CID_AUDIO_VOLUME: diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c index 9907b9aff2b..6b66ae4f430 100644 --- a/drivers/media/video/usbvision/usbvision-i2c.c +++ b/drivers/media/video/usbvision/usbvision-i2c.c @@ -157,7 +157,7 @@ usbvision_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) struct i2c_msg *pmsg; struct usb_usbvision *usbvision; int i, ret; - unsigned char addr; + unsigned char addr = 0; usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap); -- cgit v1.2.3 From ba390f005573bdf6ab7fd78bb05119036c2ed539 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 15 Jan 2009 05:37:14 -0300 Subject: V4L/DVB (10250): cx25840: fix regression: fw not loaded on first use With the conversion to v4l2_subdev one bit of code was accidentally dropped: on receiving the first command the driver has to load the fw. A new init() command was introduced to do that explicitly for bridge drivers that are converted to use v4l2_subdev, but old drivers that are not yet converted no longer worked. This patch fixes this regression for these old drivers. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx25840/cx25840-core.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/media/video') diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 88f2fd32bfe..b3b5b17dc8e 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -1382,6 +1382,14 @@ static int cx25840_log_status(struct v4l2_subdev *sd) static int cx25840_command(struct i2c_client *client, unsigned cmd, void *arg) { + /* ignore this command */ + if (cmd == TUNER_SET_TYPE_ADDR) + return 0; + + /* Old-style drivers rely on initialization on first use, so + call the init whenever a command is issued to this driver. + New-style drivers using v4l2_subdev should call init explicitly. */ + cx25840_init(i2c_get_clientdata(client), 0); return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); } -- cgit v1.2.3 From 53d12e5a56934c31ca59f3b6f127e5a68e645fd2 Mon Sep 17 00:00:00 2001 From: Robert Krakora Date: Fri, 16 Jan 2009 11:23:25 -0300 Subject: V4L/DVB (10254): em28xx: Fix audio URB transfer buffer race condition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit em28xx: Fix audio URB transfer buffer memory leak and race condition/corruption of capture pointer Leak fix kindly contributed by Pádraig Brady. Signed-off-by: Robert Krakora Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-audio.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index 94378ccb750..4df6d328842 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c @@ -65,6 +65,9 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev) usb_unlink_urb(dev->adev.urb[i]); usb_free_urb(dev->adev.urb[i]); dev->adev.urb[i] = NULL; + + kfree(dev->adev.transfer_buffer[i]); + dev->adev.transfer_buffer[i] = NULL; } return 0; @@ -389,11 +392,15 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream, static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream *substream) { - struct em28xx *dev; + unsigned long flags; + struct em28xx *dev; snd_pcm_uframes_t hwptr_done; + dev = snd_pcm_substream_chip(substream); + spin_lock_irqsave(&dev->adev.slock, flags); hwptr_done = dev->adev.hwptr_done_capture; + spin_unlock_irqrestore(&dev->adev.slock, flags); return hwptr_done; } -- cgit v1.2.3 From 7e4b15e4201a101840c226dafe0d3df7ee652bf6 Mon Sep 17 00:00:00 2001 From: Robert Krakora Date: Sun, 18 Jan 2009 21:45:28 -0300 Subject: V4L/DVB (10256): em28xx: Fix for KWorld 330U AC97 Fix for KWorld 330U AC97 Many thanks to Devin and Mauro again!!! Signed-off-by: Robert Krakora Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-core.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/media/video') diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 69ce78867a4..71ad35192c0 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -438,6 +438,10 @@ int em28xx_audio_analog_set(struct em28xx *dev) if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { int vol; + em28xx_write_ac97(dev, AC97_POWER_DOWN_CTRL, 0x4200); + em28xx_write_ac97(dev, AC97_EXT_AUD_CTRL, 0x0031); + em28xx_write_ac97(dev, AC97_PCM_IN_SRATE, 0xbb80); + /* LSB: left channel - both channels with the same level */ vol = (0x1f - dev->volume) | ((0x1f - dev->volume) << 8); -- cgit v1.2.3 From 6e7b9ea0937eeb75fa166ef7bd22b5f3bb5676d1 Mon Sep 17 00:00:00 2001 From: Robert Krakora Date: Sun, 18 Jan 2009 21:59:34 -0300 Subject: V4L/DVB (10257): em28xx: Fix for KWorld 330U Board Fix for KWorld 330U Board Many thanks to Devin and Mauro!!! Signed-off-by: Robert Krakora Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-cards.c | 32 +++++++++++++++++++++++++------ drivers/media/video/em28xx/em28xx-dvb.c | 20 ++++++++++++++++++- drivers/media/video/em28xx/em28xx-video.c | 4 +++- drivers/media/video/em28xx/em28xx.h | 2 +- 4 files changed, 49 insertions(+), 9 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index ef9bf008a92..3b3ca3f46d5 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -102,6 +102,18 @@ static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = { /* Board - EM2870 Kworld 355u Analog - No input analog */ +static struct em28xx_reg_seq kworld_330u_analog[] = { + {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10}, + {EM2880_R04_GPO, 0x00, 0xff, 10}, + { -1, -1, -1, -1}, +}; + +static struct em28xx_reg_seq kworld_330u_digital[] = { + {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10}, + {EM2880_R04_GPO, 0x08, 0xff, 10}, + { -1, -1, -1, -1}, +}; + /* Callback for the most boards */ static struct em28xx_reg_seq default_tuner_gpio[] = { {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, @@ -1177,29 +1189,33 @@ struct em28xx_board em28xx_boards[] = { .gpio = hauppauge_wintv_hvr_900_analog, } }, }, - [EM2883_BOARD_KWORLD_HYBRID_A316] = { + [EM2883_BOARD_KWORLD_HYBRID_330U] = { .name = "Kworld PlusTV HD Hybrid 330", .tuner_type = TUNER_XC2028, .tuner_gpio = default_tuner_gpio, .decoder = EM28XX_TVP5150, .mts_firmware = 1, .has_dvb = 1, - .dvb_gpio = default_digital, + .dvb_gpio = kworld_330u_digital, + .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_EEPROM_ON_BOARD | EM28XX_I2C_EEPROM_KEY_VALID, .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = TVP5150_COMPOSITE0, .amux = EM28XX_AMUX_VIDEO, - .gpio = default_analog, + .gpio = kworld_330u_analog, + .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, }, { .type = EM28XX_VMUX_COMPOSITE1, .vmux = TVP5150_COMPOSITE1, .amux = EM28XX_AMUX_LINE_IN, - .gpio = hauppauge_wintv_hvr_900_analog, + .gpio = kworld_330u_analog, + .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, }, { .type = EM28XX_VMUX_SVIDEO, .vmux = TVP5150_SVIDEO, .amux = EM28XX_AMUX_LINE_IN, - .gpio = hauppauge_wintv_hvr_900_analog, + .gpio = kworld_330u_analog, } }, }, [EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = { @@ -1249,7 +1265,7 @@ struct usb_device_id em28xx_id_table [] = { { USB_DEVICE(0xeb1a, 0xe310), .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD }, { USB_DEVICE(0xeb1a, 0xa316), - .driver_info = EM2883_BOARD_KWORLD_HYBRID_A316 }, + .driver_info = EM2883_BOARD_KWORLD_HYBRID_330U }, { USB_DEVICE(0xeb1a, 0xe320), .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD_II }, { USB_DEVICE(0xeb1a, 0xe323), @@ -1526,6 +1542,10 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) /* FIXME: Better to specify the needed IF */ ctl->demod = XC3028_FE_DEFAULT; break; + case EM2883_BOARD_KWORLD_HYBRID_330U: + ctl->demod = XC3028_FE_CHINA; + ctl->fname = XC2028_DEFAULT_FIRMWARE; + break; default: ctl->demod = XC3028_FE_OREN538; } diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index d38cb21834d..9ad8527b3fd 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c @@ -28,6 +28,7 @@ #include "lgdt330x.h" #include "zl10353.h" +#include "s5h1409.h" #ifdef EM28XX_DRX397XD_SUPPORT #include "drx397xD.h" #endif @@ -232,6 +233,15 @@ static struct zl10353_config em28xx_zl10353_with_xc3028 = { .if2 = 45600, }; +static struct s5h1409_config em28xx_s5h1409_with_xc3028 = { + .demod_address = 0x32 >> 1, + .output_mode = S5H1409_PARALLEL_OUTPUT, + .gpio = S5H1409_GPIO_OFF, + .inversion = S5H1409_INVERSION_OFF, + .status_mode = S5H1409_DEMODLOCKING, + .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK +}; + #ifdef EM28XX_DRX397XD_SUPPORT /* [TODO] djh - not sure yet what the device config needs to contain */ static struct drx397xD_config em28xx_drx397xD_with_xc3028 = { @@ -412,7 +422,6 @@ static int dvb_init(struct em28xx *dev) case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: - case EM2883_BOARD_KWORLD_HYBRID_A316: case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: dvb->frontend = dvb_attach(lgdt330x_attach, &em2880_lgdt3303_dev, @@ -433,6 +442,15 @@ static int dvb_init(struct em28xx *dev) goto out_free; } break; + case EM2883_BOARD_KWORLD_HYBRID_330U: + dvb->frontend = dvb_attach(s5h1409_attach, + &em28xx_s5h1409_with_xc3028, + &dev->i2c_adap); + if (attach_xc3028(0x61, dev) < 0) { + result = -EINVAL; + goto out_free; + } + break; case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: #ifdef EM28XX_DRX397XD_SUPPORT /* We don't have the config structure properly populated, so diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index d40650655f7..8e61b2ca916 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -1956,6 +1956,7 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev, int em28xx_register_analog_devices(struct em28xx *dev) { + u8 val; int ret; printk(KERN_INFO "%s: v4l2 driver version %d.%d.%d\n", @@ -1983,7 +1984,8 @@ int em28xx_register_analog_devices(struct em28xx *dev) /* enable vbi capturing */ /* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */ -/* em28xx_write_reg(dev, EM28XX_R0F_XCLK, 0x80); clk register */ + val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK); + em28xx_write_reg(dev, EM28XX_R0F_XCLK, (EM28XX_XCLK_AUDIO_UNMUTE | val)); em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51); em28xx_set_outfmt(dev); diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index e15ca2f0fb1..dd2cd36fb1b 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -94,7 +94,7 @@ #define EM2882_BOARD_KWORLD_VS_DVBT 54 #define EM2882_BOARD_TERRATEC_HYBRID_XS 55 #define EM2882_BOARD_PINNACLE_HYBRID_PRO 56 -#define EM2883_BOARD_KWORLD_HYBRID_A316 57 +#define EM2883_BOARD_KWORLD_HYBRID_330U 57 #define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58 #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 60 #define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2 61 -- cgit v1.2.3 From 8760e5b6d1dc9527e0f96f80daaa12a8158d9839 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Sat, 17 Jan 2009 13:41:54 -0300 Subject: V4L/DVB (10261): em28xx: fix kernel panic on audio shutdown Revert a change made in change 9743 which resulted in a kernel panic in some cases on shutdown of the audio stream. First discovered when working on the Pinnacle 880e support, and later reproduced by a user on the mailing list with the HVR-900 as well. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index 4df6d328842..fcc300c9399 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c @@ -62,7 +62,7 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev) dprintk("Stopping isoc\n"); for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { - usb_unlink_urb(dev->adev.urb[i]); + usb_kill_urb(dev->adev.urb[i]); usb_free_urb(dev->adev.urb[i]); dev->adev.urb[i] = NULL; -- cgit v1.2.3 From 6d9f13c47a009ccbaf40c2e388ab349690dd8000 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 27 Jan 2009 06:20:34 -0300 Subject: V4L/DVB (10314): cx25840: ignore TUNER_SET_CONFIG in the command callback. These days TUNER_SET_CONFIG is broadcast to the other i2c devices and that triggers a fw load on the cx25840. Ignore this command since cx25840 isn't a tuner and you really do not want to load the firmware that early. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx25840/cx25840-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index b3b5b17dc8e..25eb3bec9e5 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -1383,7 +1383,7 @@ static int cx25840_log_status(struct v4l2_subdev *sd) static int cx25840_command(struct i2c_client *client, unsigned cmd, void *arg) { /* ignore this command */ - if (cmd == TUNER_SET_TYPE_ADDR) + if (cmd == TUNER_SET_TYPE_ADDR || cmd == TUNER_SET_CONFIG) return 0; /* Old-style drivers rely on initialization on first use, so -- cgit v1.2.3 From 9c06210b89e604aa75314d3d173a93292b0d2777 Mon Sep 17 00:00:00 2001 From: Robert Krakora Date: Sun, 25 Jan 2009 13:08:07 -0300 Subject: V4L/DVB (10325): em28xx: Fix for fail to submit URB with IRQs and Pre-emption Disabled Trace: (Provided by Douglas) BUG: sleeping function called from invalid context at drivers/usb/core/urb.c:558 in_atomic():0, irqs_disabled():1 Pid: 4918, comm: sox Not tainted 2.6.27.5 #1 [] __might_sleep+0xc6/0xcb [] usb_kill_urb+0x1a/0xd8 [] ? __kmalloc+0x9b/0xfc [] ? __kmalloc+0xb8/0xfc [] ? usb_alloc_urb+0xf/0x31 [] em28xx_isoc_audio_deinit+0x2f/0x6c [em28xx_alsa] [] em28xx_cmd+0x1aa/0x1c5 [em28xx_alsa] [] snd_em28xx_capture_trigger+0x53/0x68 [em28xx_alsa] [] snd_pcm_do_start+0x1c/0x23 [snd_pcm] [] snd_pcm_action_single+0x25/0x4b [snd_pcm] [] snd_pcm_action+0x6a/0x76 [snd_pcm] [] snd_pcm_start+0x14/0x16 [snd_pcm] [] snd_pcm_lib_read1+0x66/0x273 [snd_pcm] [] ? snd_pcm_kernel_ioctl+0x46/0x5f [snd_pcm] [] snd_pcm_lib_read+0xbf/0xcd [snd_pcm] [] ? snd_pcm_lib_read_transfer+0x0/0xaf [snd_pcm] [] snd_pcm_oss_read3+0x99/0xdc [snd_pcm_oss] [] snd_pcm_oss_read2+0xa3/0xbf [snd_pcm_oss] [] ? _cond_resched+0x8/0x32 [] snd_pcm_oss_read+0x106/0x150 [snd_pcm_oss] [] ? snd_pcm_oss_read+0x0/0x150 [snd_pcm_oss] [] vfs_read+0x81/0xdc [] sys_read+0x3b/0x60 [] sysenter_do_call+0x12/0x34 ======================= The culprit in the trace is snd_pcm_action() which invokes a spin lock which disables pre-emption which disables an IRQ which causes the __might_sleep() function to fail the irqs_disabled() test. Since pre-emption is enabled then it is safe to de-allocate the memory if you first unlink each URB. In this instance you are safe since pre-emption is disabled. If pre-emption and irqs are not disabled then call usb_kill_urb(), else call usb_unlink_urb(). Thanks to Douglas for tracking down this bug originally!!! [dougsland@redhat.com: Fixed codyingstyle] Signed-off-by: Robert Krakora Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-audio.c | 9 ++++++--- drivers/media/video/em28xx/em28xx-core.c | 7 +++++-- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index fcc300c9399..5d882a44e3e 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c @@ -62,12 +62,15 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev) dprintk("Stopping isoc\n"); for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { - usb_kill_urb(dev->adev.urb[i]); + if (!irqs_disabled()) + usb_kill_urb(dev->adev.urb[i]); + else + usb_unlink_urb(dev->adev.urb[i]); usb_free_urb(dev->adev.urb[i]); dev->adev.urb[i] = NULL; - kfree(dev->adev.transfer_buffer[i]); - dev->adev.transfer_buffer[i] = NULL; + kfree(dev->adev.transfer_buffer[i]); + dev->adev.transfer_buffer[i] = NULL; } return 0; diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 71ad35192c0..94fb1b639a2 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -860,8 +860,11 @@ void em28xx_uninit_isoc(struct em28xx *dev) 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 (!irqs_disabled()) + usb_kill_urb(urb); + else + usb_unlink_urb(urb); + if (dev->isoc_ctl.transfer_buffer[i]) { usb_buffer_free(dev->udev, urb->transfer_buffer_length, -- cgit v1.2.3 From 2fd9c2eac31d8b3c1b719c7dfbbfed17c5cbccc4 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 24 Jan 2009 07:45:14 -0300 Subject: V4L/DVB (10385): gspca - main: Fix memory leak when USB disconnection while streaming. Resetting the streaming flag on disconnection prevented the URBs to be freed when streaming was active. Also, USBs cannot be killed after disconnection (oops in [usbcore] unlink1). Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 5e36b9a4ae3..2ed24527ecd 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -423,7 +423,8 @@ static void destroy_urbs(struct gspca_dev *gspca_dev) break; gspca_dev->urb[i] = NULL; - usb_kill_urb(urb); + if (!gspca_dev->present) + usb_kill_urb(urb); if (urb->transfer_buffer != NULL) usb_buffer_free(gspca_dev->dev, urb->transfer_buffer_length, @@ -1950,7 +1951,6 @@ void gspca_disconnect(struct usb_interface *intf) struct gspca_dev *gspca_dev = usb_get_intfdata(intf); gspca_dev->present = 0; - gspca_dev->streaming = 0; usb_set_intfdata(intf, NULL); -- cgit v1.2.3 From 2c1a3c979ce66e3073c1b87373c0c01a95f847e6 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 12 Jan 2009 18:10:43 -0300 Subject: V4L/DVB (10229): ivtv: fix memory leak Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-driver.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index e8e5921cdc3..c46c990987f 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -949,8 +949,10 @@ static int __devinit ivtv_probe(struct pci_dev *dev, itv->instance = atomic_inc_return(&ivtv_instance) - 1; retval = v4l2_device_register(&dev->dev, &itv->device); - if (retval) + if (retval) { + kfree(itv); return retval; + } /* "ivtv + PCI ID" is a bit of a mouthful, so use "ivtv + instance" instead. */ snprintf(itv->device.name, sizeof(itv->device.name), -- cgit v1.2.3 From 40c41c8cf1d04445013a14772afb3903a17344a6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 31 Jan 2009 08:09:33 -0300 Subject: V4L/DVB (10403): saa7134-alsa: saa7130 doesn't support digital audio According with saa7130 public datasheet, saa7130 doesn't support digital audio. This is also confirmed by experimental tests. So, it doesn't make sense to let saa7134-alsa register for those chipsets. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-alsa.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c index 26194a0ce92..c750d3dd57d 100644 --- a/drivers/media/video/saa7134/saa7134-alsa.c +++ b/drivers/media/video/saa7134/saa7134-alsa.c @@ -1089,7 +1089,11 @@ static int saa7134_alsa_init(void) list_for_each(list,&saa7134_devlist) { dev = list_entry(list, struct saa7134_dev, devlist); - alsa_device_init(dev); + if (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7130) + printk(KERN_INFO "%s/alsa: %s doesn't support digital audio\n", + dev->name, saa7134_boards[dev->board].name); + else + alsa_device_init(dev); } if (dev == NULL) -- cgit v1.2.3