2005-11-09 13:37:07 +08:00
|
|
|
/*
|
2008-04-18 08:41:10 +08:00
|
|
|
em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB
|
|
|
|
video capture devices
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2005-11-09 13:38:25 +08:00
|
|
|
Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
|
|
|
|
Markus Rechberger <mrechberger@gmail.com>
|
2006-04-03 18:53:40 +08:00
|
|
|
Mauro Carvalho Chehab <mchehab@infradead.org>
|
2005-11-09 13:38:25 +08:00
|
|
|
Sascha Sommer <saschasommer@freenet.de>
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2006-01-24 03:10:54 +08:00
|
|
|
Some parts based on SN9C10x PC Camera Controllers GPL driver made
|
|
|
|
by Luca Risolia <luca.risolia@studio.unibo.it>
|
|
|
|
|
2005-11-09 13:37:07 +08:00
|
|
|
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
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/list.h>
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/kernel.h>
|
2006-01-24 03:11:08 +08:00
|
|
|
#include <linux/bitmap.h>
|
2005-11-09 13:37:07 +08:00
|
|
|
#include <linux/usb.h>
|
|
|
|
#include <linux/i2c.h>
|
2005-11-09 13:38:37 +08:00
|
|
|
#include <linux/version.h>
|
2007-11-01 12:16:09 +08:00
|
|
|
#include <linux/mm.h>
|
2006-01-15 17:52:23 +08:00
|
|
|
#include <linux/mutex.h>
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2005-11-09 13:38:25 +08:00
|
|
|
#include "em28xx.h"
|
2006-01-10 01:25:14 +08:00
|
|
|
#include <media/v4l2-common.h>
|
2008-07-20 19:12:02 +08:00
|
|
|
#include <media/v4l2-ioctl.h>
|
2006-03-19 23:35:57 +08:00
|
|
|
#include <media/msp3400.h>
|
V4L/DVB (7060): em28xx: remove has_tuner
has_tuner flag doesn't make much sense, since tuner_type=TUNER_ABSENT
means the same thing.
Having two ways to say that a tuner is not present is
not nice, since it may lead to bad setups. In fact, with the previous
code, if a device were using has_tuner=0, but the user forces a tuner,
with modprobe option tuner=type, the modprobe option won't work.
Also, tveeprom returns TUNER_ABSENT, when tuner is unknown or absent.
So, with the previous logic, in this case, the driver should set
has_tuner=0, or has_tuner=1 otherwise.
Instead of adding several additional tests and setups, better just to
remove .has_tuner.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-01-24 17:59:20 +08:00
|
|
|
#include <media/tuner.h>
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2005-11-09 13:38:25 +08:00
|
|
|
#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
|
|
|
|
"Markus Rechberger <mrechberger@gmail.com>, " \
|
2006-04-03 18:53:40 +08:00
|
|
|
"Mauro Carvalho Chehab <mchehab@infradead.org>, " \
|
2005-11-09 13:38:25 +08:00
|
|
|
"Sascha Sommer <saschasommer@freenet.de>"
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2005-11-09 13:38:25 +08:00
|
|
|
#define DRIVER_NAME "em28xx"
|
|
|
|
#define DRIVER_DESC "Empia em28xx based USB video device driver"
|
2007-11-12 00:17:17 +08:00
|
|
|
#define EM28XX_VERSION_CODE KERNEL_VERSION(0, 1, 0)
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2005-11-09 13:38:27 +08:00
|
|
|
#define em28xx_videodbg(fmt, arg...) do {\
|
2005-11-09 13:37:43 +08:00
|
|
|
if (video_debug) \
|
|
|
|
printk(KERN_INFO "%s %s :"fmt, \
|
2008-04-09 10:20:00 +08:00
|
|
|
dev->name, __func__ , ##arg); } while (0)
|
2005-11-09 13:37:07 +08:00
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
static unsigned int isoc_debug;
|
2008-04-14 01:41:23 +08:00
|
|
|
module_param(isoc_debug, int, 0644);
|
|
|
|
MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]");
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
|
2008-04-18 08:41:10 +08:00
|
|
|
#define em28xx_isocdbg(fmt, arg...) \
|
|
|
|
do {\
|
|
|
|
if (isoc_debug) { \
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
printk(KERN_INFO "%s %s :"fmt, \
|
2008-04-18 08:41:10 +08:00
|
|
|
dev->name, __func__ , ##arg); \
|
|
|
|
} \
|
|
|
|
} while (0)
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
|
2005-11-09 13:37:07 +08:00
|
|
|
MODULE_AUTHOR(DRIVER_AUTHOR);
|
|
|
|
MODULE_DESCRIPTION(DRIVER_DESC);
|
|
|
|
MODULE_LICENSE("GPL");
|
|
|
|
|
2005-11-09 13:38:27 +08:00
|
|
|
static LIST_HEAD(em28xx_devlist);
|
2008-11-20 21:30:26 +08:00
|
|
|
static DEFINE_MUTEX(em28xx_devlist_mutex);
|
2005-11-09 13:37:52 +08:00
|
|
|
|
2005-11-09 13:38:52 +08:00
|
|
|
static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
|
2006-01-24 03:11:08 +08:00
|
|
|
static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
|
2008-01-06 04:22:01 +08:00
|
|
|
static unsigned int vbi_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
|
|
|
|
static unsigned int radio_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
|
|
|
|
|
2005-11-09 13:37:24 +08:00
|
|
|
module_param_array(card, int, NULL, 0444);
|
2006-01-24 03:11:08 +08:00
|
|
|
module_param_array(video_nr, int, NULL, 0444);
|
|
|
|
module_param_array(vbi_nr, int, NULL, 0444);
|
2008-01-06 04:22:01 +08:00
|
|
|
module_param_array(radio_nr, int, NULL, 0444);
|
|
|
|
MODULE_PARM_DESC(card, "card type");
|
|
|
|
MODULE_PARM_DESC(video_nr, "video device numbers");
|
|
|
|
MODULE_PARM_DESC(vbi_nr, "vbi device numbers");
|
|
|
|
MODULE_PARM_DESC(radio_nr, "radio device numbers");
|
2005-11-09 13:37:24 +08:00
|
|
|
|
2008-04-23 01:41:48 +08:00
|
|
|
static unsigned int video_debug;
|
2008-04-18 08:41:10 +08:00
|
|
|
module_param(video_debug, int, 0644);
|
|
|
|
MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2006-01-24 03:11:08 +08:00
|
|
|
/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */
|
|
|
|
static unsigned long em28xx_devused;
|
|
|
|
|
2005-11-09 13:37:07 +08:00
|
|
|
/* supported controls */
|
2006-01-10 01:25:14 +08:00
|
|
|
/* Common to all boards */
|
2005-11-09 13:38:27 +08:00
|
|
|
static struct v4l2_queryctrl em28xx_qctrl[] = {
|
2006-01-10 01:25:14 +08:00
|
|
|
{
|
|
|
|
.id = V4L2_CID_AUDIO_VOLUME,
|
|
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
|
|
.name = "Volume",
|
|
|
|
.minimum = 0x0,
|
|
|
|
.maximum = 0x1f,
|
|
|
|
.step = 0x1,
|
|
|
|
.default_value = 0x1f,
|
|
|
|
.flags = 0,
|
2008-04-18 08:41:10 +08:00
|
|
|
}, {
|
2006-01-10 01:25:14 +08:00
|
|
|
.id = V4L2_CID_AUDIO_MUTE,
|
|
|
|
.type = V4L2_CTRL_TYPE_BOOLEAN,
|
|
|
|
.name = "Mute",
|
|
|
|
.minimum = 0,
|
|
|
|
.maximum = 1,
|
|
|
|
.step = 1,
|
|
|
|
.default_value = 1,
|
|
|
|
.flags = 0,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2005-11-09 13:38:27 +08:00
|
|
|
static struct usb_driver em28xx_usb_driver;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
/* ------------------------------------------------------------------
|
|
|
|
DMA and thread functions
|
|
|
|
------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Announces that a buffer were filled and request the next
|
|
|
|
*/
|
2008-04-14 01:41:23 +08:00
|
|
|
static inline void buffer_filled(struct em28xx *dev,
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
struct em28xx_dmaqueue *dma_q,
|
|
|
|
struct em28xx_buffer *buf)
|
|
|
|
{
|
|
|
|
/* Advice that buffer was filled */
|
|
|
|
em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
|
|
|
|
buf->vb.state = VIDEOBUF_DONE;
|
|
|
|
buf->vb.field_count++;
|
|
|
|
do_gettimeofday(&buf->vb.ts);
|
|
|
|
|
2008-04-14 02:06:52 +08:00
|
|
|
dev->isoc_ctl.buf = NULL;
|
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
list_del(&buf->vb.queue);
|
|
|
|
wake_up(&buf->vb.done);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Identify the buffer header type and properly handles
|
|
|
|
*/
|
|
|
|
static void em28xx_copy_video(struct em28xx *dev,
|
|
|
|
struct em28xx_dmaqueue *dma_q,
|
|
|
|
struct em28xx_buffer *buf,
|
|
|
|
unsigned char *p,
|
|
|
|
unsigned char *outp, unsigned long len)
|
|
|
|
{
|
|
|
|
void *fieldstart, *startwrite, *startread;
|
2008-04-14 01:41:23 +08:00
|
|
|
int linesdone, currlinedone, offset, lencopy, remain;
|
2008-04-14 02:11:08 +08:00
|
|
|
int bytesperline = dev->width << 1;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
|
|
|
|
if (dma_q->pos + len > buf->vb.size)
|
|
|
|
len = buf->vb.size - dma_q->pos;
|
|
|
|
|
2008-04-14 01:38:47 +08:00
|
|
|
if (p[0] != 0x88 && p[0] != 0x22) {
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
em28xx_isocdbg("frame is not complete\n");
|
|
|
|
len += 4;
|
|
|
|
} else
|
2008-04-14 01:41:23 +08:00
|
|
|
p += 4;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
|
|
|
|
startread = p;
|
|
|
|
remain = len;
|
|
|
|
|
|
|
|
/* Interlaces frame */
|
|
|
|
if (buf->top_field)
|
|
|
|
fieldstart = outp;
|
|
|
|
else
|
2008-04-14 02:11:08 +08:00
|
|
|
fieldstart = outp + bytesperline;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
|
2008-04-14 02:11:08 +08:00
|
|
|
linesdone = dma_q->pos / bytesperline;
|
|
|
|
currlinedone = dma_q->pos % bytesperline;
|
|
|
|
offset = linesdone * bytesperline * 2 + currlinedone;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
startwrite = fieldstart + offset;
|
2008-04-14 02:11:08 +08:00
|
|
|
lencopy = bytesperline - currlinedone;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
lencopy = lencopy > remain ? remain : lencopy;
|
|
|
|
|
2008-04-14 01:41:23 +08:00
|
|
|
if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) {
|
2008-04-14 01:39:29 +08:00
|
|
|
em28xx_isocdbg("Overflow of %zi bytes past buffer end (1)\n",
|
2008-04-14 01:41:23 +08:00
|
|
|
((char *)startwrite + lencopy) -
|
|
|
|
((char *)outp + buf->vb.size));
|
|
|
|
lencopy = remain = (char *)outp + buf->vb.size - (char *)startwrite;
|
2008-04-14 01:38:47 +08:00
|
|
|
}
|
2008-04-14 01:56:02 +08:00
|
|
|
if (lencopy <= 0)
|
|
|
|
return;
|
2008-04-14 01:38:47 +08:00
|
|
|
memcpy(startwrite, startread, lencopy);
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
|
|
|
|
remain -= lencopy;
|
|
|
|
|
|
|
|
while (remain > 0) {
|
2008-04-14 02:11:08 +08:00
|
|
|
startwrite += lencopy + bytesperline;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
startread += lencopy;
|
2008-04-14 02:11:08 +08:00
|
|
|
if (bytesperline > remain)
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
lencopy = remain;
|
|
|
|
else
|
2008-04-14 02:11:08 +08:00
|
|
|
lencopy = bytesperline;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
|
2008-04-14 01:41:23 +08:00
|
|
|
if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) {
|
2008-04-14 01:39:29 +08:00
|
|
|
em28xx_isocdbg("Overflow of %zi bytes past buffer end (2)\n",
|
2008-04-14 01:41:23 +08:00
|
|
|
((char *)startwrite + lencopy) -
|
|
|
|
((char *)outp + buf->vb.size));
|
|
|
|
lencopy = remain = (char *)outp + buf->vb.size -
|
|
|
|
(char *)startwrite;
|
2008-04-14 01:38:47 +08:00
|
|
|
}
|
2008-04-14 01:41:23 +08:00
|
|
|
if (lencopy <= 0)
|
|
|
|
break;
|
2008-04-14 01:38:47 +08:00
|
|
|
|
|
|
|
memcpy(startwrite, startread, lencopy);
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
|
|
|
|
remain -= lencopy;
|
|
|
|
}
|
|
|
|
|
|
|
|
dma_q->pos += len;
|
|
|
|
}
|
|
|
|
|
2008-04-14 01:41:23 +08:00
|
|
|
static inline void print_err_status(struct em28xx *dev,
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
int packet, int status)
|
|
|
|
{
|
|
|
|
char *errmsg = "Unknown";
|
|
|
|
|
2008-04-14 01:41:23 +08:00
|
|
|
switch (status) {
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
case -ENOENT:
|
|
|
|
errmsg = "unlinked synchronuously";
|
|
|
|
break;
|
|
|
|
case -ECONNRESET:
|
|
|
|
errmsg = "unlinked asynchronuously";
|
|
|
|
break;
|
|
|
|
case -ENOSR:
|
|
|
|
errmsg = "Buffer error (overrun)";
|
|
|
|
break;
|
|
|
|
case -EPIPE:
|
|
|
|
errmsg = "Stalled (device not responding)";
|
|
|
|
break;
|
|
|
|
case -EOVERFLOW:
|
|
|
|
errmsg = "Babble (bad cable?)";
|
|
|
|
break;
|
|
|
|
case -EPROTO:
|
|
|
|
errmsg = "Bit-stuff error (bad cable?)";
|
|
|
|
break;
|
|
|
|
case -EILSEQ:
|
|
|
|
errmsg = "CRC/Timeout (could be anything)";
|
|
|
|
break;
|
|
|
|
case -ETIME:
|
|
|
|
errmsg = "Device does not respond";
|
|
|
|
break;
|
|
|
|
}
|
2008-04-14 01:41:23 +08:00
|
|
|
if (packet < 0) {
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
em28xx_isocdbg("URB status %d [%s].\n", status, errmsg);
|
|
|
|
} else {
|
|
|
|
em28xx_isocdbg("URB packet %d, status %d [%s].\n",
|
|
|
|
packet, status, errmsg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* video-buf generic routine to get the next available buffer
|
|
|
|
*/
|
2008-04-14 02:09:36 +08:00
|
|
|
static inline void get_next_buf(struct em28xx_dmaqueue *dma_q,
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
struct em28xx_buffer **buf)
|
|
|
|
{
|
|
|
|
struct em28xx *dev = container_of(dma_q, struct em28xx, vidq);
|
2008-04-14 02:08:55 +08:00
|
|
|
char *outp;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
|
2008-04-14 02:08:55 +08:00
|
|
|
if (list_empty(&dma_q->active)) {
|
|
|
|
em28xx_isocdbg("No active queue to serve\n");
|
|
|
|
dev->isoc_ctl.buf = NULL;
|
|
|
|
*buf = NULL;
|
2008-04-14 02:09:36 +08:00
|
|
|
return;
|
2008-04-14 02:08:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the next buffer */
|
|
|
|
*buf = list_entry(dma_q->active.next, struct em28xx_buffer, vb.queue);
|
|
|
|
|
|
|
|
/* Cleans up buffer - Usefull for testing for frame/URB loss */
|
|
|
|
outp = videobuf_to_vmalloc(&(*buf)->vb);
|
|
|
|
memset(outp, 0, (*buf)->vb.size);
|
2008-04-14 02:06:52 +08:00
|
|
|
|
|
|
|
dev->isoc_ctl.buf = *buf;
|
|
|
|
|
2008-04-14 02:09:36 +08:00
|
|
|
return;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Controls the isoc copy of each urb packet
|
|
|
|
*/
|
2008-04-18 08:40:16 +08:00
|
|
|
static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
{
|
2008-04-14 01:38:47 +08:00
|
|
|
struct em28xx_buffer *buf;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
struct em28xx_dmaqueue *dma_q = urb->context;
|
2008-04-14 02:09:36 +08:00
|
|
|
unsigned char *outp = NULL;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
int i, len = 0, rc = 1;
|
2008-04-14 01:38:47 +08:00
|
|
|
unsigned char *p;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
|
|
|
|
if (!dev)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
|
|
|
|
return 0;
|
|
|
|
|
2008-04-14 01:41:23 +08:00
|
|
|
if (urb->status < 0) {
|
|
|
|
print_err_status(dev, -1, urb->status);
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
if (urb->status == -ENOENT)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-04-14 02:09:36 +08:00
|
|
|
buf = dev->isoc_ctl.buf;
|
|
|
|
if (buf != NULL)
|
|
|
|
outp = videobuf_to_vmalloc(&buf->vb);
|
2008-04-14 01:38:47 +08:00
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
for (i = 0; i < urb->number_of_packets; i++) {
|
|
|
|
int status = urb->iso_frame_desc[i].status;
|
|
|
|
|
2008-04-14 01:41:23 +08:00
|
|
|
if (status < 0) {
|
|
|
|
print_err_status(dev, i, status);
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
if (urb->iso_frame_desc[i].status != -EPROTO)
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2008-04-14 01:41:23 +08:00
|
|
|
len = urb->iso_frame_desc[i].actual_length - 4;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
|
|
|
|
if (urb->iso_frame_desc[i].actual_length <= 0) {
|
2008-04-14 01:38:47 +08:00
|
|
|
/* em28xx_isocdbg("packet %d is empty",i); - spammy */
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (urb->iso_frame_desc[i].actual_length >
|
|
|
|
dev->max_pkt_size) {
|
|
|
|
em28xx_isocdbg("packet bigger than packet size");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
|
|
|
|
|
|
|
|
/* FIXME: incomplete buffer checks where removed to make
|
|
|
|
logic simpler. Impacts of those changes should be evaluated
|
|
|
|
*/
|
2008-04-14 02:09:14 +08:00
|
|
|
if (p[0] == 0x33 && p[1] == 0x95 && p[2] == 0x00) {
|
|
|
|
em28xx_isocdbg("VBI HEADER!!!\n");
|
|
|
|
/* FIXME: Should add vbi copy */
|
|
|
|
continue;
|
|
|
|
}
|
2008-04-14 01:38:47 +08:00
|
|
|
if (p[0] == 0x22 && p[1] == 0x5a) {
|
2008-04-14 01:56:25 +08:00
|
|
|
em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2],
|
|
|
|
len, (p[2] & 1)? "odd" : "even");
|
2008-04-14 01:38:47 +08:00
|
|
|
|
2008-04-14 02:09:36 +08:00
|
|
|
if (!(p[2] & 1)) {
|
|
|
|
if (buf != NULL)
|
|
|
|
buffer_filled(dev, dma_q, buf);
|
|
|
|
get_next_buf(dma_q, &buf);
|
|
|
|
if (buf == NULL)
|
|
|
|
outp = NULL;
|
|
|
|
else
|
|
|
|
outp = videobuf_to_vmalloc(&buf->vb);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (buf != NULL) {
|
|
|
|
if (p[2] & 1)
|
|
|
|
buf->top_field = 0;
|
|
|
|
else
|
|
|
|
buf->top_field = 1;
|
2008-04-14 01:56:02 +08:00
|
|
|
}
|
2008-04-14 02:09:14 +08:00
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
dma_q->pos = 0;
|
|
|
|
}
|
2008-04-14 02:09:36 +08:00
|
|
|
if (buf != NULL)
|
|
|
|
em28xx_copy_video(dev, dma_q, buf, p, outp, len);
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------
|
|
|
|
Videobuf operations
|
|
|
|
------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
static int
|
|
|
|
buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = vq->priv_data;
|
2008-04-18 08:38:53 +08:00
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
struct v4l2_frequency f;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
|
2008-04-14 01:38:47 +08:00
|
|
|
*size = 16 * fh->dev->width * fh->dev->height >> 3;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
if (0 == *count)
|
|
|
|
*count = EM28XX_DEF_BUF;
|
|
|
|
|
2008-04-14 01:41:23 +08:00
|
|
|
if (*count < EM28XX_MIN_BUF)
|
|
|
|
*count = EM28XX_MIN_BUF;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
|
2008-04-18 08:38:53 +08:00
|
|
|
/* Ask tuner to go to analog mode */
|
2008-04-18 08:41:10 +08:00
|
|
|
memset(&f, 0, sizeof(f));
|
2008-04-18 08:38:53 +08:00
|
|
|
f.frequency = dev->ctl_freq;
|
|
|
|
|
|
|
|
em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
|
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-04-14 02:09:36 +08:00
|
|
|
/* This is called *without* dev->slock held; please keep it that way */
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
static void free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf)
|
|
|
|
{
|
2008-04-14 02:09:36 +08:00
|
|
|
struct em28xx_fh *fh = vq->priv_data;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
unsigned long flags = 0;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
if (in_interrupt())
|
|
|
|
BUG();
|
|
|
|
|
2008-04-14 02:09:36 +08:00
|
|
|
/* We used to wait for the buffer to finish here, but this didn't work
|
|
|
|
because, as we were keeping the state as VIDEOBUF_QUEUED,
|
|
|
|
videobuf_queue_cancel marked it as finished for us.
|
|
|
|
(Also, it could wedge forever if the hardware was misconfigured.)
|
|
|
|
|
|
|
|
This should be safe; by the time we get here, the buffer isn't
|
|
|
|
queued anymore. If we ever start marking the buffers as
|
|
|
|
VIDEOBUF_ACTIVE, it won't be, though.
|
|
|
|
*/
|
|
|
|
spin_lock_irqsave(&dev->slock, flags);
|
|
|
|
if (dev->isoc_ctl.buf == buf)
|
|
|
|
dev->isoc_ctl.buf = NULL;
|
|
|
|
spin_unlock_irqrestore(&dev->slock, flags);
|
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
videobuf_vmalloc_free(&buf->vb);
|
|
|
|
buf->vb.state = VIDEOBUF_NEEDS_INIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
|
|
|
|
enum v4l2_field field)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = vq->priv_data;
|
2008-04-14 01:41:23 +08:00
|
|
|
struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc = 0, urb_init = 0;
|
|
|
|
|
|
|
|
/* FIXME: It assumes depth = 16 */
|
|
|
|
/* The only currently supported format is 16 bits/pixel */
|
2008-04-14 01:38:47 +08:00
|
|
|
buf->vb.size = 16 * dev->width * dev->height >> 3;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
|
|
|
|
if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2008-04-14 01:57:01 +08:00
|
|
|
buf->vb.width = dev->width;
|
|
|
|
buf->vb.height = dev->height;
|
|
|
|
buf->vb.field = field;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
|
|
|
|
if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
|
2008-04-14 01:38:47 +08:00
|
|
|
rc = videobuf_iolock(vq, &buf->vb, NULL);
|
|
|
|
if (rc < 0)
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!dev->isoc_ctl.num_bufs)
|
2008-04-14 01:41:23 +08:00
|
|
|
urb_init = 1;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
|
|
|
|
if (urb_init) {
|
2008-04-18 08:40:16 +08:00
|
|
|
rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS,
|
|
|
|
EM28XX_NUM_BUFS, dev->max_pkt_size,
|
2008-04-18 08:48:00 +08:00
|
|
|
em28xx_isoc_copy);
|
2008-04-14 01:41:23 +08:00
|
|
|
if (rc < 0)
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
buf->vb.state = VIDEOBUF_PREPARED;
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
fail:
|
2008-04-14 01:41:23 +08:00
|
|
|
free_buffer(vq, buf);
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
|
|
|
|
{
|
|
|
|
struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
|
|
|
|
struct em28xx_fh *fh = vq->priv_data;
|
2008-04-14 01:41:23 +08:00
|
|
|
struct em28xx *dev = fh->dev;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
struct em28xx_dmaqueue *vidq = &dev->vidq;
|
|
|
|
|
2008-04-14 01:38:47 +08:00
|
|
|
buf->vb.state = VIDEOBUF_QUEUED;
|
|
|
|
list_add_tail(&buf->vb.queue, &vidq->active);
|
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
}
|
|
|
|
|
2008-04-18 08:41:10 +08:00
|
|
|
static void buffer_release(struct videobuf_queue *vq,
|
|
|
|
struct videobuf_buffer *vb)
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
{
|
2008-04-14 01:41:23 +08:00
|
|
|
struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
struct em28xx_fh *fh = vq->priv_data;
|
2008-04-14 01:41:23 +08:00
|
|
|
struct em28xx *dev = (struct em28xx *)fh->dev;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
|
2008-04-14 01:38:47 +08:00
|
|
|
em28xx_isocdbg("em28xx: called buffer_release\n");
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
|
2008-04-14 01:41:23 +08:00
|
|
|
free_buffer(vq, buf);
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static struct videobuf_queue_ops em28xx_video_qops = {
|
|
|
|
.buf_setup = buffer_setup,
|
|
|
|
.buf_prepare = buffer_prepare,
|
|
|
|
.buf_queue = buffer_queue,
|
|
|
|
.buf_release = buffer_release,
|
|
|
|
};
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2008-04-18 08:41:10 +08:00
|
|
|
/********************* v4l2 interface **************************************/
|
2005-11-09 13:37:07 +08:00
|
|
|
|
|
|
|
/*
|
2005-11-09 13:38:27 +08:00
|
|
|
* em28xx_config()
|
2005-11-09 13:37:07 +08:00
|
|
|
* inits registers with sane defaults
|
|
|
|
*/
|
2005-11-09 13:38:27 +08:00
|
|
|
static int em28xx_config(struct em28xx *dev)
|
2005-11-09 13:37:07 +08:00
|
|
|
{
|
2008-09-08 14:27:20 +08:00
|
|
|
int retval;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
|
|
|
/* Sets I2C speed to 100 KHz */
|
2008-11-25 20:39:50 +08:00
|
|
|
if (!dev->board.is_em2800) {
|
V4L/DVB (9758): em28xx: replace some magic by register descriptions where known
Replaces all occurrences of em28xx_write_regs_req() and em28xx_write_reg()
used to setup register names by em28xx_write_reg().
Also, documents the register names that are known.
This patch were generated by this small perl script:
my %reg_map = (
# Register table - the same as defined on parse_em28xx.pl script
);
while (<>) {
if (m/(.*)em28xx_write_regs_req\(dev\,\s*0x00\,\s*(.*)\,\s*\"\\x(..)\",\s*1\)\;(.*)/) {
my $reg = $2;
my $val = $3;
$val =~ tr/A-f/a-f/;
$reg = $reg_map{$reg} if defined($reg_map{$reg});
printf "$1em28xx_write_reg(dev, %s, 0x%s);$4\n", $reg, $val;
} elsif (m/(.*)em28xx_write_regs\(dev\,\s*(.*)\,\s*\"\\x(..)\",\s*1\)\;(.*)/) {
my $reg = $2;
my $val = $3;
$val =~ tr/A-f/a-f/;
$reg = $reg_map{$reg} if defined($reg_map{$reg});
printf "$1em28xx_write_reg(dev, %s, 0x%s);$4\n", $reg, $val;
} else {
print $_;
}
}
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2008-11-27 03:28:42 +08:00
|
|
|
retval = em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40);
|
2008-09-08 14:27:20 +08:00
|
|
|
if (retval < 0) {
|
|
|
|
em28xx_errdev("%s: em28xx_write_regs_req failed! retval [%d]\n",
|
|
|
|
__func__, retval);
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
}
|
2005-11-09 13:37:07 +08:00
|
|
|
|
|
|
|
/* enable vbi capturing */
|
2006-01-24 03:11:08 +08:00
|
|
|
|
V4L/DVB (9758): em28xx: replace some magic by register descriptions where known
Replaces all occurrences of em28xx_write_regs_req() and em28xx_write_reg()
used to setup register names by em28xx_write_reg().
Also, documents the register names that are known.
This patch were generated by this small perl script:
my %reg_map = (
# Register table - the same as defined on parse_em28xx.pl script
);
while (<>) {
if (m/(.*)em28xx_write_regs_req\(dev\,\s*0x00\,\s*(.*)\,\s*\"\\x(..)\",\s*1\)\;(.*)/) {
my $reg = $2;
my $val = $3;
$val =~ tr/A-f/a-f/;
$reg = $reg_map{$reg} if defined($reg_map{$reg});
printf "$1em28xx_write_reg(dev, %s, 0x%s);$4\n", $reg, $val;
} elsif (m/(.*)em28xx_write_regs\(dev\,\s*(.*)\,\s*\"\\x(..)\",\s*1\)\;(.*)/) {
my $reg = $2;
my $val = $3;
$val =~ tr/A-f/a-f/;
$reg = $reg_map{$reg} if defined($reg_map{$reg});
printf "$1em28xx_write_reg(dev, %s, 0x%s);$4\n", $reg, $val;
} else {
print $_;
}
}
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2008-11-27 03:28:42 +08:00
|
|
|
/* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
|
|
|
|
/* em28xx_write_reg(dev, EM28XX_R0F_XCLK, 0x80); clk register */
|
|
|
|
em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51);
|
2006-01-24 03:11:08 +08:00
|
|
|
|
2005-11-09 13:37:07 +08:00
|
|
|
dev->mute = 1; /* maybe not the right place... */
|
|
|
|
dev->volume = 0x1f;
|
2008-01-05 20:53:54 +08:00
|
|
|
|
2005-11-09 13:38:27 +08:00
|
|
|
em28xx_outfmt_set_yuv422(dev);
|
|
|
|
em28xx_colorlevels_set_default(dev);
|
|
|
|
em28xx_compression_disable(dev);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2005-11-09 13:38:27 +08:00
|
|
|
* em28xx_config_i2c()
|
2005-11-09 13:37:07 +08:00
|
|
|
* configure i2c attached devices
|
|
|
|
*/
|
2005-12-01 16:51:35 +08:00
|
|
|
static void em28xx_config_i2c(struct em28xx *dev)
|
2005-11-09 13:37:07 +08:00
|
|
|
{
|
2006-04-03 00:35:00 +08:00
|
|
|
struct v4l2_routing route;
|
2008-12-17 10:09:35 +08:00
|
|
|
int zero = 0;
|
2006-04-03 00:35:00 +08:00
|
|
|
|
|
|
|
route.input = INPUT(dev->ctl_input)->vmux;
|
|
|
|
route.output = 0;
|
2008-12-17 10:09:35 +08:00
|
|
|
em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, &zero);
|
2006-04-03 00:35:00 +08:00
|
|
|
em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
|
2006-03-14 00:31:31 +08:00
|
|
|
em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL);
|
2005-11-09 13:37:07 +08:00
|
|
|
}
|
|
|
|
|
2005-11-09 13:38:43 +08:00
|
|
|
static void video_mux(struct em28xx *dev, int index)
|
|
|
|
{
|
2006-04-03 00:35:00 +08:00
|
|
|
struct v4l2_routing route;
|
2005-11-09 13:38:43 +08:00
|
|
|
|
2006-04-03 00:35:00 +08:00
|
|
|
route.input = INPUT(index)->vmux;
|
|
|
|
route.output = 0;
|
2005-11-09 13:38:43 +08:00
|
|
|
dev->ctl_input = index;
|
|
|
|
dev->ctl_ainput = INPUT(index)->amux;
|
2008-11-20 23:40:51 +08:00
|
|
|
dev->ctl_aoutput = INPUT(index)->aout;
|
2005-11-09 13:38:43 +08:00
|
|
|
|
2008-11-21 00:39:39 +08:00
|
|
|
if (!dev->ctl_aoutput)
|
|
|
|
dev->ctl_aoutput = EM28XX_AOUT_MASTER;
|
|
|
|
|
2006-04-03 00:35:00 +08:00
|
|
|
em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
|
2005-11-09 13:38:43 +08:00
|
|
|
|
2008-11-25 20:39:50 +08:00
|
|
|
if (dev->board.has_msp34xx) {
|
2008-04-18 08:41:10 +08:00
|
|
|
if (dev->i2s_speed) {
|
|
|
|
em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ,
|
|
|
|
&dev->i2s_speed);
|
|
|
|
}
|
2006-03-19 23:35:57 +08:00
|
|
|
route.input = dev->ctl_ainput;
|
2006-04-02 05:03:23 +08:00
|
|
|
route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
|
2006-03-19 23:35:57 +08:00
|
|
|
/* Note: this is msp3400 specific */
|
2008-04-18 08:41:10 +08:00
|
|
|
em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING,
|
|
|
|
&route);
|
2005-11-09 13:38:43 +08:00
|
|
|
}
|
2008-01-05 20:53:54 +08:00
|
|
|
|
2008-02-07 05:34:13 +08:00
|
|
|
em28xx_audio_analog_set(dev);
|
2005-11-09 13:38:43 +08:00
|
|
|
}
|
|
|
|
|
2007-11-11 12:08:26 +08:00
|
|
|
/* Usage lock check functions */
|
|
|
|
static int res_get(struct em28xx_fh *fh)
|
|
|
|
{
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
/* This instance already has stream_on */
|
|
|
|
if (fh->stream_on)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
if (dev->stream_on)
|
2008-04-14 01:55:38 +08:00
|
|
|
return -EINVAL;
|
2007-11-11 12:08:26 +08:00
|
|
|
|
2008-04-14 01:55:38 +08:00
|
|
|
mutex_lock(&dev->lock);
|
|
|
|
dev->stream_on = 1;
|
|
|
|
fh->stream_on = 1;
|
2007-11-11 12:08:26 +08:00
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int res_check(struct em28xx_fh *fh)
|
|
|
|
{
|
|
|
|
return (fh->stream_on);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void res_free(struct em28xx_fh *fh)
|
|
|
|
{
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
|
|
|
|
mutex_lock(&dev->lock);
|
|
|
|
fh->stream_on = 0;
|
|
|
|
dev->stream_on = 0;
|
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
}
|
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
/*
|
|
|
|
* em28xx_get_ctrl()
|
|
|
|
* return the current saturation, brightness or contrast, mute state
|
|
|
|
*/
|
|
|
|
static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
|
|
|
|
{
|
|
|
|
switch (ctrl->id) {
|
|
|
|
case V4L2_CID_AUDIO_MUTE:
|
|
|
|
ctrl->value = dev->mute;
|
|
|
|
return 0;
|
|
|
|
case V4L2_CID_AUDIO_VOLUME:
|
|
|
|
ctrl->value = dev->volume;
|
|
|
|
return 0;
|
|
|
|
default:
|
|
|
|
return -EINVAL;
|
2005-11-09 13:37:07 +08:00
|
|
|
}
|
2007-11-12 00:17:17 +08:00
|
|
|
}
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
/*
|
|
|
|
* em28xx_set_ctrl()
|
|
|
|
* mute or set new saturation, brightness or contrast
|
|
|
|
*/
|
|
|
|
static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl)
|
|
|
|
{
|
|
|
|
switch (ctrl->id) {
|
|
|
|
case V4L2_CID_AUDIO_MUTE:
|
|
|
|
if (ctrl->value != dev->mute) {
|
|
|
|
dev->mute = ctrl->value;
|
|
|
|
return em28xx_audio_analog_set(dev);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
case V4L2_CID_AUDIO_VOLUME:
|
|
|
|
dev->volume = ctrl->value;
|
|
|
|
return em28xx_audio_analog_set(dev);
|
|
|
|
default:
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
static int check_dev(struct em28xx *dev)
|
|
|
|
{
|
|
|
|
if (dev->state & DEV_DISCONNECTED) {
|
|
|
|
em28xx_errdev("v4l2 ioctl: device not present\n");
|
|
|
|
return -ENODEV;
|
2006-01-24 03:11:08 +08:00
|
|
|
}
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
if (dev->state & DEV_MISCONFIGURED) {
|
|
|
|
em28xx_errdev("v4l2 ioctl: device is misconfigured; "
|
|
|
|
"close and open it again\n");
|
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
static void get_scale(struct em28xx *dev,
|
|
|
|
unsigned int width, unsigned int height,
|
|
|
|
unsigned int *hscale, unsigned int *vscale)
|
|
|
|
{
|
|
|
|
unsigned int maxw = norm_maxw(dev);
|
|
|
|
unsigned int maxh = norm_maxh(dev);
|
|
|
|
|
|
|
|
*hscale = (((unsigned long)maxw) << 12) / width - 4096L;
|
|
|
|
if (*hscale >= 0x4000)
|
|
|
|
*hscale = 0x3fff;
|
|
|
|
|
|
|
|
*vscale = (((unsigned long)maxh) << 12) / height - 4096L;
|
|
|
|
if (*vscale >= 0x4000)
|
|
|
|
*vscale = 0x3fff;
|
2005-11-09 13:37:07 +08:00
|
|
|
}
|
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
/* ------------------------------------------------------------------
|
|
|
|
IOCTL vidioc handling
|
|
|
|
------------------------------------------------------------------*/
|
|
|
|
|
2008-05-28 23:16:41 +08:00
|
|
|
static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
|
2007-11-12 00:17:17 +08:00
|
|
|
struct v4l2_format *f)
|
2005-11-09 13:37:07 +08:00
|
|
|
{
|
2007-11-12 00:17:17 +08:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
mutex_lock(&dev->lock);
|
2006-01-24 03:11:08 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
f->fmt.pix.width = dev->width;
|
|
|
|
f->fmt.pix.height = dev->height;
|
|
|
|
f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
|
2008-04-14 02:11:08 +08:00
|
|
|
f->fmt.pix.bytesperline = dev->width * 2;
|
|
|
|
f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height;
|
2007-11-12 00:17:17 +08:00
|
|
|
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
|
2006-01-24 03:11:08 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
/* FIXME: TOP? NONE? BOTTOM? ALTENATE? */
|
|
|
|
f->fmt.pix.field = dev->interlaced ?
|
|
|
|
V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
|
2006-01-24 03:11:08 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
return 0;
|
2005-11-09 13:37:07 +08:00
|
|
|
}
|
|
|
|
|
2008-05-28 23:16:41 +08:00
|
|
|
static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
|
2007-11-12 00:17:17 +08:00
|
|
|
struct v4l2_format *f)
|
2005-11-09 13:37:07 +08:00
|
|
|
{
|
2007-11-12 00:17:17 +08:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int width = f->fmt.pix.width;
|
|
|
|
int height = f->fmt.pix.height;
|
|
|
|
unsigned int maxw = norm_maxw(dev);
|
|
|
|
unsigned int maxh = norm_maxh(dev);
|
|
|
|
unsigned int hscale, vscale;
|
|
|
|
|
|
|
|
/* width must even because of the YUYV format
|
|
|
|
height must be even because of interlacing */
|
|
|
|
height &= 0xfffe;
|
|
|
|
width &= 0xfffe;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
if (height < 32)
|
|
|
|
height = 32;
|
|
|
|
if (height > maxh)
|
|
|
|
height = maxh;
|
|
|
|
if (width < 48)
|
|
|
|
width = 48;
|
|
|
|
if (width > maxw)
|
|
|
|
width = maxw;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
mutex_lock(&dev->lock);
|
2007-11-11 12:08:26 +08:00
|
|
|
|
2008-11-25 20:39:50 +08:00
|
|
|
if (dev->board.is_em2800) {
|
2007-11-12 00:17:17 +08:00
|
|
|
/* the em2800 can only scale down to 50% */
|
|
|
|
if (height % (maxh / 2))
|
|
|
|
height = maxh;
|
|
|
|
if (width % (maxw / 2))
|
|
|
|
width = maxw;
|
|
|
|
/* according to empiatech support */
|
|
|
|
/* the MaxPacketSize is to small to support */
|
|
|
|
/* framesizes larger than 640x480 @ 30 fps */
|
|
|
|
/* or 640x576 @ 25 fps. As this would cut */
|
|
|
|
/* of a part of the image we prefer */
|
|
|
|
/* 360x576 or 360x480 for now */
|
|
|
|
if (width == maxw && height == maxh)
|
|
|
|
width /= 2;
|
|
|
|
}
|
2007-11-11 12:08:26 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
get_scale(dev, width, height, &hscale, &vscale);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
width = (((unsigned long)maxw) << 12) / (hscale + 4096L);
|
|
|
|
height = (((unsigned long)maxh) << 12) / (vscale + 4096L);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
f->fmt.pix.width = width;
|
|
|
|
f->fmt.pix.height = height;
|
|
|
|
f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
|
|
|
|
f->fmt.pix.bytesperline = width * 2;
|
|
|
|
f->fmt.pix.sizeimage = width * 2 * height;
|
|
|
|
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
|
|
|
|
f->fmt.pix.field = V4L2_FIELD_INTERLACED;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2006-02-07 16:49:14 +08:00
|
|
|
mutex_unlock(&dev->lock);
|
2005-11-09 13:37:07 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-05-28 23:16:41 +08:00
|
|
|
static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
|
2007-11-12 00:17:17 +08:00
|
|
|
struct v4l2_format *f)
|
2005-11-09 13:37:07 +08:00
|
|
|
{
|
2007-11-12 00:17:17 +08:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
int rc;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
2007-11-11 12:08:26 +08:00
|
|
|
|
2008-05-28 23:16:41 +08:00
|
|
|
vidioc_try_fmt_vid_cap(file, priv, f);
|
2007-11-11 12:08:26 +08:00
|
|
|
|
2007-11-04 08:22:38 +08:00
|
|
|
mutex_lock(&dev->lock);
|
|
|
|
|
2008-04-14 01:57:01 +08:00
|
|
|
if (videobuf_queue_is_busy(&fh->vb_vidq)) {
|
|
|
|
em28xx_errdev("%s queue busy\n", __func__);
|
|
|
|
rc = -EBUSY;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2008-04-14 02:02:24 +08:00
|
|
|
if (dev->stream_on && !fh->stream_on) {
|
|
|
|
em28xx_errdev("%s device in use by another fh\n", __func__);
|
|
|
|
rc = -EBUSY;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
/* set new image size */
|
|
|
|
dev->width = f->fmt.pix.width;
|
|
|
|
dev->height = f->fmt.pix.height;
|
|
|
|
get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
em28xx_set_alternate(dev);
|
|
|
|
em28xx_resolution_set(dev);
|
|
|
|
|
2008-04-14 01:57:01 +08:00
|
|
|
rc = 0;
|
|
|
|
|
|
|
|
out:
|
2007-11-12 00:17:17 +08:00
|
|
|
mutex_unlock(&dev->lock);
|
2008-04-14 01:57:01 +08:00
|
|
|
return rc;
|
2007-11-12 00:17:17 +08:00
|
|
|
}
|
|
|
|
|
2008-04-18 08:41:10 +08:00
|
|
|
static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
|
2007-11-12 00:17:17 +08:00
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
struct v4l2_format f;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
mutex_lock(&dev->lock);
|
2007-11-12 01:15:34 +08:00
|
|
|
dev->norm = *norm;
|
2007-11-12 00:17:17 +08:00
|
|
|
mutex_unlock(&dev->lock);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
/* Adjusts width/height, if needed */
|
|
|
|
f.fmt.pix.width = dev->width;
|
|
|
|
f.fmt.pix.height = dev->height;
|
2008-05-28 23:16:41 +08:00
|
|
|
vidioc_try_fmt_vid_cap(file, priv, &f);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
mutex_lock(&dev->lock);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
/* set new image size */
|
|
|
|
dev->width = f.fmt.pix.width;
|
|
|
|
dev->height = f.fmt.pix.height;
|
|
|
|
get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
em28xx_resolution_set(dev);
|
2007-11-12 01:15:34 +08:00
|
|
|
em28xx_i2c_call_clients(dev, VIDIOC_S_STD, &dev->norm);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
return 0;
|
|
|
|
}
|
2007-11-11 12:13:49 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
static const char *iname[] = {
|
|
|
|
[EM28XX_VMUX_COMPOSITE1] = "Composite1",
|
|
|
|
[EM28XX_VMUX_COMPOSITE2] = "Composite2",
|
|
|
|
[EM28XX_VMUX_COMPOSITE3] = "Composite3",
|
|
|
|
[EM28XX_VMUX_COMPOSITE4] = "Composite4",
|
|
|
|
[EM28XX_VMUX_SVIDEO] = "S-Video",
|
|
|
|
[EM28XX_VMUX_TELEVISION] = "Television",
|
|
|
|
[EM28XX_VMUX_CABLE] = "Cable TV",
|
|
|
|
[EM28XX_VMUX_DVB] = "DVB",
|
|
|
|
[EM28XX_VMUX_DEBUG] = "for debug only",
|
|
|
|
};
|
2007-11-11 12:13:49 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
static int vidioc_enum_input(struct file *file, void *priv,
|
|
|
|
struct v4l2_input *i)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
unsigned int n;
|
2007-11-11 12:13:49 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
n = i->index;
|
|
|
|
if (n >= MAX_EM28XX_INPUT)
|
|
|
|
return -EINVAL;
|
|
|
|
if (0 == INPUT(n)->type)
|
|
|
|
return -EINVAL;
|
2007-11-11 12:13:49 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
i->index = n;
|
|
|
|
i->type = V4L2_INPUT_TYPE_CAMERA;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
strcpy(i->name, iname[INPUT(n)->type]);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) ||
|
|
|
|
(EM28XX_VMUX_CABLE == INPUT(n)->type))
|
|
|
|
i->type = V4L2_INPUT_TYPE_TUNER;
|
|
|
|
|
2007-11-12 01:15:34 +08:00
|
|
|
i->std = dev->vdev->tvnorms;
|
2007-11-12 00:17:17 +08:00
|
|
|
|
|
|
|
return 0;
|
2005-11-09 13:37:07 +08:00
|
|
|
}
|
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
|
2005-11-09 13:37:07 +08:00
|
|
|
{
|
2007-11-12 00:17:17 +08:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
*i = dev->ctl_input;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
if (i >= MAX_EM28XX_INPUT)
|
|
|
|
return -EINVAL;
|
|
|
|
if (0 == INPUT(i)->type)
|
|
|
|
return -EINVAL;
|
2007-11-11 12:08:26 +08:00
|
|
|
|
2007-11-04 08:22:38 +08:00
|
|
|
mutex_lock(&dev->lock);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
video_mux(dev, i);
|
|
|
|
|
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
|
2008-11-20 23:40:51 +08:00
|
|
|
switch (a->index) {
|
|
|
|
case EM28XX_AMUX_VIDEO:
|
2007-11-12 00:17:17 +08:00
|
|
|
strcpy(a->name, "Television");
|
2008-11-20 23:40:51 +08:00
|
|
|
break;
|
|
|
|
case EM28XX_AMUX_LINE_IN:
|
2007-11-12 00:17:17 +08:00
|
|
|
strcpy(a->name, "Line In");
|
2008-11-20 23:40:51 +08:00
|
|
|
break;
|
|
|
|
case EM28XX_AMUX_VIDEO2:
|
|
|
|
strcpy(a->name, "Television alt");
|
|
|
|
break;
|
|
|
|
case EM28XX_AMUX_PHONE:
|
|
|
|
strcpy(a->name, "Phone");
|
|
|
|
break;
|
|
|
|
case EM28XX_AMUX_MIC:
|
|
|
|
strcpy(a->name, "Mic");
|
|
|
|
break;
|
|
|
|
case EM28XX_AMUX_CD:
|
|
|
|
strcpy(a->name, "CD");
|
|
|
|
break;
|
|
|
|
case EM28XX_AMUX_AUX:
|
|
|
|
strcpy(a->name, "Aux");
|
|
|
|
break;
|
|
|
|
case EM28XX_AMUX_PCM_OUT:
|
|
|
|
strcpy(a->name, "PCM");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2008-04-18 08:41:10 +08:00
|
|
|
|
2008-11-20 23:40:51 +08:00
|
|
|
a->index = dev->ctl_ainput;
|
2007-11-12 00:17:17 +08:00
|
|
|
a->capability = V4L2_AUDCAP_STEREO;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
|
2008-11-20 23:40:51 +08:00
|
|
|
dev->ctl_ainput = INPUT(a->index)->amux;
|
|
|
|
dev->ctl_aoutput = INPUT(a->index)->aout;
|
2008-11-21 00:39:39 +08:00
|
|
|
|
|
|
|
if (!dev->ctl_aoutput)
|
|
|
|
dev->ctl_aoutput = EM28XX_AOUT_MASTER;
|
2007-11-12 00:17:17 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vidioc_queryctrl(struct file *file, void *priv,
|
|
|
|
struct v4l2_queryctrl *qc)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int id = qc->id;
|
|
|
|
int i;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
memset(qc, 0, sizeof(*qc));
|
|
|
|
|
|
|
|
qc->id = id;
|
|
|
|
|
2008-11-25 20:39:50 +08:00
|
|
|
if (!dev->board.has_msp34xx) {
|
2007-11-12 00:17:17 +08:00
|
|
|
for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
|
|
|
|
if (qc->id && qc->id == em28xx_qctrl[i].id) {
|
|
|
|
memcpy(qc, &(em28xx_qctrl[i]), sizeof(*qc));
|
|
|
|
return 0;
|
2005-11-09 13:37:07 +08:00
|
|
|
}
|
|
|
|
}
|
2007-11-12 00:17:17 +08:00
|
|
|
}
|
|
|
|
mutex_lock(&dev->lock);
|
|
|
|
em28xx_i2c_call_clients(dev, VIDIOC_QUERYCTRL, qc);
|
|
|
|
mutex_unlock(&dev->lock);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
if (qc->type)
|
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
static int vidioc_g_ctrl(struct file *file, void *priv,
|
|
|
|
struct v4l2_control *ctrl)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
mutex_lock(&dev->lock);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2008-11-25 20:39:50 +08:00
|
|
|
if (!dev->board.has_msp34xx)
|
2007-11-12 00:17:17 +08:00
|
|
|
rc = em28xx_get_ctrl(dev, ctrl);
|
|
|
|
else
|
|
|
|
rc = -EINVAL;
|
|
|
|
|
|
|
|
if (rc == -EINVAL) {
|
|
|
|
em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl);
|
|
|
|
rc = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vidioc_s_ctrl(struct file *file, void *priv,
|
|
|
|
struct v4l2_control *ctrl)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
u8 i;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
mutex_lock(&dev->lock);
|
|
|
|
|
2008-11-25 20:39:50 +08:00
|
|
|
if (dev->board.has_msp34xx)
|
2007-11-12 00:17:17 +08:00
|
|
|
em28xx_i2c_call_clients(dev, VIDIOC_S_CTRL, ctrl);
|
|
|
|
else {
|
|
|
|
rc = 1;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
|
|
|
|
if (ctrl->id == em28xx_qctrl[i].id) {
|
|
|
|
if (ctrl->value < em28xx_qctrl[i].minimum ||
|
|
|
|
ctrl->value > em28xx_qctrl[i].maximum) {
|
|
|
|
rc = -ERANGE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = em28xx_set_ctrl(dev, ctrl);
|
|
|
|
break;
|
|
|
|
}
|
2005-11-09 13:37:07 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
/* Control not found - try to send it to the attached devices */
|
|
|
|
if (rc == 1) {
|
|
|
|
em28xx_i2c_call_clients(dev, VIDIOC_S_CTRL, ctrl);
|
|
|
|
rc = 0;
|
|
|
|
}
|
|
|
|
|
2007-11-04 08:22:38 +08:00
|
|
|
mutex_unlock(&dev->lock);
|
2007-11-12 00:17:17 +08:00
|
|
|
return rc;
|
2005-11-09 13:37:07 +08:00
|
|
|
}
|
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
static int vidioc_g_tuner(struct file *file, void *priv,
|
|
|
|
struct v4l2_tuner *t)
|
2005-11-09 13:37:07 +08:00
|
|
|
{
|
2007-11-12 00:17:17 +08:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
if (0 != t->index)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
strcpy(t->name, "Tuner");
|
|
|
|
|
|
|
|
mutex_lock(&dev->lock);
|
|
|
|
|
|
|
|
em28xx_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
|
|
|
|
|
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
return 0;
|
2005-11-09 13:37:07 +08:00
|
|
|
}
|
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
static int vidioc_s_tuner(struct file *file, void *priv,
|
|
|
|
struct v4l2_tuner *t)
|
2005-11-09 13:37:07 +08:00
|
|
|
{
|
2007-11-12 00:17:17 +08:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc;
|
2007-11-10 21:26:20 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
if (0 != t->index)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
mutex_lock(&dev->lock);
|
|
|
|
|
|
|
|
em28xx_i2c_call_clients(dev, VIDIOC_S_TUNER, t);
|
|
|
|
|
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
return 0;
|
2005-11-09 13:37:07 +08:00
|
|
|
}
|
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
static int vidioc_g_frequency(struct file *file, void *priv,
|
|
|
|
struct v4l2_frequency *f)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2008-01-06 04:22:01 +08:00
|
|
|
f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
|
2007-11-12 00:17:17 +08:00
|
|
|
f->frequency = dev->ctl_freq;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vidioc_s_frequency(struct file *file, void *priv,
|
|
|
|
struct v4l2_frequency *f)
|
2005-11-09 13:37:07 +08:00
|
|
|
{
|
2007-11-12 00:17:17 +08:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc;
|
2005-11-09 13:37:52 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
if (0 != f->tuner)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2008-01-06 04:22:01 +08:00
|
|
|
if (unlikely(0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV))
|
|
|
|
return -EINVAL;
|
|
|
|
if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO))
|
2007-11-12 00:17:17 +08:00
|
|
|
return -EINVAL;
|
2007-11-11 12:08:26 +08:00
|
|
|
|
|
|
|
mutex_lock(&dev->lock);
|
2007-11-11 09:21:01 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
dev->ctl_freq = f->frequency;
|
|
|
|
em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
return 0;
|
|
|
|
}
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2008-02-06 20:00:41 +08:00
|
|
|
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
|
|
|
static int em28xx_reg_len(int reg)
|
|
|
|
{
|
|
|
|
switch (reg) {
|
2008-04-18 08:44:58 +08:00
|
|
|
case EM28XX_R40_AC97LSB:
|
|
|
|
case EM28XX_R30_HSCALELOW:
|
|
|
|
case EM28XX_R32_VSCALELOW:
|
2008-02-06 20:00:41 +08:00
|
|
|
return 2;
|
|
|
|
default:
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vidioc_g_register(struct file *file, void *priv,
|
|
|
|
struct v4l2_register *reg)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
if (em28xx_reg_len(reg->reg) == 1) {
|
|
|
|
ret = em28xx_read_reg(dev, reg->reg);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
reg->val = ret;
|
|
|
|
} else {
|
2008-05-21 11:32:51 +08:00
|
|
|
__le64 val = 0;
|
2008-02-06 20:00:41 +08:00
|
|
|
ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS,
|
|
|
|
reg->reg, (char *)&val, 2);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
|
2008-05-21 11:32:51 +08:00
|
|
|
reg->val = le64_to_cpu(val);
|
2008-02-06 20:00:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vidioc_s_register(struct file *file, void *priv,
|
|
|
|
struct v4l2_register *reg)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
2008-05-21 11:32:51 +08:00
|
|
|
__le64 buf;
|
2008-02-06 20:00:41 +08:00
|
|
|
|
2008-05-21 11:32:51 +08:00
|
|
|
buf = cpu_to_le64(reg->val);
|
2008-02-06 20:00:41 +08:00
|
|
|
|
|
|
|
return em28xx_write_regs(dev, reg->reg, (char *)&buf,
|
|
|
|
em28xx_reg_len(reg->reg));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
static int vidioc_cropcap(struct file *file, void *priv,
|
|
|
|
struct v4l2_cropcap *cc)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
|
|
|
|
if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
2005-11-09 13:37:07 +08:00
|
|
|
return -EINVAL;
|
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
cc->bounds.left = 0;
|
|
|
|
cc->bounds.top = 0;
|
|
|
|
cc->bounds.width = dev->width;
|
|
|
|
cc->bounds.height = dev->height;
|
|
|
|
cc->defrect = cc->bounds;
|
|
|
|
cc->pixelaspect.numerator = 54; /* 4:3 FIXME: remove magic numbers */
|
|
|
|
cc->pixelaspect.denominator = 59;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vidioc_streamon(struct file *file, void *priv,
|
|
|
|
enum v4l2_buf_type type)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
if (unlikely(res_get(fh) < 0))
|
2007-11-12 00:17:17 +08:00
|
|
|
return -EBUSY;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
return (videobuf_streamon(&fh->vb_vidq));
|
2007-11-12 00:17:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int vidioc_streamoff(struct file *file, void *priv,
|
|
|
|
enum v4l2_buf_type type)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
|
|
|
return -EINVAL;
|
|
|
|
if (type != fh->type)
|
2007-11-12 00:17:17 +08:00
|
|
|
return -EINVAL;
|
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
videobuf_streamoff(&fh->vb_vidq);
|
|
|
|
res_free(fh);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
static int vidioc_querycap(struct file *file, void *priv,
|
|
|
|
struct v4l2_capability *cap)
|
2005-11-09 13:37:07 +08:00
|
|
|
{
|
2007-11-12 00:17:17 +08:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
|
|
|
|
strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
|
|
|
|
strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
|
V4L/DVB (9521): V4L: struct device - replace bus_id with dev_name(), dev_set_name()
This patch is part of a larger patch series which will remove
the "char bus_id[20]" name string from struct device. The device
name is managed in the kobject anyway, and without any size
limitation, and just needlessly copied into "struct device".
To set and read the device name dev_name(dev) and dev_set_name(dev)
must be used. If your code uses static kobjects, which it shouldn't
do, "const char *init_name" can be used to statically provide the
name the registered device should have. At registration time, the
init_name field is cleared, to enforce the use of dev_name(dev) to
access the device name at a later time.
We need to get rid of all occurrences of bus_id in the entire tree
to be able to enable the new interface. Please apply this patch,
and possibly convert any remaining remaining occurrences of bus_id.
We want to submit a patch to -next, which will remove bus_id from
"struct device", to find the remaining pieces to convert, and finally
switch over to the new api, which will remove the 20 bytes array
and does no longer have a size limitation.
Thanks,
Kay
Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2008-10-30 11:51:46 +08:00
|
|
|
strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
|
2007-11-12 00:17:17 +08:00
|
|
|
|
|
|
|
cap->version = EM28XX_VERSION_CODE;
|
|
|
|
|
|
|
|
cap->capabilities =
|
|
|
|
V4L2_CAP_SLICED_VBI_CAPTURE |
|
|
|
|
V4L2_CAP_VIDEO_CAPTURE |
|
|
|
|
V4L2_CAP_AUDIO |
|
|
|
|
V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
|
|
|
|
|
V4L/DVB (7060): em28xx: remove has_tuner
has_tuner flag doesn't make much sense, since tuner_type=TUNER_ABSENT
means the same thing.
Having two ways to say that a tuner is not present is
not nice, since it may lead to bad setups. In fact, with the previous
code, if a device were using has_tuner=0, but the user forces a tuner,
with modprobe option tuner=type, the modprobe option won't work.
Also, tveeprom returns TUNER_ABSENT, when tuner is unknown or absent.
So, with the previous logic, in this case, the driver should set
has_tuner=0, or has_tuner=1 otherwise.
Instead of adding several additional tests and setups, better just to
remove .has_tuner.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-01-24 17:59:20 +08:00
|
|
|
if (dev->tuner_type != TUNER_ABSENT)
|
2007-11-12 00:17:17 +08:00
|
|
|
cap->capabilities |= V4L2_CAP_TUNER;
|
|
|
|
|
|
|
|
return 0;
|
2006-01-10 01:25:14 +08:00
|
|
|
}
|
|
|
|
|
2008-05-28 23:16:41 +08:00
|
|
|
static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
|
2007-11-12 00:17:17 +08:00
|
|
|
struct v4l2_fmtdesc *fmtd)
|
2005-11-09 13:37:07 +08:00
|
|
|
{
|
2007-11-12 00:17:17 +08:00
|
|
|
if (fmtd->index != 0)
|
2006-01-10 01:25:14 +08:00
|
|
|
return -EINVAL;
|
2007-11-12 00:17:17 +08:00
|
|
|
|
|
|
|
fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
|
|
|
strcpy(fmtd->description, "Packed YUY2");
|
|
|
|
fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
|
|
|
|
memset(fmtd->reserved, 0, sizeof(fmtd->reserved));
|
|
|
|
|
|
|
|
return 0;
|
2006-01-10 01:25:14 +08:00
|
|
|
}
|
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
/* Sliced VBI ioctls */
|
2008-05-28 23:16:41 +08:00
|
|
|
static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv,
|
2007-11-12 00:17:17 +08:00
|
|
|
struct v4l2_format *f)
|
2005-11-09 13:37:07 +08:00
|
|
|
{
|
2007-11-12 00:17:17 +08:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
mutex_lock(&dev->lock);
|
|
|
|
|
|
|
|
f->fmt.sliced.service_set = 0;
|
|
|
|
|
|
|
|
em28xx_i2c_call_clients(dev, VIDIOC_G_FMT, f);
|
|
|
|
|
|
|
|
if (f->fmt.sliced.service_set == 0)
|
|
|
|
rc = -EINVAL;
|
|
|
|
|
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2008-05-28 23:16:41 +08:00
|
|
|
static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
|
2007-11-12 00:17:17 +08:00
|
|
|
struct v4l2_format *f)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
mutex_lock(&dev->lock);
|
|
|
|
em28xx_i2c_call_clients(dev, VIDIOC_G_FMT, f);
|
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
|
|
|
|
if (f->fmt.sliced.service_set == 0)
|
|
|
|
return -EINVAL;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
|
|
|
|
static int vidioc_reqbufs(struct file *file, void *priv,
|
|
|
|
struct v4l2_requestbuffers *rb)
|
2005-11-09 13:37:07 +08:00
|
|
|
{
|
2007-11-12 00:17:17 +08:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
return (videobuf_reqbufs(&fh->vb_vidq, rb));
|
2005-11-09 13:37:07 +08:00
|
|
|
}
|
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
static int vidioc_querybuf(struct file *file, void *priv,
|
|
|
|
struct v4l2_buffer *b)
|
2006-01-24 03:11:08 +08:00
|
|
|
{
|
2007-11-12 00:17:17 +08:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc;
|
2006-01-24 03:11:08 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
2006-01-24 03:11:08 +08:00
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
return (videobuf_querybuf(&fh->vb_vidq, b));
|
2007-11-12 00:17:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
return (videobuf_qbuf(&fh->vb_vidq, b));
|
2006-01-24 03:11:08 +08:00
|
|
|
}
|
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
|
2006-01-24 03:11:08 +08:00
|
|
|
{
|
2007-11-12 00:17:17 +08:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
2006-01-24 03:11:08 +08:00
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
return (videobuf_dqbuf(&fh->vb_vidq, b,
|
|
|
|
file->f_flags & O_NONBLOCK));
|
|
|
|
}
|
2006-01-24 03:11:08 +08:00
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
2008-04-14 01:41:23 +08:00
|
|
|
static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
{
|
2008-04-14 01:41:23 +08:00
|
|
|
struct em28xx_fh *fh = priv;
|
2006-01-24 03:11:08 +08:00
|
|
|
|
2008-04-14 01:41:23 +08:00
|
|
|
return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
|
2007-11-12 00:17:17 +08:00
|
|
|
}
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
#endif
|
|
|
|
|
2006-01-24 03:11:08 +08:00
|
|
|
|
2008-01-06 04:22:01 +08:00
|
|
|
/* ----------------------------------------------------------- */
|
|
|
|
/* RADIO ESPECIFIC IOCTLS */
|
|
|
|
/* ----------------------------------------------------------- */
|
|
|
|
|
|
|
|
static int radio_querycap(struct file *file, void *priv,
|
|
|
|
struct v4l2_capability *cap)
|
|
|
|
{
|
|
|
|
struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
|
|
|
|
|
|
|
|
strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
|
|
|
|
strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
|
V4L/DVB (9521): V4L: struct device - replace bus_id with dev_name(), dev_set_name()
This patch is part of a larger patch series which will remove
the "char bus_id[20]" name string from struct device. The device
name is managed in the kobject anyway, and without any size
limitation, and just needlessly copied into "struct device".
To set and read the device name dev_name(dev) and dev_set_name(dev)
must be used. If your code uses static kobjects, which it shouldn't
do, "const char *init_name" can be used to statically provide the
name the registered device should have. At registration time, the
init_name field is cleared, to enforce the use of dev_name(dev) to
access the device name at a later time.
We need to get rid of all occurrences of bus_id in the entire tree
to be able to enable the new interface. Please apply this patch,
and possibly convert any remaining remaining occurrences of bus_id.
We want to submit a patch to -next, which will remove bus_id from
"struct device", to find the remaining pieces to convert, and finally
switch over to the new api, which will remove the 20 bytes array
and does no longer have a size limitation.
Thanks,
Kay
Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2008-10-30 11:51:46 +08:00
|
|
|
strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
|
2008-01-06 04:22:01 +08:00
|
|
|
|
|
|
|
cap->version = EM28XX_VERSION_CODE;
|
|
|
|
cap->capabilities = V4L2_CAP_TUNER;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int radio_g_tuner(struct file *file, void *priv,
|
|
|
|
struct v4l2_tuner *t)
|
|
|
|
{
|
|
|
|
struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
|
|
|
|
|
|
|
|
if (unlikely(t->index > 0))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
strcpy(t->name, "Radio");
|
|
|
|
t->type = V4L2_TUNER_RADIO;
|
|
|
|
|
|
|
|
em28xx_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int radio_enum_input(struct file *file, void *priv,
|
|
|
|
struct v4l2_input *i)
|
|
|
|
{
|
|
|
|
if (i->index != 0)
|
|
|
|
return -EINVAL;
|
|
|
|
strcpy(i->name, "Radio");
|
|
|
|
i->type = V4L2_INPUT_TYPE_TUNER;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int radio_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
|
|
|
|
{
|
|
|
|
if (unlikely(a->index))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
strcpy(a->name, "Radio");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int radio_s_tuner(struct file *file, void *priv,
|
|
|
|
struct v4l2_tuner *t)
|
|
|
|
{
|
|
|
|
struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
|
|
|
|
|
|
|
|
if (0 != t->index)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
em28xx_i2c_call_clients(dev, VIDIOC_S_TUNER, t);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int radio_s_audio(struct file *file, void *fh,
|
|
|
|
struct v4l2_audio *a)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int radio_s_input(struct file *file, void *fh, unsigned int i)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int radio_queryctrl(struct file *file, void *priv,
|
|
|
|
struct v4l2_queryctrl *qc)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (qc->id < V4L2_CID_BASE ||
|
|
|
|
qc->id >= V4L2_CID_LASTP1)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
|
|
|
|
if (qc->id && qc->id == em28xx_qctrl[i].id) {
|
|
|
|
memcpy(qc, &(em28xx_qctrl[i]), sizeof(*qc));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
/*
|
|
|
|
* em28xx_v4l2_open()
|
|
|
|
* inits the device and starts isoc transfer
|
|
|
|
*/
|
|
|
|
static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
|
|
|
|
{
|
|
|
|
int minor = iminor(inode);
|
2008-01-06 04:22:01 +08:00
|
|
|
int errCode = 0, radio = 0;
|
2008-04-18 08:41:10 +08:00
|
|
|
struct em28xx *h, *dev = NULL;
|
2007-11-12 00:17:17 +08:00
|
|
|
struct em28xx_fh *fh;
|
2008-04-14 01:38:47 +08:00
|
|
|
enum v4l2_buf_type fh_type = 0;
|
2006-01-24 03:11:08 +08:00
|
|
|
|
2008-11-20 21:30:26 +08:00
|
|
|
mutex_lock(&em28xx_devlist_mutex);
|
2007-11-12 00:17:17 +08:00
|
|
|
list_for_each_entry(h, &em28xx_devlist, devlist) {
|
|
|
|
if (h->vdev->minor == minor) {
|
|
|
|
dev = h;
|
2008-04-14 01:38:47 +08:00
|
|
|
fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
2007-11-12 00:17:17 +08:00
|
|
|
}
|
|
|
|
if (h->vbi_dev->minor == minor) {
|
|
|
|
dev = h;
|
2008-04-14 01:38:47 +08:00
|
|
|
fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
|
2007-11-12 00:17:17 +08:00
|
|
|
}
|
2008-01-06 04:22:01 +08:00
|
|
|
if (h->radio_dev &&
|
|
|
|
h->radio_dev->minor == minor) {
|
|
|
|
radio = 1;
|
|
|
|
dev = h;
|
|
|
|
}
|
2006-01-24 03:11:08 +08:00
|
|
|
}
|
2008-11-20 21:30:26 +08:00
|
|
|
mutex_unlock(&em28xx_devlist_mutex);
|
|
|
|
if (NULL == dev)
|
2007-11-12 00:17:17 +08:00
|
|
|
return -ENODEV;
|
2008-11-20 21:30:26 +08:00
|
|
|
|
|
|
|
mutex_lock(&dev->lock);
|
2006-01-24 03:11:08 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
em28xx_videodbg("open minor=%d type=%s users=%d\n",
|
2008-04-14 01:38:47 +08:00
|
|
|
minor, v4l2_type_names[fh_type], dev->users);
|
2006-01-24 03:11:08 +08:00
|
|
|
|
2006-01-24 03:11:09 +08:00
|
|
|
|
2008-04-18 08:48:00 +08:00
|
|
|
fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
|
2007-11-12 00:17:17 +08:00
|
|
|
if (!fh) {
|
|
|
|
em28xx_errdev("em28xx-video.c: Out of memory?!\n");
|
2008-11-20 21:30:26 +08:00
|
|
|
mutex_unlock(&dev->lock);
|
2007-11-12 00:17:17 +08:00
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
fh->dev = dev;
|
2008-01-06 04:22:01 +08:00
|
|
|
fh->radio = radio;
|
2008-04-14 01:38:47 +08:00
|
|
|
fh->type = fh_type;
|
2007-11-12 00:17:17 +08:00
|
|
|
filp->private_data = fh;
|
2006-01-24 03:11:09 +08:00
|
|
|
|
2008-04-14 01:38:47 +08:00
|
|
|
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
|
2007-11-12 00:17:17 +08:00
|
|
|
dev->width = norm_maxw(dev);
|
|
|
|
dev->height = norm_maxh(dev);
|
|
|
|
dev->hscale = 0;
|
|
|
|
dev->vscale = 0;
|
2006-01-24 03:11:08 +08:00
|
|
|
|
2008-04-18 08:48:00 +08:00
|
|
|
em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
|
V4L/DVB (7179): Allow more than one em28xx board
em28xx driver is capable of handling more than one usb device. However, isoc
transfers require a large amount of data to be transfered.
Before this patch, just one em28xx board were enough to allocate more than 50%
URBs:
T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 8
B: Alloc=480/800 us (60%), #Int= 0, #Iso= 2
D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=01 MxPS=64 #Cfgs= 1
So, only one board could use an USB host at the same time. After the patch, it
is possible to use more than one em28xx at the same time, on the same usb host,
if the image size is slower or equal to 345600, since those images will
require about 30% of the URBs:
T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 8
B: Alloc=232/800 us (29%), #Int= 0, #Iso= 2
D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=01 MxPS=64 #Cfgs= 1
So, in thesis, after the patch, it would be possible to use up to 3 boards by
each usb host, if the devices are generating small images.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-02-09 02:44:25 +08:00
|
|
|
em28xx_set_alternate(dev);
|
2007-11-12 00:17:17 +08:00
|
|
|
em28xx_resolution_set(dev);
|
2006-01-24 03:11:08 +08:00
|
|
|
|
2008-04-18 08:48:00 +08:00
|
|
|
/* Needed, since GPIO might have disabled power of
|
|
|
|
some i2c device
|
|
|
|
*/
|
|
|
|
em28xx_config_i2c(dev);
|
|
|
|
|
2006-01-24 03:11:08 +08:00
|
|
|
}
|
2008-01-06 04:22:01 +08:00
|
|
|
if (fh->radio) {
|
|
|
|
em28xx_videodbg("video_open: setting radio device\n");
|
|
|
|
em28xx_i2c_call_clients(dev, AUDC_SET_RADIO, NULL);
|
|
|
|
}
|
2006-01-24 03:11:08 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
dev->users++;
|
2006-01-24 03:11:08 +08:00
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops,
|
|
|
|
NULL, &dev->slock, fh->type, V4L2_FIELD_INTERLACED,
|
|
|
|
sizeof(struct em28xx_buffer), fh);
|
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
mutex_unlock(&dev->lock);
|
2008-04-18 08:48:00 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
return errCode;
|
2006-01-24 03:11:08 +08:00
|
|
|
}
|
2006-01-24 03:11:08 +08:00
|
|
|
|
2005-11-09 13:37:07 +08:00
|
|
|
/*
|
2007-11-12 00:17:17 +08:00
|
|
|
* em28xx_realease_resources()
|
|
|
|
* unregisters the v4l2,i2c and usb devices
|
|
|
|
* called when the device gets disconected or at module unload
|
|
|
|
*/
|
|
|
|
static void em28xx_release_resources(struct em28xx *dev)
|
2005-11-09 13:37:07 +08:00
|
|
|
{
|
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
/*FIXME: I2C IR should be disconnected */
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
list_del(&dev->devlist);
|
2008-06-28 19:57:06 +08:00
|
|
|
if (dev->sbutton_input_dev)
|
|
|
|
em28xx_deregister_snapshot_button(dev);
|
2008-11-12 19:41:29 +08:00
|
|
|
|
|
|
|
if (dev->ir)
|
|
|
|
em28xx_ir_fini(dev);
|
|
|
|
|
2008-01-06 04:22:01 +08:00
|
|
|
if (dev->radio_dev) {
|
|
|
|
if (-1 != dev->radio_dev->minor)
|
|
|
|
video_unregister_device(dev->radio_dev);
|
|
|
|
else
|
|
|
|
video_device_release(dev->radio_dev);
|
|
|
|
dev->radio_dev = NULL;
|
|
|
|
}
|
|
|
|
if (dev->vbi_dev) {
|
2008-11-12 13:05:15 +08:00
|
|
|
em28xx_info("V4L2 device /dev/vbi%d deregistered\n",
|
|
|
|
dev->vbi_dev->num);
|
2008-01-06 04:22:01 +08:00
|
|
|
if (-1 != dev->vbi_dev->minor)
|
|
|
|
video_unregister_device(dev->vbi_dev);
|
|
|
|
else
|
|
|
|
video_device_release(dev->vbi_dev);
|
|
|
|
dev->vbi_dev = NULL;
|
|
|
|
}
|
|
|
|
if (dev->vdev) {
|
2008-11-12 13:05:15 +08:00
|
|
|
em28xx_info("V4L2 device /dev/video%d deregistered\n",
|
|
|
|
dev->vdev->num);
|
2008-01-06 04:22:01 +08:00
|
|
|
if (-1 != dev->vdev->minor)
|
|
|
|
video_unregister_device(dev->vdev);
|
|
|
|
else
|
|
|
|
video_device_release(dev->vdev);
|
|
|
|
dev->vdev = NULL;
|
|
|
|
}
|
2007-11-12 00:17:17 +08:00
|
|
|
em28xx_i2c_unregister(dev);
|
|
|
|
usb_put_dev(dev->udev);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
/* Mark device as unused */
|
2008-04-18 08:41:10 +08:00
|
|
|
em28xx_devused &= ~(1<<dev->devno);
|
2007-11-12 00:17:17 +08:00
|
|
|
}
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
/*
|
|
|
|
* em28xx_v4l2_close()
|
2008-04-18 08:41:10 +08:00
|
|
|
* stops streaming and deallocates all resources allocated by the v4l2
|
|
|
|
* calls and ioctls
|
2007-11-12 00:17:17 +08:00
|
|
|
*/
|
|
|
|
static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = filp->private_data;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int errCode;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
em28xx_videodbg("users=%d\n", dev->users);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
if (res_check(fh))
|
|
|
|
res_free(fh);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
mutex_lock(&dev->lock);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
if (dev->users == 1) {
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
videobuf_stop(&fh->vb_vidq);
|
|
|
|
videobuf_mmap_free(&fh->vb_vidq);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
/* the device is already disconnect,
|
|
|
|
free the remaining resources */
|
|
|
|
if (dev->state & DEV_DISCONNECTED) {
|
|
|
|
em28xx_release_resources(dev);
|
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
kfree(dev);
|
|
|
|
return 0;
|
|
|
|
}
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2008-04-14 01:38:47 +08:00
|
|
|
/* do this before setting alternate! */
|
|
|
|
em28xx_uninit_isoc(dev);
|
2008-04-18 08:48:00 +08:00
|
|
|
em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED);
|
2008-04-14 01:38:47 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
/* set alternate 0 */
|
|
|
|
dev->alt = 0;
|
|
|
|
em28xx_videodbg("setting alternate 0\n");
|
|
|
|
errCode = usb_set_interface(dev->udev, 0, 0);
|
|
|
|
if (errCode < 0) {
|
|
|
|
em28xx_errdev("cannot change alternate number to "
|
|
|
|
"0 (error=%i)\n", errCode);
|
|
|
|
}
|
2006-01-24 03:11:09 +08:00
|
|
|
}
|
2007-11-12 00:17:17 +08:00
|
|
|
kfree(fh);
|
|
|
|
dev->users--;
|
|
|
|
wake_up_interruptible_nr(&dev->open, 1);
|
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
return 0;
|
|
|
|
}
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
/*
|
|
|
|
* em28xx_v4l2_read()
|
|
|
|
* will allocate buffers when called for the first time
|
|
|
|
*/
|
|
|
|
static ssize_t
|
2008-04-18 08:41:10 +08:00
|
|
|
em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count,
|
2008-04-14 01:41:23 +08:00
|
|
|
loff_t *pos)
|
2007-11-12 00:17:17 +08:00
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = filp->private_data;
|
|
|
|
struct em28xx *dev = fh->dev;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
/* FIXME: read() is not prepared to allow changing the video
|
|
|
|
resolution while streaming. Seems a bug at em28xx_set_fmt
|
|
|
|
*/
|
2005-11-09 13:37:07 +08:00
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
|
|
|
|
if (unlikely(res_get(fh)))
|
|
|
|
return -EBUSY;
|
2007-11-12 00:17:17 +08:00
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
|
|
|
|
filp->f_flags & O_NONBLOCK);
|
2007-11-12 00:17:17 +08:00
|
|
|
}
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
return 0;
|
2005-11-09 13:37:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2007-11-12 00:17:17 +08:00
|
|
|
* em28xx_v4l2_poll()
|
|
|
|
* will allocate buffers when called for the first time
|
2005-11-09 13:37:07 +08:00
|
|
|
*/
|
2007-11-12 00:17:17 +08:00
|
|
|
static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
|
2005-11-09 13:37:07 +08:00
|
|
|
{
|
2007-11-11 09:21:01 +08:00
|
|
|
struct em28xx_fh *fh = filp->private_data;
|
2007-11-12 00:17:17 +08:00
|
|
|
struct em28xx *dev = fh->dev;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
if (unlikely(res_get(fh) < 0))
|
|
|
|
return POLLERR;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
|
|
|
|
return POLLERR;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
|
2007-11-12 00:17:17 +08:00
|
|
|
}
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
/*
|
|
|
|
* em28xx_v4l2_mmap()
|
|
|
|
*/
|
|
|
|
static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = filp->private_data;
|
|
|
|
struct em28xx *dev = fh->dev;
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
int rc;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 00:17:17 +08:00
|
|
|
if (unlikely(res_get(fh) < 0))
|
|
|
|
return -EBUSY;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
em28xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n",
|
|
|
|
(unsigned long)vma->vm_start,
|
|
|
|
(unsigned long)vma->vm_end-(unsigned long)vma->vm_start,
|
|
|
|
rc);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
return rc;
|
2005-11-09 13:37:07 +08:00
|
|
|
}
|
|
|
|
|
2007-02-12 16:55:33 +08:00
|
|
|
static const struct file_operations em28xx_v4l_fops = {
|
2007-11-12 00:17:17 +08:00
|
|
|
.owner = THIS_MODULE,
|
|
|
|
.open = em28xx_v4l2_open,
|
|
|
|
.release = em28xx_v4l2_close,
|
|
|
|
.read = em28xx_v4l2_read,
|
|
|
|
.poll = em28xx_v4l2_poll,
|
|
|
|
.mmap = em28xx_v4l2_mmap,
|
|
|
|
.ioctl = video_ioctl2,
|
|
|
|
.llseek = no_llseek,
|
|
|
|
.compat_ioctl = v4l_compat_ioctl32,
|
|
|
|
};
|
2006-01-10 01:24:58 +08:00
|
|
|
|
2008-07-21 13:57:38 +08:00
|
|
|
static const struct v4l2_ioctl_ops video_ioctl_ops = {
|
2007-11-12 00:17:17 +08:00
|
|
|
.vidioc_querycap = vidioc_querycap,
|
2008-05-28 23:16:41 +08:00
|
|
|
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
|
|
|
|
.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
|
|
|
|
.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
|
|
|
|
.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
|
2007-11-12 00:17:17 +08:00
|
|
|
.vidioc_g_audio = vidioc_g_audio,
|
|
|
|
.vidioc_s_audio = vidioc_s_audio,
|
|
|
|
.vidioc_cropcap = vidioc_cropcap,
|
|
|
|
|
2008-05-28 23:16:41 +08:00
|
|
|
.vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap,
|
|
|
|
.vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
|
|
|
|
.vidioc_s_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
|
2007-11-12 00:17:17 +08:00
|
|
|
|
|
|
|
.vidioc_reqbufs = vidioc_reqbufs,
|
|
|
|
.vidioc_querybuf = vidioc_querybuf,
|
|
|
|
.vidioc_qbuf = vidioc_qbuf,
|
|
|
|
.vidioc_dqbuf = vidioc_dqbuf,
|
|
|
|
.vidioc_s_std = vidioc_s_std,
|
|
|
|
.vidioc_enum_input = vidioc_enum_input,
|
|
|
|
.vidioc_g_input = vidioc_g_input,
|
|
|
|
.vidioc_s_input = vidioc_s_input,
|
|
|
|
.vidioc_queryctrl = vidioc_queryctrl,
|
|
|
|
.vidioc_g_ctrl = vidioc_g_ctrl,
|
|
|
|
.vidioc_s_ctrl = vidioc_s_ctrl,
|
|
|
|
.vidioc_streamon = vidioc_streamon,
|
|
|
|
.vidioc_streamoff = vidioc_streamoff,
|
|
|
|
.vidioc_g_tuner = vidioc_g_tuner,
|
|
|
|
.vidioc_s_tuner = vidioc_s_tuner,
|
|
|
|
.vidioc_g_frequency = vidioc_g_frequency,
|
|
|
|
.vidioc_s_frequency = vidioc_s_frequency,
|
2008-02-06 20:00:41 +08:00
|
|
|
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
|
|
|
.vidioc_g_register = vidioc_g_register,
|
|
|
|
.vidioc_s_register = vidioc_s_register,
|
|
|
|
#endif
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
|
|
|
.vidiocgmbuf = vidiocgmbuf,
|
|
|
|
#endif
|
2008-07-21 13:57:38 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static const struct video_device em28xx_video_template = {
|
|
|
|
.fops = &em28xx_v4l_fops,
|
|
|
|
.release = video_device_release,
|
|
|
|
.ioctl_ops = &video_ioctl_ops,
|
|
|
|
|
|
|
|
.minor = -1,
|
2007-11-12 00:17:17 +08:00
|
|
|
|
|
|
|
.tvnorms = V4L2_STD_ALL,
|
2007-11-12 01:15:34 +08:00
|
|
|
.current_norm = V4L2_STD_PAL,
|
2005-11-09 13:37:07 +08:00
|
|
|
};
|
|
|
|
|
2008-07-21 13:57:38 +08:00
|
|
|
static const struct file_operations radio_fops = {
|
|
|
|
.owner = THIS_MODULE,
|
|
|
|
.open = em28xx_v4l2_open,
|
|
|
|
.release = em28xx_v4l2_close,
|
|
|
|
.ioctl = video_ioctl2,
|
|
|
|
.compat_ioctl = v4l_compat_ioctl32,
|
|
|
|
.llseek = no_llseek,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct v4l2_ioctl_ops radio_ioctl_ops = {
|
2008-01-06 04:22:01 +08:00
|
|
|
.vidioc_querycap = radio_querycap,
|
|
|
|
.vidioc_g_tuner = radio_g_tuner,
|
|
|
|
.vidioc_enum_input = radio_enum_input,
|
|
|
|
.vidioc_g_audio = radio_g_audio,
|
|
|
|
.vidioc_s_tuner = radio_s_tuner,
|
|
|
|
.vidioc_s_audio = radio_s_audio,
|
|
|
|
.vidioc_s_input = radio_s_input,
|
|
|
|
.vidioc_queryctrl = radio_queryctrl,
|
|
|
|
.vidioc_g_ctrl = vidioc_g_ctrl,
|
|
|
|
.vidioc_s_ctrl = vidioc_s_ctrl,
|
|
|
|
.vidioc_g_frequency = vidioc_g_frequency,
|
|
|
|
.vidioc_s_frequency = vidioc_s_frequency,
|
2008-02-06 20:00:41 +08:00
|
|
|
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
|
|
|
.vidioc_g_register = vidioc_g_register,
|
|
|
|
.vidioc_s_register = vidioc_s_register,
|
|
|
|
#endif
|
2008-01-06 04:22:01 +08:00
|
|
|
};
|
|
|
|
|
2008-07-21 13:57:38 +08:00
|
|
|
static struct video_device em28xx_radio_template = {
|
|
|
|
.name = "em28xx-radio",
|
|
|
|
.fops = &radio_fops,
|
|
|
|
.ioctl_ops = &radio_ioctl_ops,
|
|
|
|
.minor = -1,
|
|
|
|
};
|
|
|
|
|
2008-04-18 08:41:10 +08:00
|
|
|
/******************************** usb interface ******************************/
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2008-01-05 20:57:31 +08:00
|
|
|
|
|
|
|
static LIST_HEAD(em28xx_extension_devlist);
|
|
|
|
static DEFINE_MUTEX(em28xx_extension_devlist_lock);
|
|
|
|
|
|
|
|
int em28xx_register_extension(struct em28xx_ops *ops)
|
|
|
|
{
|
2008-06-10 01:58:04 +08:00
|
|
|
struct em28xx *dev = NULL;
|
2008-01-05 20:57:31 +08:00
|
|
|
|
2008-11-20 21:30:26 +08:00
|
|
|
mutex_lock(&em28xx_devlist_mutex);
|
2008-01-05 20:57:31 +08:00
|
|
|
mutex_lock(&em28xx_extension_devlist_lock);
|
|
|
|
list_add_tail(&ops->next, &em28xx_extension_devlist);
|
2008-06-10 01:58:04 +08:00
|
|
|
list_for_each_entry(dev, &em28xx_devlist, devlist) {
|
|
|
|
if (dev)
|
|
|
|
ops->init(dev);
|
|
|
|
}
|
2008-01-05 20:57:31 +08:00
|
|
|
printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name);
|
|
|
|
mutex_unlock(&em28xx_extension_devlist_lock);
|
2008-11-20 21:30:26 +08:00
|
|
|
mutex_unlock(&em28xx_devlist_mutex);
|
2008-01-05 20:57:31 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(em28xx_register_extension);
|
|
|
|
|
|
|
|
void em28xx_unregister_extension(struct em28xx_ops *ops)
|
|
|
|
{
|
2008-06-10 01:58:04 +08:00
|
|
|
struct em28xx *dev = NULL;
|
2008-01-05 20:57:31 +08:00
|
|
|
|
2008-11-20 21:30:26 +08:00
|
|
|
mutex_lock(&em28xx_devlist_mutex);
|
2008-06-10 01:58:04 +08:00
|
|
|
list_for_each_entry(dev, &em28xx_devlist, devlist) {
|
|
|
|
if (dev)
|
|
|
|
ops->fini(dev);
|
|
|
|
}
|
2008-01-05 20:57:31 +08:00
|
|
|
|
|
|
|
mutex_lock(&em28xx_extension_devlist_lock);
|
|
|
|
printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name);
|
|
|
|
list_del(&ops->next);
|
|
|
|
mutex_unlock(&em28xx_extension_devlist_lock);
|
2008-11-20 21:30:26 +08:00
|
|
|
mutex_unlock(&em28xx_devlist_mutex);
|
2008-01-05 20:57:31 +08:00
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(em28xx_unregister_extension);
|
|
|
|
|
2008-01-29 09:10:48 +08:00
|
|
|
static struct video_device *em28xx_vdev_init(struct em28xx *dev,
|
|
|
|
const struct video_device *template,
|
|
|
|
const char *type_name)
|
2008-01-06 04:22:01 +08:00
|
|
|
{
|
|
|
|
struct video_device *vfd;
|
|
|
|
|
|
|
|
vfd = video_device_alloc();
|
|
|
|
if (NULL == vfd)
|
|
|
|
return NULL;
|
|
|
|
*vfd = *template;
|
|
|
|
vfd->minor = -1;
|
2008-07-20 17:31:39 +08:00
|
|
|
vfd->parent = &dev->udev->dev;
|
2008-01-06 04:22:01 +08:00
|
|
|
vfd->release = video_device_release;
|
2008-04-14 02:05:47 +08:00
|
|
|
vfd->debug = video_debug;
|
2008-01-06 04:22:01 +08:00
|
|
|
|
|
|
|
snprintf(vfd->name, sizeof(vfd->name), "%s %s",
|
|
|
|
dev->name, type_name);
|
|
|
|
|
|
|
|
return vfd;
|
|
|
|
}
|
|
|
|
|
2008-11-20 21:30:26 +08:00
|
|
|
static int register_analog_devices(struct em28xx *dev)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
/* allocate and fill video video_device struct */
|
|
|
|
dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
|
|
|
|
if (!dev->vdev) {
|
|
|
|
em28xx_errdev("cannot allocate video_device.\n");
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* register v4l2 video video_device */
|
|
|
|
ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
|
|
|
|
video_nr[dev->devno]);
|
|
|
|
if (ret) {
|
|
|
|
em28xx_errdev("unable to register video device (error=%i).\n",
|
|
|
|
ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate and fill vbi video_device struct */
|
|
|
|
dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, "vbi");
|
|
|
|
|
|
|
|
/* register v4l2 vbi video_device */
|
|
|
|
ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
|
|
|
|
vbi_nr[dev->devno]);
|
|
|
|
if (ret < 0) {
|
|
|
|
em28xx_errdev("unable to register vbi device\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
|
|
|
|
dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio");
|
|
|
|
if (!dev->radio_dev) {
|
|
|
|
em28xx_errdev("cannot allocate video_device.\n");
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
|
|
|
ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
|
|
|
|
radio_nr[dev->devno]);
|
|
|
|
if (ret < 0) {
|
|
|
|
em28xx_errdev("can't register radio device\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
em28xx_info("Registered radio device as /dev/radio%d\n",
|
|
|
|
dev->radio_dev->num);
|
|
|
|
}
|
|
|
|
|
|
|
|
em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n",
|
|
|
|
dev->vdev->num, dev->vbi_dev->num);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-11-09 13:37:07 +08:00
|
|
|
/*
|
2005-11-09 13:38:27 +08:00
|
|
|
* em28xx_init_dev()
|
2005-11-09 13:37:07 +08:00
|
|
|
* allocates and inits the device structs, registers i2c bus and v4l device
|
|
|
|
*/
|
2005-11-09 13:38:27 +08:00
|
|
|
static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
|
2007-11-04 08:20:59 +08:00
|
|
|
int minor)
|
2005-11-09 13:37:07 +08:00
|
|
|
{
|
2008-01-05 20:57:31 +08:00
|
|
|
struct em28xx_ops *ops = NULL;
|
2005-11-09 13:38:27 +08:00
|
|
|
struct em28xx *dev = *devhandle;
|
2005-11-09 13:37:07 +08:00
|
|
|
int retval = -ENOMEM;
|
2007-11-12 01:15:34 +08:00
|
|
|
int errCode;
|
2005-11-09 13:37:07 +08:00
|
|
|
unsigned int maxh, maxw;
|
|
|
|
|
|
|
|
dev->udev = udev;
|
2006-02-07 16:49:14 +08:00
|
|
|
mutex_init(&dev->lock);
|
2008-11-19 17:17:44 +08:00
|
|
|
mutex_init(&dev->ctrl_urb_lock);
|
2008-04-14 01:38:47 +08:00
|
|
|
spin_lock_init(&dev->slock);
|
2005-11-09 13:37:07 +08:00
|
|
|
init_waitqueue_head(&dev->open);
|
2007-11-11 09:21:01 +08:00
|
|
|
init_waitqueue_head(&dev->wait_frame);
|
|
|
|
init_waitqueue_head(&dev->wait_stream);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2005-11-09 13:38:27 +08:00
|
|
|
dev->em28xx_write_regs = em28xx_write_regs;
|
|
|
|
dev->em28xx_read_reg = em28xx_read_reg;
|
|
|
|
dev->em28xx_read_reg_req_len = em28xx_read_reg_req_len;
|
|
|
|
dev->em28xx_write_regs_req = em28xx_write_regs_req;
|
|
|
|
dev->em28xx_read_reg_req = em28xx_read_reg_req;
|
2008-11-25 20:39:50 +08:00
|
|
|
dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2006-01-24 03:11:10 +08:00
|
|
|
em28xx_pre_card_setup(dev);
|
2007-11-04 08:20:59 +08:00
|
|
|
|
2005-11-09 13:38:27 +08:00
|
|
|
errCode = em28xx_config(dev);
|
2005-11-09 13:37:07 +08:00
|
|
|
if (errCode) {
|
2005-11-09 13:38:27 +08:00
|
|
|
em28xx_errdev("error configuring device\n");
|
2005-11-09 13:37:07 +08:00
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* register i2c bus */
|
2008-09-08 14:27:20 +08:00
|
|
|
errCode = em28xx_i2c_register(dev);
|
|
|
|
if (errCode < 0) {
|
|
|
|
em28xx_errdev("%s: em28xx_i2c_register - errCode [%d]!\n",
|
|
|
|
__func__, errCode);
|
|
|
|
return errCode;
|
|
|
|
}
|
2005-11-09 13:37:07 +08:00
|
|
|
|
|
|
|
/* Do board specific init and eeprom reading */
|
2005-11-09 13:38:27 +08:00
|
|
|
em28xx_card_setup(dev);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2008-01-06 04:01:41 +08:00
|
|
|
/* Configure audio */
|
2008-11-19 23:01:33 +08:00
|
|
|
errCode = em28xx_audio_setup(dev);
|
2008-09-08 14:27:20 +08:00
|
|
|
if (errCode < 0) {
|
2008-11-19 23:01:33 +08:00
|
|
|
em28xx_errdev("%s: Error while setting audio - errCode [%d]!\n",
|
2008-09-08 14:27:20 +08:00
|
|
|
__func__, errCode);
|
|
|
|
}
|
2008-01-06 04:01:41 +08:00
|
|
|
|
2005-11-09 13:37:07 +08:00
|
|
|
/* configure the device */
|
2005-11-09 13:38:27 +08:00
|
|
|
em28xx_config_i2c(dev);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2007-11-12 01:15:34 +08:00
|
|
|
/* set default norm */
|
|
|
|
dev->norm = em28xx_video_template.current_norm;
|
2007-11-04 08:20:59 +08:00
|
|
|
|
|
|
|
maxw = norm_maxw(dev);
|
|
|
|
maxh = norm_maxh(dev);
|
|
|
|
|
|
|
|
/* set default image size */
|
|
|
|
dev->width = maxw;
|
|
|
|
dev->height = maxh;
|
|
|
|
dev->interlaced = EM28XX_INTERLACED_DEFAULT;
|
|
|
|
dev->hscale = 0;
|
|
|
|
dev->vscale = 0;
|
|
|
|
dev->ctl_input = 2;
|
|
|
|
|
2005-11-09 13:38:27 +08:00
|
|
|
errCode = em28xx_config(dev);
|
2008-09-08 14:27:20 +08:00
|
|
|
if (errCode < 0) {
|
|
|
|
em28xx_errdev("%s: em28xx_config - errCode [%d]!\n",
|
|
|
|
__func__, errCode);
|
|
|
|
return errCode;
|
|
|
|
}
|
2005-11-09 13:37:07 +08:00
|
|
|
|
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-04-14 01:37:52 +08:00
|
|
|
/* init video dma queues */
|
|
|
|
INIT_LIST_HEAD(&dev->vidq.active);
|
|
|
|
INIT_LIST_HEAD(&dev->vidq.queued);
|
|
|
|
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2008-11-25 20:39:50 +08:00
|
|
|
if (dev->board.has_msp34xx) {
|
2007-11-04 08:22:38 +08:00
|
|
|
/* Send a reset to other chips via gpio */
|
V4L/DVB (9758): em28xx: replace some magic by register descriptions where known
Replaces all occurrences of em28xx_write_regs_req() and em28xx_write_reg()
used to setup register names by em28xx_write_reg().
Also, documents the register names that are known.
This patch were generated by this small perl script:
my %reg_map = (
# Register table - the same as defined on parse_em28xx.pl script
);
while (<>) {
if (m/(.*)em28xx_write_regs_req\(dev\,\s*0x00\,\s*(.*)\,\s*\"\\x(..)\",\s*1\)\;(.*)/) {
my $reg = $2;
my $val = $3;
$val =~ tr/A-f/a-f/;
$reg = $reg_map{$reg} if defined($reg_map{$reg});
printf "$1em28xx_write_reg(dev, %s, 0x%s);$4\n", $reg, $val;
} elsif (m/(.*)em28xx_write_regs\(dev\,\s*(.*)\,\s*\"\\x(..)\",\s*1\)\;(.*)/) {
my $reg = $2;
my $val = $3;
$val =~ tr/A-f/a-f/;
$reg = $reg_map{$reg} if defined($reg_map{$reg});
printf "$1em28xx_write_reg(dev, %s, 0x%s);$4\n", $reg, $val;
} else {
print $_;
}
}
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2008-11-27 03:28:42 +08:00
|
|
|
errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
|
2008-09-08 14:27:20 +08:00
|
|
|
if (errCode < 0) {
|
|
|
|
em28xx_errdev("%s: em28xx_write_regs_req - msp34xx(1) failed! errCode [%d]\n",
|
|
|
|
__func__, errCode);
|
|
|
|
return errCode;
|
|
|
|
}
|
2007-11-04 08:22:38 +08:00
|
|
|
msleep(3);
|
2008-09-08 14:27:20 +08:00
|
|
|
|
V4L/DVB (9758): em28xx: replace some magic by register descriptions where known
Replaces all occurrences of em28xx_write_regs_req() and em28xx_write_reg()
used to setup register names by em28xx_write_reg().
Also, documents the register names that are known.
This patch were generated by this small perl script:
my %reg_map = (
# Register table - the same as defined on parse_em28xx.pl script
);
while (<>) {
if (m/(.*)em28xx_write_regs_req\(dev\,\s*0x00\,\s*(.*)\,\s*\"\\x(..)\",\s*1\)\;(.*)/) {
my $reg = $2;
my $val = $3;
$val =~ tr/A-f/a-f/;
$reg = $reg_map{$reg} if defined($reg_map{$reg});
printf "$1em28xx_write_reg(dev, %s, 0x%s);$4\n", $reg, $val;
} elsif (m/(.*)em28xx_write_regs\(dev\,\s*(.*)\,\s*\"\\x(..)\",\s*1\)\;(.*)/) {
my $reg = $2;
my $val = $3;
$val =~ tr/A-f/a-f/;
$reg = $reg_map{$reg} if defined($reg_map{$reg});
printf "$1em28xx_write_reg(dev, %s, 0x%s);$4\n", $reg, $val;
} else {
print $_;
}
}
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2008-11-27 03:28:42 +08:00
|
|
|
errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
|
2008-09-08 14:27:20 +08:00
|
|
|
if (errCode < 0) {
|
|
|
|
em28xx_errdev("%s: em28xx_write_regs_req - msp34xx(2) failed! errCode [%d]\n",
|
|
|
|
__func__, errCode);
|
|
|
|
return errCode;
|
|
|
|
}
|
2007-11-04 08:22:38 +08:00
|
|
|
msleep(3);
|
|
|
|
}
|
2007-11-12 00:17:17 +08:00
|
|
|
|
2007-11-04 08:22:38 +08:00
|
|
|
video_mux(dev, 0);
|
|
|
|
|
2008-11-20 21:30:26 +08:00
|
|
|
mutex_lock(&em28xx_devlist_mutex);
|
|
|
|
list_add_tail(&dev->devlist, &em28xx_devlist);
|
|
|
|
retval = register_analog_devices(dev);
|
|
|
|
if (retval < 0) {
|
|
|
|
em28xx_release_resources(dev);
|
|
|
|
mutex_unlock(&em28xx_devlist_mutex);
|
|
|
|
goto fail_reg_devices;
|
|
|
|
}
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2008-01-05 20:57:31 +08:00
|
|
|
mutex_lock(&em28xx_extension_devlist_lock);
|
|
|
|
if (!list_empty(&em28xx_extension_devlist)) {
|
|
|
|
list_for_each_entry(ops, &em28xx_extension_devlist, next) {
|
|
|
|
if (ops->id)
|
|
|
|
ops->init(dev);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mutex_unlock(&em28xx_extension_devlist_lock);
|
2008-11-20 21:30:26 +08:00
|
|
|
mutex_unlock(&em28xx_devlist_mutex);
|
2008-01-05 20:57:31 +08:00
|
|
|
|
2005-11-09 13:37:07 +08:00
|
|
|
return 0;
|
2008-01-06 04:22:01 +08:00
|
|
|
|
2008-11-20 21:30:26 +08:00
|
|
|
fail_reg_devices:
|
2008-01-06 04:22:01 +08:00
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
return retval;
|
2005-11-09 13:37:07 +08:00
|
|
|
}
|
|
|
|
|
2008-01-05 20:59:03 +08:00
|
|
|
#if defined(CONFIG_MODULES) && defined(MODULE)
|
|
|
|
static void request_module_async(struct work_struct *work)
|
|
|
|
{
|
|
|
|
struct em28xx *dev = container_of(work,
|
|
|
|
struct em28xx, request_module_wk);
|
|
|
|
|
2008-01-06 20:54:17 +08:00
|
|
|
if (dev->has_audio_class)
|
|
|
|
request_module("snd-usb-audio");
|
2008-11-12 13:05:19 +08:00
|
|
|
else if (dev->has_alsa_audio)
|
2008-01-05 20:59:03 +08:00
|
|
|
request_module("em28xx-alsa");
|
2008-04-18 08:36:41 +08:00
|
|
|
|
2008-11-25 20:39:50 +08:00
|
|
|
if (dev->board.has_dvb)
|
2008-04-18 08:36:41 +08:00
|
|
|
request_module("em28xx-dvb");
|
2008-01-05 20:59:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void request_modules(struct em28xx *dev)
|
|
|
|
{
|
|
|
|
INIT_WORK(&dev->request_module_wk, request_module_async);
|
|
|
|
schedule_work(&dev->request_module_wk);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#define request_modules(dev)
|
|
|
|
#endif /* CONFIG_MODULES */
|
|
|
|
|
2005-11-09 13:37:07 +08:00
|
|
|
/*
|
2005-11-09 13:38:27 +08:00
|
|
|
* em28xx_usb_probe()
|
2005-11-09 13:37:07 +08:00
|
|
|
* checks for supported devices
|
|
|
|
*/
|
2005-11-09 13:38:27 +08:00
|
|
|
static int em28xx_usb_probe(struct usb_interface *interface,
|
2005-11-09 13:37:07 +08:00
|
|
|
const struct usb_device_id *id)
|
|
|
|
{
|
|
|
|
const struct usb_endpoint_descriptor *endpoint;
|
|
|
|
struct usb_device *udev;
|
2005-11-09 13:38:52 +08:00
|
|
|
struct usb_interface *uif;
|
2005-11-09 13:38:27 +08:00
|
|
|
struct em28xx *dev = NULL;
|
2005-11-09 13:37:07 +08:00
|
|
|
int retval = -ENODEV;
|
2008-11-12 13:02:17 +08:00
|
|
|
int i, nr, ifnum, isoc_pipe;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
|
|
|
udev = usb_get_dev(interface_to_usbdev(interface));
|
2005-11-09 13:37:32 +08:00
|
|
|
ifnum = interface->altsetting[0].desc.bInterfaceNumber;
|
|
|
|
|
2006-01-24 03:11:08 +08:00
|
|
|
/* Check to see next free device and mark as used */
|
2008-04-18 08:41:10 +08:00
|
|
|
nr = find_first_zero_bit(&em28xx_devused, EM28XX_MAXBOARDS);
|
|
|
|
em28xx_devused |= 1<<nr;
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2005-11-09 13:37:24 +08:00
|
|
|
/* Don't register audio interfaces */
|
2005-11-09 13:38:13 +08:00
|
|
|
if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
|
2005-11-09 13:38:27 +08:00
|
|
|
em28xx_err(DRIVER_NAME " audio device (%04x:%04x): interface %i, class %i\n",
|
2008-04-18 08:41:10 +08:00
|
|
|
udev->descriptor.idVendor,
|
|
|
|
udev->descriptor.idProduct,
|
2005-11-09 13:38:13 +08:00
|
|
|
ifnum,
|
|
|
|
interface->altsetting[0].desc.bInterfaceClass);
|
2006-01-24 03:11:08 +08:00
|
|
|
|
2008-04-18 08:41:10 +08:00
|
|
|
em28xx_devused &= ~(1<<nr);
|
2005-11-09 13:37:24 +08:00
|
|
|
return -ENODEV;
|
2005-11-09 13:38:13 +08:00
|
|
|
}
|
|
|
|
|
2008-11-12 13:02:17 +08:00
|
|
|
endpoint = &interface->cur_altsetting->endpoint[0].desc;
|
2005-11-09 13:37:32 +08:00
|
|
|
|
2007-05-09 14:57:56 +08:00
|
|
|
/* check if the device has the iso in endpoint at the correct place */
|
2008-11-12 13:02:17 +08:00
|
|
|
if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
|
|
|
|
USB_ENDPOINT_XFER_ISOC &&
|
|
|
|
(interface->altsetting[1].endpoint[0].desc.wMaxPacketSize == 940))
|
|
|
|
{
|
|
|
|
/* It's a newer em2874/em2875 device */
|
|
|
|
isoc_pipe = 0;
|
|
|
|
} else {
|
2008-11-22 21:50:38 +08:00
|
|
|
int check_interface = 1;
|
2008-11-12 13:02:17 +08:00
|
|
|
isoc_pipe = 1;
|
|
|
|
endpoint = &interface->cur_altsetting->endpoint[1].desc;
|
|
|
|
if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
|
2008-11-22 21:50:38 +08:00
|
|
|
USB_ENDPOINT_XFER_ISOC)
|
|
|
|
check_interface = 0;
|
|
|
|
|
|
|
|
if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)
|
|
|
|
check_interface = 0;
|
|
|
|
|
|
|
|
if (!check_interface) {
|
|
|
|
em28xx_err(DRIVER_NAME " video device (%04x:%04x): "
|
|
|
|
"interface %i, class %i found.\n",
|
|
|
|
udev->descriptor.idVendor,
|
|
|
|
udev->descriptor.idProduct,
|
|
|
|
ifnum,
|
|
|
|
interface->altsetting[0].desc.bInterfaceClass);
|
|
|
|
|
|
|
|
em28xx_err(DRIVER_NAME " This is an anciliary "
|
|
|
|
"interface not used by the driver\n");
|
|
|
|
|
2008-11-12 13:02:17 +08:00
|
|
|
em28xx_devused &= ~(1<<nr);
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
2008-11-22 21:50:38 +08:00
|
|
|
|
2005-11-09 13:37:07 +08:00
|
|
|
}
|
|
|
|
|
2008-11-22 21:50:38 +08:00
|
|
|
em28xx_err(DRIVER_NAME " new video device (%04x:%04x): interface %i, class %i\n",
|
|
|
|
udev->descriptor.idVendor,
|
|
|
|
udev->descriptor.idProduct,
|
|
|
|
ifnum,
|
|
|
|
interface->altsetting[0].desc.bInterfaceClass);
|
|
|
|
|
2006-03-15 04:24:57 +08:00
|
|
|
if (nr >= EM28XX_MAXBOARDS) {
|
2008-04-18 08:41:10 +08:00
|
|
|
printk(DRIVER_NAME ": Supports only %i em28xx boards.\n",
|
|
|
|
EM28XX_MAXBOARDS);
|
|
|
|
em28xx_devused &= ~(1<<nr);
|
2005-11-09 13:37:24 +08:00
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* allocate memory for our device state and initialize it */
|
2006-01-12 05:40:56 +08:00
|
|
|
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
2005-11-09 13:37:24 +08:00
|
|
|
if (dev == NULL) {
|
2005-11-09 13:38:27 +08:00
|
|
|
em28xx_err(DRIVER_NAME ": out of memory!\n");
|
2008-04-18 08:41:10 +08:00
|
|
|
em28xx_devused &= ~(1<<nr);
|
2005-11-09 13:37:24 +08:00
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
2006-01-24 03:11:08 +08:00
|
|
|
snprintf(dev->name, 29, "em28xx #%d", nr);
|
2007-11-04 08:20:59 +08:00
|
|
|
dev->devno = nr;
|
|
|
|
dev->model = id->driver_info;
|
V4L/DVB (7179): Allow more than one em28xx board
em28xx driver is capable of handling more than one usb device. However, isoc
transfers require a large amount of data to be transfered.
Before this patch, just one em28xx board were enough to allocate more than 50%
URBs:
T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 8
B: Alloc=480/800 us (60%), #Int= 0, #Iso= 2
D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=01 MxPS=64 #Cfgs= 1
So, only one board could use an USB host at the same time. After the patch, it
is possible to use more than one em28xx at the same time, on the same usb host,
if the image size is slower or equal to 345600, since those images will
require about 30% of the URBs:
T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 8
B: Alloc=232/800 us (29%), #Int= 0, #Iso= 2
D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=01 MxPS=64 #Cfgs= 1
So, in thesis, after the patch, it would be possible to use up to 3 boards by
each usb host, if the devices are generating small images.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
2008-02-09 02:44:25 +08:00
|
|
|
dev->alt = -1;
|
2006-01-24 03:11:08 +08:00
|
|
|
|
2008-01-05 20:59:03 +08:00
|
|
|
/* Checks if audio is provided by some interface */
|
|
|
|
for (i = 0; i < udev->config->desc.bNumInterfaces; i++) {
|
|
|
|
uif = udev->config->interface[i];
|
|
|
|
if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
|
|
|
|
dev->has_audio_class = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-11-09 13:38:52 +08:00
|
|
|
/* compute alternate max packet sizes */
|
|
|
|
uif = udev->actconfig->interface[0];
|
|
|
|
|
2008-04-18 08:41:10 +08:00
|
|
|
dev->num_alt = uif->num_altsetting;
|
2008-11-25 21:06:21 +08:00
|
|
|
em28xx_videodbg("Alternate settings: %i\n", dev->num_alt);
|
2008-04-18 08:41:10 +08:00
|
|
|
/* dev->alt_max_pkt_size = kmalloc(sizeof(*dev->alt_max_pkt_size)* */
|
|
|
|
dev->alt_max_pkt_size = kmalloc(32 * dev->num_alt, GFP_KERNEL);
|
|
|
|
|
2005-11-09 13:38:52 +08:00
|
|
|
if (dev->alt_max_pkt_size == NULL) {
|
2006-01-24 03:11:08 +08:00
|
|
|
em28xx_errdev("out of memory!\n");
|
2008-04-18 08:41:10 +08:00
|
|
|
em28xx_devused &= ~(1<<nr);
|
2007-08-10 05:02:36 +08:00
|
|
|
kfree(dev);
|
2005-11-09 13:38:52 +08:00
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < dev->num_alt ; i++) {
|
2008-11-12 13:02:17 +08:00
|
|
|
u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.
|
2005-11-09 13:38:52 +08:00
|
|
|
wMaxPacketSize);
|
|
|
|
dev->alt_max_pkt_size[i] =
|
|
|
|
(tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
|
2008-11-25 21:06:21 +08:00
|
|
|
em28xx_videodbg("Alternate setting %i, max size= %i\n", i,
|
2008-04-18 08:41:10 +08:00
|
|
|
dev->alt_max_pkt_size[i]);
|
2005-11-09 13:38:52 +08:00
|
|
|
}
|
|
|
|
|
2008-04-18 08:41:10 +08:00
|
|
|
if ((card[nr] >= 0) && (card[nr] < em28xx_bcount))
|
2007-11-04 08:20:59 +08:00
|
|
|
dev->model = card[nr];
|
2005-11-09 13:37:24 +08:00
|
|
|
|
2005-11-09 13:37:07 +08:00
|
|
|
/* allocate device struct */
|
2007-11-04 08:20:59 +08:00
|
|
|
retval = em28xx_init_dev(&dev, udev, nr);
|
2008-11-18 21:23:19 +08:00
|
|
|
if (retval) {
|
|
|
|
em28xx_devused &= ~(1<<dev->devno);
|
|
|
|
kfree(dev);
|
|
|
|
|
2005-11-09 13:37:07 +08:00
|
|
|
return retval;
|
2008-11-18 21:23:19 +08:00
|
|
|
}
|
2005-11-09 13:37:07 +08:00
|
|
|
|
|
|
|
/* save our data pointer in this interface device */
|
|
|
|
usb_set_intfdata(interface, dev);
|
2008-01-05 20:59:03 +08:00
|
|
|
|
|
|
|
request_modules(dev);
|
|
|
|
|
2005-11-09 13:37:07 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2005-11-09 13:38:27 +08:00
|
|
|
* em28xx_usb_disconnect()
|
2005-11-09 13:37:07 +08:00
|
|
|
* called when the device gets diconencted
|
|
|
|
* video device will be unregistered on v4l2_close in case it is still open
|
|
|
|
*/
|
2005-11-09 13:38:27 +08:00
|
|
|
static void em28xx_usb_disconnect(struct usb_interface *interface)
|
2005-11-09 13:37:07 +08:00
|
|
|
{
|
2007-11-04 08:22:38 +08:00
|
|
|
struct em28xx *dev;
|
2008-01-05 20:57:31 +08:00
|
|
|
struct em28xx_ops *ops = NULL;
|
2007-11-04 08:22:38 +08:00
|
|
|
|
|
|
|
dev = usb_get_intfdata(interface);
|
2005-11-09 13:37:07 +08:00
|
|
|
usb_set_intfdata(interface, NULL);
|
|
|
|
|
|
|
|
if (!dev)
|
|
|
|
return;
|
|
|
|
|
2007-11-04 08:22:38 +08:00
|
|
|
em28xx_info("disconnecting %s\n", dev->vdev->name);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2008-04-18 08:41:10 +08:00
|
|
|
/* wait until all current v4l2 io is finished then deallocate
|
|
|
|
resources */
|
2006-02-07 16:49:14 +08:00
|
|
|
mutex_lock(&dev->lock);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
|
|
|
wake_up_interruptible_all(&dev->open);
|
|
|
|
|
|
|
|
if (dev->users) {
|
2005-11-09 13:38:27 +08:00
|
|
|
em28xx_warn
|
2005-11-09 13:37:07 +08:00
|
|
|
("device /dev/video%d is open! Deregistration and memory "
|
2006-01-24 03:11:08 +08:00
|
|
|
"deallocation are deferred on close.\n",
|
2008-10-04 19:36:54 +08:00
|
|
|
dev->vdev->num);
|
2006-01-24 03:11:08 +08:00
|
|
|
|
2005-11-09 13:37:07 +08:00
|
|
|
dev->state |= DEV_MISCONFIGURED;
|
2005-11-09 13:38:27 +08:00
|
|
|
em28xx_uninit_isoc(dev);
|
2005-11-09 13:37:07 +08:00
|
|
|
dev->state |= DEV_DISCONNECTED;
|
|
|
|
wake_up_interruptible(&dev->wait_frame);
|
|
|
|
wake_up_interruptible(&dev->wait_stream);
|
|
|
|
} else {
|
|
|
|
dev->state |= DEV_DISCONNECTED;
|
2005-11-09 13:38:27 +08:00
|
|
|
em28xx_release_resources(dev);
|
2005-11-09 13:37:07 +08:00
|
|
|
}
|
2006-02-07 16:49:14 +08:00
|
|
|
mutex_unlock(&dev->lock);
|
2005-11-09 13:37:07 +08:00
|
|
|
|
2008-01-05 20:57:31 +08:00
|
|
|
mutex_lock(&em28xx_extension_devlist_lock);
|
|
|
|
if (!list_empty(&em28xx_extension_devlist)) {
|
|
|
|
list_for_each_entry(ops, &em28xx_extension_devlist, next) {
|
|
|
|
ops->fini(dev);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mutex_unlock(&em28xx_extension_devlist_lock);
|
|
|
|
|
2005-11-09 13:38:52 +08:00
|
|
|
if (!dev->users) {
|
|
|
|
kfree(dev->alt_max_pkt_size);
|
2005-11-09 13:37:07 +08:00
|
|
|
kfree(dev);
|
2005-11-09 13:38:52 +08:00
|
|
|
}
|
2005-11-09 13:37:07 +08:00
|
|
|
}
|
|
|
|
|
2005-11-09 13:38:27 +08:00
|
|
|
static struct usb_driver em28xx_usb_driver = {
|
|
|
|
.name = "em28xx",
|
|
|
|
.probe = em28xx_usb_probe,
|
|
|
|
.disconnect = em28xx_usb_disconnect,
|
|
|
|
.id_table = em28xx_id_table,
|
2005-11-09 13:37:07 +08:00
|
|
|
};
|
|
|
|
|
2005-11-09 13:38:27 +08:00
|
|
|
static int __init em28xx_module_init(void)
|
2005-11-09 13:37:07 +08:00
|
|
|
{
|
|
|
|
int result;
|
|
|
|
|
|
|
|
printk(KERN_INFO DRIVER_NAME " v4l2 driver version %d.%d.%d loaded\n",
|
2005-11-09 13:38:27 +08:00
|
|
|
(EM28XX_VERSION_CODE >> 16) & 0xff,
|
|
|
|
(EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff);
|
2005-11-09 13:37:07 +08:00
|
|
|
#ifdef SNAPSHOT
|
|
|
|
printk(KERN_INFO DRIVER_NAME " snapshot date %04d-%02d-%02d\n",
|
|
|
|
SNAPSHOT / 10000, (SNAPSHOT / 100) % 100, SNAPSHOT % 100);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* register this driver with the USB subsystem */
|
2005-11-09 13:38:27 +08:00
|
|
|
result = usb_register(&em28xx_usb_driver);
|
2005-11-09 13:37:07 +08:00
|
|
|
if (result)
|
2005-11-09 13:38:27 +08:00
|
|
|
em28xx_err(DRIVER_NAME
|
2005-11-09 13:37:07 +08:00
|
|
|
" usb_register failed. Error number %d.\n", result);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2005-11-09 13:38:27 +08:00
|
|
|
static void __exit em28xx_module_exit(void)
|
2005-11-09 13:37:07 +08:00
|
|
|
{
|
|
|
|
/* deregister this driver with the USB subsystem */
|
2005-11-09 13:38:27 +08:00
|
|
|
usb_deregister(&em28xx_usb_driver);
|
2005-11-09 13:37:07 +08:00
|
|
|
}
|
|
|
|
|
2005-11-09 13:38:27 +08:00
|
|
|
module_init(em28xx_module_init);
|
|
|
|
module_exit(em28xx_module_exit);
|