2005-11-09 05:37:07 +00:00
|
|
|
/*
|
2008-04-18 00:41:10 +00:00
|
|
|
em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB
|
|
|
|
video capture devices
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2005-11-09 05:38:25 +00:00
|
|
|
Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
|
|
|
|
Markus Rechberger <mrechberger@gmail.com>
|
2006-04-03 10:53:40 +00:00
|
|
|
Mauro Carvalho Chehab <mchehab@infradead.org>
|
2005-11-09 05:38:25 +00:00
|
|
|
Sascha Sommer <saschasommer@freenet.de>
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2006-01-23 19:10:54 +00:00
|
|
|
Some parts based on SN9C10x PC Camera Controllers GPL driver made
|
|
|
|
by Luca Risolia <luca.risolia@studio.unibo.it>
|
|
|
|
|
2005-11-09 05:37:07 +00: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-23 19:11:08 +00:00
|
|
|
#include <linux/bitmap.h>
|
2005-11-09 05:37:07 +00:00
|
|
|
#include <linux/usb.h>
|
|
|
|
#include <linux/i2c.h>
|
2005-11-09 05:38:37 +00:00
|
|
|
#include <linux/version.h>
|
2007-11-01 04:16:09 +00:00
|
|
|
#include <linux/mm.h>
|
2006-01-15 09:52:23 +00:00
|
|
|
#include <linux/mutex.h>
|
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h
percpu.h is included by sched.h and module.h and thus ends up being
included when building most .c files. percpu.h includes slab.h which
in turn includes gfp.h making everything defined by the two files
universally available and complicating inclusion dependencies.
percpu.h -> slab.h dependency is about to be removed. Prepare for
this change by updating users of gfp and slab facilities include those
headers directly instead of assuming availability. As this conversion
needs to touch large number of source files, the following script is
used as the basis of conversion.
http://userweb.kernel.org/~tj/misc/slabh-sweep.py
The script does the followings.
* Scan files for gfp and slab usages and update includes such that
only the necessary includes are there. ie. if only gfp is used,
gfp.h, if slab is used, slab.h.
* When the script inserts a new include, it looks at the include
blocks and try to put the new include such that its order conforms
to its surrounding. It's put in the include block which contains
core kernel includes, in the same order that the rest are ordered -
alphabetical, Christmas tree, rev-Xmas-tree or at the end if there
doesn't seem to be any matching order.
* If the script can't find a place to put a new include (mostly
because the file doesn't have fitting include block), it prints out
an error message indicating which .h file needs to be added to the
file.
The conversion was done in the following steps.
1. The initial automatic conversion of all .c files updated slightly
over 4000 files, deleting around 700 includes and adding ~480 gfp.h
and ~3000 slab.h inclusions. The script emitted errors for ~400
files.
2. Each error was manually checked. Some didn't need the inclusion,
some needed manual addition while adding it to implementation .h or
embedding .c file was more appropriate for others. This step added
inclusions to around 150 files.
3. The script was run again and the output was compared to the edits
from #2 to make sure no file was left behind.
4. Several build tests were done and a couple of problems were fixed.
e.g. lib/decompress_*.c used malloc/free() wrappers around slab
APIs requiring slab.h to be added manually.
5. The script was run on all .h files but without automatically
editing them as sprinkling gfp.h and slab.h inclusions around .h
files could easily lead to inclusion dependency hell. Most gfp.h
inclusion directives were ignored as stuff from gfp.h was usually
wildly available and often used in preprocessor macros. Each
slab.h inclusion directive was examined and added manually as
necessary.
6. percpu.h was updated not to include slab.h.
7. Build test were done on the following configurations and failures
were fixed. CONFIG_GCOV_KERNEL was turned off for all tests (as my
distributed build env didn't work with gcov compiles) and a few
more options had to be turned off depending on archs to make things
build (like ipr on powerpc/64 which failed due to missing writeq).
* x86 and x86_64 UP and SMP allmodconfig and a custom test config.
* powerpc and powerpc64 SMP allmodconfig
* sparc and sparc64 SMP allmodconfig
* ia64 SMP allmodconfig
* s390 SMP allmodconfig
* alpha SMP allmodconfig
* um on x86_64 SMP allmodconfig
8. percpu.h modifications were reverted so that it could be applied as
a separate patch and serve as bisection point.
Given the fact that I had only a couple of failures from tests on step
6, I'm fairly confident about the coverage of this conversion patch.
If there is a breakage, it's likely to be something in one of the arch
headers which should be easily discoverable easily on most builds of
the specific arch.
Signed-off-by: Tejun Heo <tj@kernel.org>
Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
2010-03-24 08:04:11 +00:00
|
|
|
#include <linux/slab.h>
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2005-11-09 05:38:25 +00:00
|
|
|
#include "em28xx.h"
|
2006-01-09 17:25:14 +00:00
|
|
|
#include <media/v4l2-common.h>
|
2008-07-20 11:12:02 +00:00
|
|
|
#include <media/v4l2-ioctl.h>
|
2008-12-22 23:58:41 +00:00
|
|
|
#include <media/v4l2-chip-ident.h>
|
2006-03-19 15:35:57 +00: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 09:59:20 +00:00
|
|
|
#include <media/tuner.h>
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2005-11-09 05:38:25 +00:00
|
|
|
#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
|
|
|
|
"Markus Rechberger <mrechberger@gmail.com>, " \
|
2006-04-03 10:53:40 +00:00
|
|
|
"Mauro Carvalho Chehab <mchehab@infradead.org>, " \
|
2005-11-09 05:38:25 +00:00
|
|
|
"Sascha Sommer <saschasommer@freenet.de>"
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2005-11-09 05:38:25 +00:00
|
|
|
#define DRIVER_DESC "Empia em28xx based USB video device driver"
|
2009-03-31 20:10:58 +00:00
|
|
|
#define EM28XX_VERSION_CODE KERNEL_VERSION(0, 1, 2)
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2005-11-09 05:38:27 +00:00
|
|
|
#define em28xx_videodbg(fmt, arg...) do {\
|
2005-11-09 05:37:43 +00:00
|
|
|
if (video_debug) \
|
|
|
|
printk(KERN_INFO "%s %s :"fmt, \
|
2008-04-09 02:20:00 +00:00
|
|
|
dev->name, __func__ , ##arg); } while (0)
|
2005-11-09 05:37:07 +00: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-13 17:37:52 +00:00
|
|
|
static unsigned int isoc_debug;
|
2008-04-13 17:41:23 +00: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-13 17:37:52 +00:00
|
|
|
|
2008-04-18 00:41:10 +00: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-13 17:37:52 +00:00
|
|
|
printk(KERN_INFO "%s %s :"fmt, \
|
2008-04-18 00:41:10 +00: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-13 17:37:52 +00:00
|
|
|
|
2005-11-09 05:37:07 +00:00
|
|
|
MODULE_AUTHOR(DRIVER_AUTHOR);
|
|
|
|
MODULE_DESCRIPTION(DRIVER_DESC);
|
|
|
|
MODULE_LICENSE("GPL");
|
|
|
|
|
2006-01-23 19:11:08 +00:00
|
|
|
static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
|
2008-01-05 20:22:01 +00:00
|
|
|
static unsigned int vbi_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
|
|
|
|
static unsigned int radio_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
|
|
|
|
|
2006-01-23 19:11:08 +00:00
|
|
|
module_param_array(video_nr, int, NULL, 0444);
|
|
|
|
module_param_array(vbi_nr, int, NULL, 0444);
|
2008-01-05 20:22:01 +00:00
|
|
|
module_param_array(radio_nr, int, NULL, 0444);
|
|
|
|
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 05:37:24 +00:00
|
|
|
|
2008-04-22 17:41:48 +00:00
|
|
|
static unsigned int video_debug;
|
2008-04-18 00:41:10 +00:00
|
|
|
module_param(video_debug, int, 0644);
|
|
|
|
MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2008-12-20 12:06:37 +00:00
|
|
|
/* supported video standards */
|
|
|
|
static struct em28xx_fmt format[] = {
|
|
|
|
{
|
2009-07-03 05:54:18 +00:00
|
|
|
.name = "16 bpp YUY2, 4:2:2, packed",
|
2008-12-20 12:06:37 +00:00
|
|
|
.fourcc = V4L2_PIX_FMT_YUYV,
|
|
|
|
.depth = 16,
|
2008-12-30 02:34:37 +00:00
|
|
|
.reg = EM28XX_OUTFMT_YUV422_Y0UY1V,
|
2009-06-30 11:36:17 +00:00
|
|
|
}, {
|
2009-07-03 05:54:18 +00:00
|
|
|
.name = "16 bpp RGB 565, LE",
|
2009-06-30 11:36:17 +00:00
|
|
|
.fourcc = V4L2_PIX_FMT_RGB565,
|
|
|
|
.depth = 16,
|
2009-07-03 05:54:18 +00:00
|
|
|
.reg = EM28XX_OUTFMT_RGB_16_656,
|
|
|
|
}, {
|
|
|
|
.name = "8 bpp Bayer BGBG..GRGR",
|
|
|
|
.fourcc = V4L2_PIX_FMT_SBGGR8,
|
|
|
|
.depth = 8,
|
|
|
|
.reg = EM28XX_OUTFMT_RGB_8_BGBG,
|
|
|
|
}, {
|
|
|
|
.name = "8 bpp Bayer GRGR..BGBG",
|
|
|
|
.fourcc = V4L2_PIX_FMT_SGRBG8,
|
|
|
|
.depth = 8,
|
|
|
|
.reg = EM28XX_OUTFMT_RGB_8_GRGR,
|
|
|
|
}, {
|
|
|
|
.name = "8 bpp Bayer GBGB..RGRG",
|
|
|
|
.fourcc = V4L2_PIX_FMT_SGBRG8,
|
|
|
|
.depth = 8,
|
|
|
|
.reg = EM28XX_OUTFMT_RGB_8_GBGB,
|
|
|
|
}, {
|
|
|
|
.name = "12 bpp YUV411",
|
|
|
|
.fourcc = V4L2_PIX_FMT_YUV411P,
|
|
|
|
.depth = 12,
|
|
|
|
.reg = EM28XX_OUTFMT_YUV411,
|
2008-12-20 12:06:37 +00:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2005-11-09 05:37:07 +00:00
|
|
|
/* supported controls */
|
2006-01-09 17:25:14 +00:00
|
|
|
/* Common to all boards */
|
2009-07-19 12:10:06 +00:00
|
|
|
static struct v4l2_queryctrl ac97_qctrl[] = {
|
2006-01-09 17:25:14 +00:00
|
|
|
{
|
|
|
|
.id = V4L2_CID_AUDIO_VOLUME,
|
|
|
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
|
|
.name = "Volume",
|
|
|
|
.minimum = 0x0,
|
|
|
|
.maximum = 0x1f,
|
|
|
|
.step = 0x1,
|
|
|
|
.default_value = 0x1f,
|
2009-07-19 13:45:49 +00:00
|
|
|
.flags = V4L2_CTRL_FLAG_SLIDER,
|
2008-04-18 00:41:10 +00:00
|
|
|
}, {
|
2006-01-09 17:25:14 +00:00
|
|
|
.id = V4L2_CID_AUDIO_MUTE,
|
|
|
|
.type = V4L2_CTRL_TYPE_BOOLEAN,
|
|
|
|
.name = "Mute",
|
|
|
|
.minimum = 0,
|
|
|
|
.maximum = 1,
|
|
|
|
.step = 1,
|
|
|
|
.default_value = 1,
|
|
|
|
.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-13 17:37:52 +00:00
|
|
|
/* ------------------------------------------------------------------
|
|
|
|
DMA and thread functions
|
|
|
|
------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Announces that a buffer were filled and request the next
|
|
|
|
*/
|
2008-04-13 17:41:23 +00: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-13 17:37:52 +00: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);
|
|
|
|
|
2009-09-01 04:54:54 +00:00
|
|
|
dev->isoc_ctl.vid_buf = NULL;
|
|
|
|
|
|
|
|
list_del(&buf->vb.queue);
|
|
|
|
wake_up(&buf->vb.done);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void vbi_buffer_filled(struct em28xx *dev,
|
|
|
|
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);
|
|
|
|
|
|
|
|
dev->isoc_ctl.vbi_buf = NULL;
|
2008-04-13 18:06:52 +00: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-13 17:37:52 +00: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-13 17:41:23 +00:00
|
|
|
int linesdone, currlinedone, offset, lencopy, remain;
|
2008-04-13 18:11:08 +00: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-13 17:37:52 +00:00
|
|
|
|
|
|
|
if (dma_q->pos + len > buf->vb.size)
|
|
|
|
len = buf->vb.size - dma_q->pos;
|
|
|
|
|
|
|
|
startread = p;
|
|
|
|
remain = len;
|
|
|
|
|
2009-08-08 06:14:55 +00:00
|
|
|
if (dev->progressive)
|
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-13 17:37:52 +00:00
|
|
|
fieldstart = outp;
|
2009-08-08 06:14:55 +00:00
|
|
|
else {
|
|
|
|
/* Interlaces two half frames */
|
|
|
|
if (buf->top_field)
|
|
|
|
fieldstart = outp;
|
|
|
|
else
|
|
|
|
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-13 17:37:52 +00:00
|
|
|
|
2008-04-13 18:11:08 +00:00
|
|
|
linesdone = dma_q->pos / bytesperline;
|
|
|
|
currlinedone = dma_q->pos % bytesperline;
|
2009-08-08 06:14:55 +00:00
|
|
|
|
|
|
|
if (dev->progressive)
|
|
|
|
offset = linesdone * bytesperline + currlinedone;
|
|
|
|
else
|
|
|
|
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-13 17:37:52 +00:00
|
|
|
startwrite = fieldstart + offset;
|
2008-04-13 18:11:08 +00: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-13 17:37:52 +00:00
|
|
|
lencopy = lencopy > remain ? remain : lencopy;
|
|
|
|
|
2008-04-13 17:41:23 +00:00
|
|
|
if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) {
|
2008-04-13 17:39:29 +00:00
|
|
|
em28xx_isocdbg("Overflow of %zi bytes past buffer end (1)\n",
|
2008-04-13 17:41:23 +00:00
|
|
|
((char *)startwrite + lencopy) -
|
|
|
|
((char *)outp + buf->vb.size));
|
2009-02-11 02:28:24 +00:00
|
|
|
remain = (char *)outp + buf->vb.size - (char *)startwrite;
|
|
|
|
lencopy = remain;
|
2008-04-13 17:38:47 +00:00
|
|
|
}
|
2008-04-13 17:56:02 +00:00
|
|
|
if (lencopy <= 0)
|
|
|
|
return;
|
2008-04-13 17:38:47 +00: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-13 17:37:52 +00:00
|
|
|
|
|
|
|
remain -= lencopy;
|
|
|
|
|
|
|
|
while (remain > 0) {
|
2008-04-13 18:11:08 +00: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-13 17:37:52 +00:00
|
|
|
startread += lencopy;
|
2008-04-13 18:11:08 +00: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-13 17:37:52 +00:00
|
|
|
lencopy = remain;
|
|
|
|
else
|
2008-04-13 18:11:08 +00: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-13 17:37:52 +00:00
|
|
|
|
2009-02-11 02:28:24 +00:00
|
|
|
if ((char *)startwrite + lencopy > (char *)outp +
|
|
|
|
buf->vb.size) {
|
2009-09-15 03:18:06 +00:00
|
|
|
em28xx_isocdbg("Overflow of %zi bytes past buffer end"
|
|
|
|
"(2)\n",
|
2008-04-13 17:41:23 +00:00
|
|
|
((char *)startwrite + lencopy) -
|
|
|
|
((char *)outp + buf->vb.size));
|
|
|
|
lencopy = remain = (char *)outp + buf->vb.size -
|
|
|
|
(char *)startwrite;
|
2008-04-13 17:38:47 +00:00
|
|
|
}
|
2008-04-13 17:41:23 +00:00
|
|
|
if (lencopy <= 0)
|
|
|
|
break;
|
2008-04-13 17:38:47 +00: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-13 17:37:52 +00:00
|
|
|
|
|
|
|
remain -= lencopy;
|
|
|
|
}
|
|
|
|
|
|
|
|
dma_q->pos += len;
|
|
|
|
}
|
|
|
|
|
2009-09-01 04:54:54 +00:00
|
|
|
static void em28xx_copy_vbi(struct em28xx *dev,
|
|
|
|
struct em28xx_dmaqueue *dma_q,
|
|
|
|
struct em28xx_buffer *buf,
|
|
|
|
unsigned char *p,
|
|
|
|
unsigned char *outp, unsigned long len)
|
|
|
|
{
|
|
|
|
void *startwrite, *startread;
|
|
|
|
int offset;
|
2009-11-25 02:17:25 +00:00
|
|
|
int bytesperline = dev->vbi_width;
|
2009-09-01 04:54:54 +00:00
|
|
|
|
|
|
|
if (dev == NULL) {
|
2009-09-15 03:18:06 +00:00
|
|
|
em28xx_isocdbg("dev is null\n");
|
2009-09-01 04:54:54 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dma_q == NULL) {
|
2009-09-15 03:18:06 +00:00
|
|
|
em28xx_isocdbg("dma_q is null\n");
|
2009-09-01 04:54:54 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (buf == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (p == NULL) {
|
2009-09-15 03:18:06 +00:00
|
|
|
em28xx_isocdbg("p is null\n");
|
2009-09-01 04:54:54 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (outp == NULL) {
|
2009-09-15 03:18:06 +00:00
|
|
|
em28xx_isocdbg("outp is null\n");
|
2009-09-01 04:54:54 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dma_q->pos + len > buf->vb.size)
|
|
|
|
len = buf->vb.size - dma_q->pos;
|
|
|
|
|
|
|
|
startread = p;
|
|
|
|
|
|
|
|
startwrite = outp + dma_q->pos;
|
|
|
|
offset = dma_q->pos;
|
|
|
|
|
|
|
|
/* Make sure the bottom field populates the second half of the frame */
|
|
|
|
if (buf->top_field == 0) {
|
2009-11-25 02:17:25 +00:00
|
|
|
startwrite += bytesperline * dev->vbi_height;
|
|
|
|
offset += bytesperline * dev->vbi_height;
|
2009-09-01 04:54:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(startwrite, startread, len);
|
|
|
|
dma_q->pos += len;
|
|
|
|
}
|
|
|
|
|
2008-04-13 17:41:23 +00: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-13 17:37:52 +00:00
|
|
|
int packet, int status)
|
|
|
|
{
|
|
|
|
char *errmsg = "Unknown";
|
|
|
|
|
2008-04-13 17:41:23 +00: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-13 17:37:52 +00: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-13 17:41:23 +00: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-13 17:37:52 +00: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-13 18:09:36 +00: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-13 17:37:52 +00:00
|
|
|
struct em28xx_buffer **buf)
|
|
|
|
{
|
|
|
|
struct em28xx *dev = container_of(dma_q, struct em28xx, vidq);
|
2008-04-13 18:08:55 +00: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-13 17:37:52 +00:00
|
|
|
|
2008-04-13 18:08:55 +00:00
|
|
|
if (list_empty(&dma_q->active)) {
|
|
|
|
em28xx_isocdbg("No active queue to serve\n");
|
2009-09-01 04:54:54 +00:00
|
|
|
dev->isoc_ctl.vid_buf = NULL;
|
2008-04-13 18:08:55 +00:00
|
|
|
*buf = NULL;
|
2008-04-13 18:09:36 +00:00
|
|
|
return;
|
2008-04-13 18:08:55 +00: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-13 18:06:52 +00:00
|
|
|
|
2009-09-01 04:54:54 +00:00
|
|
|
dev->isoc_ctl.vid_buf = *buf;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* video-buf generic routine to get the next available VBI buffer
|
|
|
|
*/
|
|
|
|
static inline void vbi_get_next_buf(struct em28xx_dmaqueue *dma_q,
|
|
|
|
struct em28xx_buffer **buf)
|
|
|
|
{
|
|
|
|
struct em28xx *dev = container_of(dma_q, struct em28xx, vbiq);
|
|
|
|
char *outp;
|
|
|
|
|
|
|
|
if (list_empty(&dma_q->active)) {
|
|
|
|
em28xx_isocdbg("No active queue to serve\n");
|
|
|
|
dev->isoc_ctl.vbi_buf = NULL;
|
|
|
|
*buf = NULL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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, 0x00, (*buf)->vb.size);
|
|
|
|
|
|
|
|
dev->isoc_ctl.vbi_buf = *buf;
|
2008-04-13 18:06:52 +00:00
|
|
|
|
2008-04-13 18:09:36 +00: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-13 17:37:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Controls the isoc copy of each urb packet
|
|
|
|
*/
|
2008-04-18 00:40:16 +00: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-13 17:37:52 +00:00
|
|
|
{
|
2008-04-13 17:38:47 +00:00
|
|
|
struct em28xx_buffer *buf;
|
2009-09-01 04:19:46 +00:00
|
|
|
struct em28xx_dmaqueue *dma_q = &dev->vidq;
|
2008-04-13 18:09:36 +00: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-13 17:37:52 +00:00
|
|
|
int i, len = 0, rc = 1;
|
2008-04-13 17:38:47 +00: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-13 17:37:52 +00:00
|
|
|
|
|
|
|
if (!dev)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
|
|
|
|
return 0;
|
|
|
|
|
2008-04-13 17:41:23 +00: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-13 17:37:52 +00:00
|
|
|
if (urb->status == -ENOENT)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-09-01 04:54:54 +00:00
|
|
|
buf = dev->isoc_ctl.vid_buf;
|
2008-04-13 18:09:36 +00:00
|
|
|
if (buf != NULL)
|
|
|
|
outp = videobuf_to_vmalloc(&buf->vb);
|
2008-04-13 17:38:47 +00: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-13 17:37:52 +00:00
|
|
|
for (i = 0; i < urb->number_of_packets; i++) {
|
|
|
|
int status = urb->iso_frame_desc[i].status;
|
|
|
|
|
2008-04-13 17:41:23 +00: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-13 17:37:52 +00:00
|
|
|
if (urb->iso_frame_desc[i].status != -EPROTO)
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2008-04-13 17:41:23 +00: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-13 17:37:52 +00:00
|
|
|
|
|
|
|
if (urb->iso_frame_desc[i].actual_length <= 0) {
|
2008-04-13 17:38:47 +00: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-13 17:37:52 +00: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-13 18:09:14 +00:00
|
|
|
if (p[0] == 0x33 && p[1] == 0x95 && p[2] == 0x00) {
|
|
|
|
em28xx_isocdbg("VBI HEADER!!!\n");
|
|
|
|
/* FIXME: Should add vbi copy */
|
|
|
|
continue;
|
|
|
|
}
|
2008-04-13 17:38:47 +00:00
|
|
|
if (p[0] == 0x22 && p[1] == 0x5a) {
|
2008-04-13 17:56:25 +00:00
|
|
|
em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2],
|
2009-02-11 02:28:24 +00:00
|
|
|
len, (p[2] & 1) ? "odd" : "even");
|
2008-04-13 17:38:47 +00:00
|
|
|
|
2009-08-08 06:14:55 +00:00
|
|
|
if (dev->progressive || !(p[2] & 1)) {
|
2008-04-13 18:09:36 +00:00
|
|
|
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-13 17:56:02 +00:00
|
|
|
}
|
2008-04-13 18:09:14 +00: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-13 17:37:52 +00:00
|
|
|
dma_q->pos = 0;
|
|
|
|
}
|
2010-01-22 05:34:32 +00:00
|
|
|
if (buf != NULL) {
|
|
|
|
if (p[0] != 0x88 && p[0] != 0x22) {
|
|
|
|
em28xx_isocdbg("frame is not complete\n");
|
|
|
|
len += 4;
|
|
|
|
} else {
|
|
|
|
p += 4;
|
|
|
|
}
|
2008-04-13 18:09:36 +00:00
|
|
|
em28xx_copy_video(dev, dma_q, buf, p, outp, len);
|
2010-01-22 05:34:32 +00: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-13 17:37:52 +00:00
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2009-09-01 04:19:46 +00:00
|
|
|
/* Version of isoc handler that takes into account a mixture of video and
|
|
|
|
VBI data */
|
|
|
|
static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
|
|
|
|
{
|
|
|
|
struct em28xx_buffer *buf, *vbi_buf;
|
|
|
|
struct em28xx_dmaqueue *dma_q = &dev->vidq;
|
2009-09-01 04:54:54 +00:00
|
|
|
struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq;
|
2009-09-01 04:19:46 +00:00
|
|
|
unsigned char *outp = NULL;
|
|
|
|
unsigned char *vbioutp = NULL;
|
|
|
|
int i, len = 0, rc = 1;
|
|
|
|
unsigned char *p;
|
|
|
|
int vbi_size;
|
|
|
|
|
|
|
|
if (!dev)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (urb->status < 0) {
|
|
|
|
print_err_status(dev, -1, urb->status);
|
|
|
|
if (urb->status == -ENOENT)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-09-01 04:54:54 +00:00
|
|
|
buf = dev->isoc_ctl.vid_buf;
|
2009-09-01 04:19:46 +00:00
|
|
|
if (buf != NULL)
|
|
|
|
outp = videobuf_to_vmalloc(&buf->vb);
|
2009-09-01 04:54:54 +00:00
|
|
|
|
|
|
|
vbi_buf = dev->isoc_ctl.vbi_buf;
|
|
|
|
if (vbi_buf != NULL)
|
|
|
|
vbioutp = videobuf_to_vmalloc(&vbi_buf->vb);
|
|
|
|
|
2009-09-01 04:19:46 +00:00
|
|
|
for (i = 0; i < urb->number_of_packets; i++) {
|
|
|
|
int status = urb->iso_frame_desc[i].status;
|
|
|
|
|
|
|
|
if (status < 0) {
|
|
|
|
print_err_status(dev, i, status);
|
|
|
|
if (urb->iso_frame_desc[i].status != -EPROTO)
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2010-01-22 05:34:32 +00:00
|
|
|
len = urb->iso_frame_desc[i].actual_length;
|
2009-09-01 04:19:46 +00:00
|
|
|
if (urb->iso_frame_desc[i].actual_length <= 0) {
|
|
|
|
/* em28xx_isocdbg("packet %d is empty",i); - spammy */
|
|
|
|
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;
|
|
|
|
|
|
|
|
/* capture type 0 = vbi start
|
|
|
|
capture type 1 = video start
|
|
|
|
capture type 2 = video in progress */
|
|
|
|
if (p[0] == 0x33 && p[1] == 0x95) {
|
|
|
|
dev->capture_type = 0;
|
|
|
|
dev->vbi_read = 0;
|
|
|
|
em28xx_isocdbg("VBI START HEADER!!!\n");
|
|
|
|
dev->cur_field = p[2];
|
2010-01-22 05:34:32 +00:00
|
|
|
p += 4;
|
|
|
|
len -= 4;
|
|
|
|
} else if (p[0] == 0x88 && p[1] == 0x88 &&
|
|
|
|
p[2] == 0x88 && p[3] == 0x88) {
|
|
|
|
/* continuation */
|
|
|
|
p += 4;
|
|
|
|
len -= 4;
|
|
|
|
} else if (p[0] == 0x22 && p[1] == 0x5a) {
|
|
|
|
/* start video */
|
|
|
|
p += 4;
|
|
|
|
len -= 4;
|
2009-09-01 04:19:46 +00:00
|
|
|
}
|
|
|
|
|
2009-11-25 02:17:25 +00:00
|
|
|
vbi_size = dev->vbi_width * dev->vbi_height;
|
2009-09-01 04:19:46 +00:00
|
|
|
|
|
|
|
if (dev->capture_type == 0) {
|
|
|
|
if (dev->vbi_read >= vbi_size) {
|
|
|
|
/* We've already read all the VBI data, so
|
|
|
|
treat the rest as video */
|
2009-09-15 03:18:06 +00:00
|
|
|
em28xx_isocdbg("dev->vbi_read > vbi_size\n");
|
2009-09-01 04:19:46 +00:00
|
|
|
} else if ((dev->vbi_read + len) < vbi_size) {
|
|
|
|
/* This entire frame is VBI data */
|
2009-09-01 04:54:54 +00:00
|
|
|
if (dev->vbi_read == 0 &&
|
|
|
|
(!(dev->cur_field & 1))) {
|
|
|
|
/* Brand new frame */
|
|
|
|
if (vbi_buf != NULL)
|
|
|
|
vbi_buffer_filled(dev,
|
|
|
|
vbi_dma_q,
|
|
|
|
vbi_buf);
|
|
|
|
vbi_get_next_buf(vbi_dma_q, &vbi_buf);
|
|
|
|
if (vbi_buf == NULL)
|
|
|
|
vbioutp = NULL;
|
2009-09-15 03:18:06 +00:00
|
|
|
else
|
|
|
|
vbioutp = videobuf_to_vmalloc(
|
|
|
|
&vbi_buf->vb);
|
2009-09-01 04:54:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (dev->vbi_read == 0) {
|
|
|
|
vbi_dma_q->pos = 0;
|
|
|
|
if (vbi_buf != NULL) {
|
|
|
|
if (dev->cur_field & 1)
|
|
|
|
vbi_buf->top_field = 0;
|
|
|
|
else
|
|
|
|
vbi_buf->top_field = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-01 04:19:46 +00:00
|
|
|
dev->vbi_read += len;
|
2009-09-01 04:54:54 +00:00
|
|
|
em28xx_copy_vbi(dev, vbi_dma_q, vbi_buf, p,
|
|
|
|
vbioutp, len);
|
2009-09-01 04:19:46 +00:00
|
|
|
} else {
|
|
|
|
/* Some of this frame is VBI data and some is
|
|
|
|
video data */
|
|
|
|
int vbi_data_len = vbi_size - dev->vbi_read;
|
|
|
|
dev->vbi_read += vbi_data_len;
|
2009-09-01 04:54:54 +00:00
|
|
|
em28xx_copy_vbi(dev, vbi_dma_q, vbi_buf, p,
|
|
|
|
vbioutp, vbi_data_len);
|
2009-09-01 04:19:46 +00:00
|
|
|
dev->capture_type = 1;
|
|
|
|
p += vbi_data_len;
|
|
|
|
len -= vbi_data_len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dev->capture_type == 1) {
|
|
|
|
dev->capture_type = 2;
|
|
|
|
if (dev->progressive || !(dev->cur_field & 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 (dev->cur_field & 1)
|
|
|
|
buf->top_field = 0;
|
|
|
|
else
|
|
|
|
buf->top_field = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
dma_q->pos = 0;
|
|
|
|
}
|
2010-01-22 05:34:32 +00:00
|
|
|
|
|
|
|
if (buf != NULL && dev->capture_type == 2) {
|
|
|
|
if (len > 4 && p[0] == 0x88 && p[1] == 0x88 &&
|
|
|
|
p[2] == 0x88 && p[3] == 0x88) {
|
|
|
|
p += 4;
|
|
|
|
len -= 4;
|
|
|
|
}
|
|
|
|
if (len > 4 && p[0] == 0x22 && p[1] == 0x5a) {
|
|
|
|
em28xx_isocdbg("Video frame %d, len=%i, %s\n",
|
|
|
|
p[2], len, (p[2] & 1) ?
|
|
|
|
"odd" : "even");
|
|
|
|
p += 4;
|
|
|
|
len -= 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (len > 0)
|
|
|
|
em28xx_copy_video(dev, dma_q, buf, p, outp,
|
|
|
|
len);
|
|
|
|
}
|
2009-09-01 04:19:46 +00:00
|
|
|
}
|
|
|
|
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-13 17:37:52 +00:00
|
|
|
/* ------------------------------------------------------------------
|
|
|
|
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 00:38:53 +00: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-13 17:37:52 +00:00
|
|
|
|
2009-09-15 03:18:06 +00:00
|
|
|
*size = (fh->dev->width * fh->dev->height * dev->format->depth + 7)
|
|
|
|
>> 3;
|
2008-12-20 12:06:37 +00: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-13 17:37:52 +00:00
|
|
|
if (0 == *count)
|
|
|
|
*count = EM28XX_DEF_BUF;
|
|
|
|
|
2008-04-13 17:41:23 +00: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-13 17:37:52 +00:00
|
|
|
|
2008-12-20 10:43:34 +00:00
|
|
|
/* Ask tuner to go to analog or radio mode */
|
2008-04-18 00:41:10 +00:00
|
|
|
memset(&f, 0, sizeof(f));
|
2008-04-18 00:38:53 +00:00
|
|
|
f.frequency = dev->ctl_freq;
|
2008-12-20 10:43:34 +00:00
|
|
|
f.type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
|
2008-04-18 00:38:53 +00:00
|
|
|
|
2009-03-31 20:10:58 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
|
2008-04-18 00:38:53 +00: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-13 17:37:52 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-04-13 18:09:36 +00: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-13 17:37:52 +00:00
|
|
|
static void free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf)
|
|
|
|
{
|
2008-04-13 18:09:36 +00: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-13 17:37:52 +00:00
|
|
|
if (in_interrupt())
|
|
|
|
BUG();
|
|
|
|
|
2008-04-13 18:09:36 +00: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);
|
2009-09-01 04:54:54 +00:00
|
|
|
if (dev->isoc_ctl.vid_buf == buf)
|
|
|
|
dev->isoc_ctl.vid_buf = NULL;
|
2008-04-13 18:09:36 +00:00
|
|
|
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-13 17:37:52 +00: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-13 17:41:23 +00: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-13 17:37:52 +00:00
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc = 0, urb_init = 0;
|
|
|
|
|
2009-09-15 03:18:06 +00:00
|
|
|
buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth
|
|
|
|
+ 7) >> 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-13 17:37:52 +00:00
|
|
|
|
|
|
|
if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2008-04-13 17:57:01 +00: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-13 17:37:52 +00:00
|
|
|
|
|
|
|
if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
|
2008-04-13 17:38:47 +00: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-13 17:37:52 +00:00
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!dev->isoc_ctl.num_bufs)
|
2008-04-13 17:41:23 +00: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-13 17:37:52 +00:00
|
|
|
|
|
|
|
if (urb_init) {
|
2009-09-01 04:19:46 +00:00
|
|
|
if (em28xx_vbi_supported(dev) == 1)
|
|
|
|
rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS,
|
|
|
|
EM28XX_NUM_BUFS,
|
|
|
|
dev->max_pkt_size,
|
|
|
|
em28xx_isoc_copy_vbi);
|
|
|
|
else
|
|
|
|
rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS,
|
|
|
|
EM28XX_NUM_BUFS,
|
|
|
|
dev->max_pkt_size,
|
|
|
|
em28xx_isoc_copy);
|
2008-04-13 17:41:23 +00: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-13 17:37:52 +00:00
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
buf->vb.state = VIDEOBUF_PREPARED;
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
fail:
|
2008-04-13 17:41:23 +00: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-13 17:37:52 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
|
|
|
|
{
|
2009-02-11 02:28:24 +00: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-13 17:37:52 +00:00
|
|
|
struct em28xx_fh *fh = vq->priv_data;
|
2008-04-13 17:41:23 +00: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-13 17:37:52 +00:00
|
|
|
struct em28xx_dmaqueue *vidq = &dev->vidq;
|
|
|
|
|
2008-04-13 17:38:47 +00: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-13 17:37:52 +00:00
|
|
|
}
|
|
|
|
|
2008-04-18 00:41:10 +00: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-13 17:37:52 +00:00
|
|
|
{
|
2009-02-11 02:28:24 +00: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-13 17:37:52 +00:00
|
|
|
struct em28xx_fh *fh = vq->priv_data;
|
2008-04-13 17:41:23 +00: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-13 17:37:52 +00:00
|
|
|
|
2008-04-13 17:38:47 +00: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-13 17:37:52 +00:00
|
|
|
|
2008-04-13 17:41:23 +00: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-13 17:37:52 +00: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 05:37:07 +00:00
|
|
|
|
2008-04-18 00:41:10 +00:00
|
|
|
/********************* v4l2 interface **************************************/
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2005-11-09 05:38:43 +00:00
|
|
|
static void video_mux(struct em28xx *dev, int index)
|
|
|
|
{
|
|
|
|
dev->ctl_input = index;
|
|
|
|
dev->ctl_ainput = INPUT(index)->amux;
|
2008-11-20 15:40:51 +00:00
|
|
|
dev->ctl_aoutput = INPUT(index)->aout;
|
2005-11-09 05:38:43 +00:00
|
|
|
|
2008-11-20 16:39:39 +00:00
|
|
|
if (!dev->ctl_aoutput)
|
|
|
|
dev->ctl_aoutput = EM28XX_AOUT_MASTER;
|
|
|
|
|
2009-04-02 14:26:22 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
|
|
|
|
INPUT(index)->vmux, 0, 0);
|
2005-11-09 05:38:43 +00:00
|
|
|
|
2008-11-25 12:39:50 +00:00
|
|
|
if (dev->board.has_msp34xx) {
|
2008-04-18 00:41:10 +00:00
|
|
|
if (dev->i2s_speed) {
|
2009-03-31 20:10:58 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, audio,
|
|
|
|
s_i2s_clock_freq, dev->i2s_speed);
|
2008-04-18 00:41:10 +00:00
|
|
|
}
|
2006-03-19 15:35:57 +00:00
|
|
|
/* Note: this is msp3400 specific */
|
2009-04-02 14:26:22 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
|
|
|
|
dev->ctl_ainput, MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0);
|
2005-11-09 05:38:43 +00:00
|
|
|
}
|
2008-01-05 12:53:54 +00:00
|
|
|
|
2009-03-04 11:27:52 +00:00
|
|
|
if (dev->board.adecoder != EM28XX_NOADECODER) {
|
2009-04-02 14:26:22 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
|
|
|
|
dev->ctl_ainput, dev->ctl_aoutput, 0);
|
2009-03-04 11:27:52 +00:00
|
|
|
}
|
|
|
|
|
2008-02-06 21:34:13 +00:00
|
|
|
em28xx_audio_analog_set(dev);
|
2005-11-09 05:38:43 +00:00
|
|
|
}
|
|
|
|
|
2007-11-11 04:08:26 +00:00
|
|
|
/* Usage lock check functions */
|
2009-09-03 03:23:27 +00:00
|
|
|
static int res_get(struct em28xx_fh *fh, unsigned int bit)
|
2007-11-11 04:08:26 +00:00
|
|
|
{
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
|
2009-09-03 03:23:27 +00:00
|
|
|
if (fh->resources & bit)
|
|
|
|
/* have it already allocated */
|
|
|
|
return 1;
|
2007-11-11 04:08:26 +00:00
|
|
|
|
2009-09-03 03:23:27 +00:00
|
|
|
/* is it free? */
|
|
|
|
mutex_lock(&dev->lock);
|
|
|
|
if (dev->resources & bit) {
|
|
|
|
/* no, someone else uses it */
|
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* it's free, grab it */
|
|
|
|
fh->resources |= bit;
|
|
|
|
dev->resources |= bit;
|
|
|
|
em28xx_videodbg("res: get %d\n", bit);
|
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
return 1;
|
|
|
|
}
|
2007-11-11 04:08:26 +00:00
|
|
|
|
2009-09-03 03:23:27 +00:00
|
|
|
static int res_check(struct em28xx_fh *fh, unsigned int bit)
|
|
|
|
{
|
2009-09-15 03:18:06 +00:00
|
|
|
return fh->resources & bit;
|
2007-11-11 04:08:26 +00:00
|
|
|
}
|
|
|
|
|
2009-09-03 03:23:27 +00:00
|
|
|
static int res_locked(struct em28xx *dev, unsigned int bit)
|
2007-11-11 04:08:26 +00:00
|
|
|
{
|
2009-09-15 03:18:06 +00:00
|
|
|
return dev->resources & bit;
|
2007-11-11 04:08:26 +00:00
|
|
|
}
|
|
|
|
|
2009-09-03 03:23:27 +00:00
|
|
|
static void res_free(struct em28xx_fh *fh, unsigned int bits)
|
2007-11-11 04:08:26 +00:00
|
|
|
{
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
|
2009-09-03 03:23:27 +00:00
|
|
|
BUG_ON((fh->resources & bits) != bits);
|
|
|
|
|
|
|
|
mutex_lock(&dev->lock);
|
|
|
|
fh->resources &= ~bits;
|
|
|
|
dev->resources &= ~bits;
|
|
|
|
em28xx_videodbg("res: put %d\n", bits);
|
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int get_ressource(struct em28xx_fh *fh)
|
|
|
|
{
|
|
|
|
switch (fh->type) {
|
|
|
|
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
|
|
|
|
return EM28XX_RESOURCE_VIDEO;
|
|
|
|
case V4L2_BUF_TYPE_VBI_CAPTURE:
|
|
|
|
return EM28XX_RESOURCE_VBI;
|
|
|
|
default:
|
|
|
|
BUG();
|
|
|
|
return 0;
|
|
|
|
}
|
2007-11-11 04:08:26 +00:00
|
|
|
}
|
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
/*
|
2009-07-19 13:45:49 +00:00
|
|
|
* ac97_queryctrl()
|
|
|
|
* return the ac97 supported controls
|
|
|
|
*/
|
|
|
|
static int ac97_queryctrl(struct v4l2_queryctrl *qc)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++) {
|
|
|
|
if (qc->id && qc->id == ac97_qctrl[i].id) {
|
|
|
|
memcpy(qc, &(ac97_qctrl[i]), sizeof(*qc));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Control is not ac97 related */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ac97_get_ctrl()
|
|
|
|
* return the current values for ac97 mute and volume
|
2007-11-11 16:17:17 +00:00
|
|
|
*/
|
2009-07-19 13:45:49 +00:00
|
|
|
static int ac97_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
|
2007-11-11 16:17:17 +00:00
|
|
|
{
|
|
|
|
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:
|
2009-07-19 13:45:49 +00:00
|
|
|
/* Control is not ac97 related */
|
|
|
|
return 1;
|
2005-11-09 05:37:07 +00:00
|
|
|
}
|
2007-11-11 16:17:17 +00:00
|
|
|
}
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
/*
|
2009-07-19 13:45:49 +00:00
|
|
|
* ac97_set_ctrl()
|
|
|
|
* set values for ac97 mute and volume
|
2007-11-11 16:17:17 +00:00
|
|
|
*/
|
2009-07-19 13:45:49 +00:00
|
|
|
static int ac97_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl)
|
2007-11-11 16:17:17 +00:00
|
|
|
{
|
2009-07-19 13:45:49 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++)
|
|
|
|
if (ctrl->id == ac97_qctrl[i].id)
|
|
|
|
goto handle;
|
|
|
|
|
|
|
|
/* Announce that hasn't handle it */
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
handle:
|
|
|
|
if (ctrl->value < ac97_qctrl[i].minimum ||
|
|
|
|
ctrl->value > ac97_qctrl[i].maximum)
|
|
|
|
return -ERANGE;
|
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
switch (ctrl->id) {
|
|
|
|
case V4L2_CID_AUDIO_MUTE:
|
2009-07-19 13:45:49 +00:00
|
|
|
dev->mute = ctrl->value;
|
|
|
|
break;
|
2007-11-11 16:17:17 +00:00
|
|
|
case V4L2_CID_AUDIO_VOLUME:
|
|
|
|
dev->volume = ctrl->value;
|
2009-07-19 13:45:49 +00:00
|
|
|
break;
|
2007-11-11 16:17:17 +00:00
|
|
|
}
|
2009-07-19 13:45:49 +00:00
|
|
|
|
|
|
|
return em28xx_audio_analog_set(dev);
|
2007-11-11 16:17:17 +00:00
|
|
|
}
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00: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-23 19:11:08 +00:00
|
|
|
}
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00: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 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
static void get_scale(struct em28xx *dev,
|
|
|
|
unsigned int width, unsigned int height,
|
|
|
|
unsigned int *hscale, unsigned int *vscale)
|
|
|
|
{
|
2009-07-13 23:15:02 +00:00
|
|
|
unsigned int maxw = norm_maxw(dev);
|
|
|
|
unsigned int maxh = norm_maxh(dev);
|
2007-11-11 16:17:17 +00:00
|
|
|
|
|
|
|
*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 05:37:07 +00:00
|
|
|
}
|
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
/* ------------------------------------------------------------------
|
|
|
|
IOCTL vidioc handling
|
|
|
|
------------------------------------------------------------------*/
|
|
|
|
|
2008-05-28 15:16:41 +00:00
|
|
|
static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
|
2007-11-11 16:17:17 +00:00
|
|
|
struct v4l2_format *f)
|
2005-11-09 05:37:07 +00:00
|
|
|
{
|
2007-11-11 16:17:17 +00:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
mutex_lock(&dev->lock);
|
2006-01-23 19:11:08 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
f->fmt.pix.width = dev->width;
|
|
|
|
f->fmt.pix.height = dev->height;
|
2008-12-20 12:06:37 +00:00
|
|
|
f->fmt.pix.pixelformat = dev->format->fourcc;
|
|
|
|
f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;
|
2008-04-13 18:11:08 +00:00
|
|
|
f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height;
|
2007-11-11 16:17:17 +00:00
|
|
|
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
|
2006-01-23 19:11:08 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
/* FIXME: TOP? NONE? BOTTOM? ALTENATE? */
|
2009-08-08 06:14:55 +00:00
|
|
|
if (dev->progressive)
|
|
|
|
f->fmt.pix.field = V4L2_FIELD_NONE;
|
|
|
|
else
|
|
|
|
f->fmt.pix.field = dev->interlaced ?
|
2007-11-11 16:17:17 +00:00
|
|
|
V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
|
2006-01-23 19:11:08 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
return 0;
|
2005-11-09 05:37:07 +00:00
|
|
|
}
|
|
|
|
|
2008-12-20 12:06:37 +00:00
|
|
|
static struct em28xx_fmt *format_by_fourcc(unsigned int fourcc)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(format); i++)
|
|
|
|
if (format[i].fourcc == fourcc)
|
|
|
|
return &format[i];
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2008-05-28 15:16:41 +00:00
|
|
|
static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
|
2007-11-11 16:17:17 +00:00
|
|
|
struct v4l2_format *f)
|
2005-11-09 05:37:07 +00:00
|
|
|
{
|
2007-11-11 16:17:17 +00:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
2009-05-31 00:45:46 +00:00
|
|
|
unsigned int width = f->fmt.pix.width;
|
|
|
|
unsigned int height = f->fmt.pix.height;
|
2007-11-11 16:17:17 +00:00
|
|
|
unsigned int maxw = norm_maxw(dev);
|
|
|
|
unsigned int maxh = norm_maxh(dev);
|
|
|
|
unsigned int hscale, vscale;
|
2008-12-20 12:06:37 +00:00
|
|
|
struct em28xx_fmt *fmt;
|
|
|
|
|
|
|
|
fmt = format_by_fourcc(f->fmt.pix.pixelformat);
|
|
|
|
if (!fmt) {
|
|
|
|
em28xx_videodbg("Fourcc format (%08x) invalid.\n",
|
|
|
|
f->fmt.pix.pixelformat);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2007-11-11 16:17:17 +00:00
|
|
|
|
2009-07-13 23:15:02 +00:00
|
|
|
if (dev->board.is_em2800) {
|
2007-11-11 16:17:17 +00:00
|
|
|
/* the em2800 can only scale down to 50% */
|
2009-05-31 00:45:46 +00:00
|
|
|
height = height > (3 * maxh / 4) ? maxh : maxh / 2;
|
|
|
|
width = width > (3 * maxw / 4) ? maxw : maxw / 2;
|
|
|
|
} else {
|
|
|
|
/* width must even because of the YUYV format
|
|
|
|
height must be even because of interlacing */
|
2009-09-15 03:18:06 +00:00
|
|
|
v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh,
|
|
|
|
1, 0);
|
2007-11-11 16:17:17 +00:00
|
|
|
}
|
2007-11-11 04:08:26 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
get_scale(dev, width, height, &hscale, &vscale);
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
width = (((unsigned long)maxw) << 12) / (hscale + 4096L);
|
|
|
|
height = (((unsigned long)maxh) << 12) / (vscale + 4096L);
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
f->fmt.pix.width = width;
|
|
|
|
f->fmt.pix.height = height;
|
2008-12-20 12:06:37 +00:00
|
|
|
f->fmt.pix.pixelformat = fmt->fourcc;
|
|
|
|
f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3;
|
|
|
|
f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height;
|
2007-11-11 16:17:17 +00:00
|
|
|
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
|
2009-08-08 06:14:55 +00:00
|
|
|
if (dev->progressive)
|
|
|
|
f->fmt.pix.field = V4L2_FIELD_NONE;
|
|
|
|
else
|
|
|
|
f->fmt.pix.field = dev->interlaced ?
|
|
|
|
V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
|
2005-11-09 05:37:07 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-07-02 20:34:04 +00:00
|
|
|
static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc,
|
|
|
|
unsigned width, unsigned height)
|
|
|
|
{
|
|
|
|
struct em28xx_fmt *fmt;
|
|
|
|
|
|
|
|
fmt = format_by_fourcc(fourcc);
|
|
|
|
if (!fmt)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
dev->format = fmt;
|
|
|
|
dev->width = width;
|
|
|
|
dev->height = height;
|
|
|
|
|
|
|
|
/* set new image size */
|
|
|
|
get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
|
|
|
|
|
|
|
|
em28xx_set_alternate(dev);
|
|
|
|
em28xx_resolution_set(dev);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-05-28 15:16:41 +00:00
|
|
|
static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
|
2007-11-11 16:17:17 +00:00
|
|
|
struct v4l2_format *f)
|
2005-11-09 05:37:07 +00:00
|
|
|
{
|
2007-11-11 16:17:17 +00: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-13 17:37:52 +00:00
|
|
|
int rc;
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
2007-11-11 04:08:26 +00:00
|
|
|
|
2007-11-04 00:22:38 +00:00
|
|
|
mutex_lock(&dev->lock);
|
|
|
|
|
2008-12-17 01:04:56 +00:00
|
|
|
vidioc_try_fmt_vid_cap(file, priv, f);
|
|
|
|
|
2008-04-13 17:57:01 +00:00
|
|
|
if (videobuf_queue_is_busy(&fh->vb_vidq)) {
|
|
|
|
em28xx_errdev("%s queue busy\n", __func__);
|
|
|
|
rc = -EBUSY;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2009-07-02 20:34:04 +00:00
|
|
|
rc = em28xx_set_video_format(dev, f->fmt.pix.pixelformat,
|
|
|
|
f->fmt.pix.width, f->fmt.pix.height);
|
2008-04-13 17:57:01 +00:00
|
|
|
|
|
|
|
out:
|
2007-11-11 16:17:17 +00:00
|
|
|
mutex_unlock(&dev->lock);
|
2008-04-13 17:57:01 +00:00
|
|
|
return rc;
|
2007-11-11 16:17:17 +00:00
|
|
|
}
|
|
|
|
|
2009-09-11 03:40:18 +00:00
|
|
|
static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
*norm = dev->norm;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-02-11 02:28:24 +00:00
|
|
|
static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
|
2007-11-11 16:17:17 +00: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-11 17:15:34 +00:00
|
|
|
dev->norm = *norm;
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
/* Adjusts width/height, if needed */
|
|
|
|
f.fmt.pix.width = dev->width;
|
|
|
|
f.fmt.pix.height = dev->height;
|
2008-05-28 15:16:41 +00:00
|
|
|
vidioc_try_fmt_vid_cap(file, priv, &f);
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00: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 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
em28xx_resolution_set(dev);
|
2009-04-01 06:52:39 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
return 0;
|
|
|
|
}
|
2007-11-11 04:13:49 +00:00
|
|
|
|
2009-08-07 00:53:59 +00:00
|
|
|
static int vidioc_g_parm(struct file *file, void *priv,
|
|
|
|
struct v4l2_streamparm *p)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
if (dev->board.is_webcam)
|
|
|
|
rc = v4l2_device_call_until_err(&dev->v4l2_dev, 0,
|
|
|
|
video, g_parm, p);
|
|
|
|
else
|
|
|
|
v4l2_video_std_frame_period(dev->norm,
|
|
|
|
&p->parm.capture.timeperframe);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vidioc_s_parm(struct file *file, void *priv,
|
|
|
|
struct v4l2_streamparm *p)
|
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
|
|
|
|
if (!dev->board.is_webcam)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
return v4l2_device_call_until_err(&dev->v4l2_dev, 0, video, s_parm, p);
|
|
|
|
}
|
|
|
|
|
2007-11-11 16:17:17 +00: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 04:13:49 +00:00
|
|
|
|
2007-11-11 16:17:17 +00: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 04:13:49 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
n = i->index;
|
|
|
|
if (n >= MAX_EM28XX_INPUT)
|
|
|
|
return -EINVAL;
|
|
|
|
if (0 == INPUT(n)->type)
|
|
|
|
return -EINVAL;
|
2007-11-11 04:13:49 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
i->index = n;
|
|
|
|
i->type = V4L2_INPUT_TYPE_CAMERA;
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
strcpy(i->name, iname[INPUT(n)->type]);
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) ||
|
|
|
|
(EM28XX_VMUX_CABLE == INPUT(n)->type))
|
|
|
|
i->type = V4L2_INPUT_TYPE_TUNER;
|
|
|
|
|
2007-11-11 17:15:34 +00:00
|
|
|
i->std = dev->vdev->tvnorms;
|
2007-11-11 16:17:17 +00:00
|
|
|
|
|
|
|
return 0;
|
2005-11-09 05:37:07 +00:00
|
|
|
}
|
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
|
2005-11-09 05:37:07 +00:00
|
|
|
{
|
2007-11-11 16:17:17 +00:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00: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 04:08:26 +00:00
|
|
|
|
2009-01-08 01:49:25 +00:00
|
|
|
dev->ctl_input = i;
|
2007-11-11 16:17:17 +00:00
|
|
|
|
2009-01-08 01:49:25 +00:00
|
|
|
mutex_lock(&dev->lock);
|
|
|
|
video_mux(dev, dev->ctl_input);
|
2007-11-11 16:17:17 +00:00
|
|
|
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;
|
|
|
|
|
2009-08-04 22:52:37 +00:00
|
|
|
if (!dev->audio_mode.has_audio)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2008-11-20 15:40:51 +00:00
|
|
|
switch (a->index) {
|
|
|
|
case EM28XX_AMUX_VIDEO:
|
2007-11-11 16:17:17 +00:00
|
|
|
strcpy(a->name, "Television");
|
2008-11-20 15:40:51 +00:00
|
|
|
break;
|
|
|
|
case EM28XX_AMUX_LINE_IN:
|
2007-11-11 16:17:17 +00:00
|
|
|
strcpy(a->name, "Line In");
|
2008-11-20 15:40:51 +00: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 00:41:10 +00:00
|
|
|
|
2008-11-20 15:40:51 +00:00
|
|
|
a->index = dev->ctl_ainput;
|
2007-11-11 16:17:17 +00: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;
|
|
|
|
|
2009-01-08 01:49:25 +00:00
|
|
|
|
2009-08-04 22:52:37 +00:00
|
|
|
if (!dev->audio_mode.has_audio)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2009-01-08 01:49:25 +00:00
|
|
|
if (a->index >= MAX_EM28XX_INPUT)
|
|
|
|
return -EINVAL;
|
|
|
|
if (0 == INPUT(a->index)->type)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2008-12-17 01:04:56 +00:00
|
|
|
mutex_lock(&dev->lock);
|
|
|
|
|
2008-11-20 15:40:51 +00:00
|
|
|
dev->ctl_ainput = INPUT(a->index)->amux;
|
|
|
|
dev->ctl_aoutput = INPUT(a->index)->aout;
|
2008-11-20 16:39:39 +00:00
|
|
|
|
|
|
|
if (!dev->ctl_aoutput)
|
|
|
|
dev->ctl_aoutput = EM28XX_AOUT_MASTER;
|
2008-12-17 01:04:56 +00:00
|
|
|
|
|
|
|
mutex_unlock(&dev->lock);
|
2007-11-11 16:17:17 +00: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 rc;
|
|
|
|
|
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
memset(qc, 0, sizeof(*qc));
|
|
|
|
|
|
|
|
qc->id = id;
|
|
|
|
|
2009-07-19 13:45:49 +00:00
|
|
|
/* enumberate AC97 controls */
|
|
|
|
if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
|
|
|
|
rc = ac97_queryctrl(qc);
|
|
|
|
if (!rc)
|
|
|
|
return 0;
|
2007-11-11 16:17:17 +00:00
|
|
|
}
|
2009-03-31 20:10:58 +00:00
|
|
|
|
2009-07-19 13:45:49 +00:00
|
|
|
/* enumberate V4L2 device controls */
|
2007-11-11 16:17:17 +00:00
|
|
|
mutex_lock(&dev->lock);
|
2009-03-31 20:10:58 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc);
|
2007-11-11 16:17:17 +00:00
|
|
|
mutex_unlock(&dev->lock);
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
if (qc->type)
|
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00: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 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
2008-12-22 09:20:32 +00:00
|
|
|
rc = 0;
|
2008-12-17 01:04:56 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
mutex_lock(&dev->lock);
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2009-07-19 13:45:49 +00:00
|
|
|
/* Set an AC97 control */
|
|
|
|
if (dev->audio_mode.ac97 != EM28XX_NO_AC97)
|
|
|
|
rc = ac97_get_ctrl(dev, ctrl);
|
|
|
|
else
|
|
|
|
rc = 1;
|
|
|
|
|
|
|
|
/* It were not an AC97 control. Sends it to the v4l2 dev interface */
|
|
|
|
if (rc == 1) {
|
2009-03-31 20:10:58 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
|
2009-07-19 13:45:49 +00:00
|
|
|
rc = 0;
|
2009-01-21 20:06:42 +00:00
|
|
|
}
|
2007-11-11 16:17:17 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
mutex_lock(&dev->lock);
|
|
|
|
|
2009-07-19 13:45:49 +00:00
|
|
|
/* Set an AC97 control */
|
|
|
|
if (dev->audio_mode.ac97 != EM28XX_NO_AC97)
|
|
|
|
rc = ac97_set_ctrl(dev, ctrl);
|
|
|
|
else
|
2007-11-11 16:17:17 +00:00
|
|
|
rc = 1;
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2009-07-29 04:42:02 +00:00
|
|
|
/* It isn't an AC97 control. Sends it to the v4l2 dev interface */
|
2007-11-11 16:17:17 +00:00
|
|
|
if (rc == 1) {
|
2009-03-31 20:10:58 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl);
|
2009-07-29 04:42:02 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* In the case of non-AC97 volume controls, we still need
|
|
|
|
* to do some setups at em28xx, in order to mute/unmute
|
|
|
|
* and to adjust audio volume. However, the value ranges
|
|
|
|
* should be checked by the corresponding V4L subdriver.
|
|
|
|
*/
|
|
|
|
switch (ctrl->id) {
|
|
|
|
case V4L2_CID_AUDIO_MUTE:
|
|
|
|
dev->mute = ctrl->value;
|
|
|
|
rc = em28xx_audio_analog_set(dev);
|
|
|
|
break;
|
|
|
|
case V4L2_CID_AUDIO_VOLUME:
|
|
|
|
dev->volume = ctrl->value;
|
|
|
|
rc = em28xx_audio_analog_set(dev);
|
|
|
|
}
|
2007-11-11 16:17:17 +00:00
|
|
|
}
|
|
|
|
|
2007-11-04 00:22:38 +00:00
|
|
|
mutex_unlock(&dev->lock);
|
2007-11-11 16:17:17 +00:00
|
|
|
return rc;
|
2005-11-09 05:37:07 +00:00
|
|
|
}
|
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
static int vidioc_g_tuner(struct file *file, void *priv,
|
|
|
|
struct v4l2_tuner *t)
|
2005-11-09 05:37:07 +00:00
|
|
|
{
|
2007-11-11 16:17:17 +00: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);
|
2009-03-31 20:10:58 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
|
2007-11-11 16:17:17 +00:00
|
|
|
mutex_unlock(&dev->lock);
|
2009-03-31 20:10:58 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
return 0;
|
2005-11-09 05:37:07 +00:00
|
|
|
}
|
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
static int vidioc_s_tuner(struct file *file, void *priv,
|
|
|
|
struct v4l2_tuner *t)
|
2005-11-09 05:37:07 +00:00
|
|
|
{
|
2007-11-11 16:17:17 +00:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc;
|
2007-11-10 13:26:20 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
if (0 != t->index)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
mutex_lock(&dev->lock);
|
2009-03-31 20:10:58 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
|
2007-11-11 16:17:17 +00:00
|
|
|
mutex_unlock(&dev->lock);
|
2009-03-31 20:10:58 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
return 0;
|
2005-11-09 05:37:07 +00:00
|
|
|
}
|
|
|
|
|
2007-11-11 16:17:17 +00: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 05:37:07 +00:00
|
|
|
|
2008-12-17 01:04:56 +00:00
|
|
|
mutex_lock(&dev->lock);
|
2008-01-05 20:22:01 +00:00
|
|
|
f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
|
2007-11-11 16:17:17 +00:00
|
|
|
f->frequency = dev->ctl_freq;
|
2008-12-17 01:04:56 +00:00
|
|
|
mutex_unlock(&dev->lock);
|
2007-11-11 16:17:17 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vidioc_s_frequency(struct file *file, void *priv,
|
|
|
|
struct v4l2_frequency *f)
|
2005-11-09 05:37:07 +00:00
|
|
|
{
|
2007-11-11 16:17:17 +00:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc;
|
2005-11-09 05:37:52 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
if (0 != f->tuner)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2008-01-05 20:22:01 +00: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-11 16:17:17 +00:00
|
|
|
return -EINVAL;
|
2007-11-11 04:08:26 +00:00
|
|
|
|
|
|
|
mutex_lock(&dev->lock);
|
2007-11-11 01:21:01 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
dev->ctl_freq = f->frequency;
|
2009-03-31 20:10:58 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f);
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
mutex_unlock(&dev->lock);
|
2008-12-17 01:04:56 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2008-02-06 12:00:41 +00:00
|
|
|
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
|
|
|
static int em28xx_reg_len(int reg)
|
|
|
|
{
|
|
|
|
switch (reg) {
|
2008-04-18 00:44:58 +00:00
|
|
|
case EM28XX_R40_AC97LSB:
|
|
|
|
case EM28XX_R30_HSCALELOW:
|
|
|
|
case EM28XX_R32_VSCALELOW:
|
2008-02-06 12:00:41 +00:00
|
|
|
return 2;
|
|
|
|
default:
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-22 23:58:41 +00:00
|
|
|
static int vidioc_g_chip_ident(struct file *file, void *priv,
|
2008-12-30 10:14:19 +00:00
|
|
|
struct v4l2_dbg_chip_ident *chip)
|
2008-12-22 23:58:41 +00:00
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
|
|
|
|
chip->ident = V4L2_IDENT_NONE;
|
|
|
|
chip->revision = 0;
|
|
|
|
|
2009-03-31 20:10:58 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_chip_ident, chip);
|
2008-12-22 23:58:41 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-06 12:00:41 +00:00
|
|
|
static int vidioc_g_register(struct file *file, void *priv,
|
2008-12-30 10:14:19 +00:00
|
|
|
struct v4l2_dbg_register *reg)
|
2008-02-06 12:00:41 +00:00
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int ret;
|
|
|
|
|
2008-12-30 10:14:19 +00:00
|
|
|
switch (reg->match.type) {
|
2008-12-22 23:58:41 +00:00
|
|
|
case V4L2_CHIP_MATCH_AC97:
|
2008-12-22 16:18:27 +00:00
|
|
|
mutex_lock(&dev->lock);
|
|
|
|
ret = em28xx_read_ac97(dev, reg->reg);
|
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
reg->val = ret;
|
2008-12-30 10:14:19 +00:00
|
|
|
reg->size = 1;
|
2008-12-22 16:18:27 +00:00
|
|
|
return 0;
|
2008-12-22 23:58:41 +00:00
|
|
|
case V4L2_CHIP_MATCH_I2C_DRIVER:
|
2009-03-31 20:10:58 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
|
2008-12-22 23:58:41 +00:00
|
|
|
return 0;
|
|
|
|
case V4L2_CHIP_MATCH_I2C_ADDR:
|
2009-08-09 22:39:23 +00:00
|
|
|
/* TODO: is this correct? */
|
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
|
|
|
|
return 0;
|
2008-12-22 23:58:41 +00:00
|
|
|
default:
|
2008-12-30 10:14:19 +00:00
|
|
|
if (!v4l2_chip_match_host(®->match))
|
2008-12-22 23:58:41 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
2008-02-06 12:00:41 +00:00
|
|
|
|
2008-12-22 23:58:41 +00:00
|
|
|
/* Match host */
|
2008-12-30 10:14:19 +00:00
|
|
|
reg->size = em28xx_reg_len(reg->reg);
|
|
|
|
if (reg->size == 1) {
|
2008-12-17 01:04:56 +00:00
|
|
|
mutex_lock(&dev->lock);
|
2008-02-06 12:00:41 +00:00
|
|
|
ret = em28xx_read_reg(dev, reg->reg);
|
2008-12-17 01:04:56 +00:00
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
|
2008-02-06 12:00:41 +00:00
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
reg->val = ret;
|
|
|
|
} else {
|
2008-12-30 10:14:19 +00:00
|
|
|
__le16 val = 0;
|
2008-12-17 01:04:56 +00:00
|
|
|
mutex_lock(&dev->lock);
|
2008-02-06 12:00:41 +00:00
|
|
|
ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS,
|
|
|
|
reg->reg, (char *)&val, 2);
|
2008-12-17 01:04:56 +00:00
|
|
|
mutex_unlock(&dev->lock);
|
2008-02-06 12:00:41 +00:00
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
|
2008-12-30 10:14:19 +00:00
|
|
|
reg->val = le16_to_cpu(val);
|
2008-02-06 12:00:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vidioc_s_register(struct file *file, void *priv,
|
2008-12-30 10:14:19 +00:00
|
|
|
struct v4l2_dbg_register *reg)
|
2008-02-06 12:00:41 +00:00
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
2008-12-30 10:14:19 +00:00
|
|
|
__le16 buf;
|
2008-12-17 01:04:56 +00:00
|
|
|
int rc;
|
2008-02-06 12:00:41 +00:00
|
|
|
|
2008-12-30 10:14:19 +00:00
|
|
|
switch (reg->match.type) {
|
2008-12-22 23:58:41 +00:00
|
|
|
case V4L2_CHIP_MATCH_AC97:
|
2008-12-22 16:18:27 +00:00
|
|
|
mutex_lock(&dev->lock);
|
|
|
|
rc = em28xx_write_ac97(dev, reg->reg, reg->val);
|
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
|
|
|
|
return rc;
|
2008-12-22 23:58:41 +00:00
|
|
|
case V4L2_CHIP_MATCH_I2C_DRIVER:
|
2009-03-31 20:10:58 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
|
2008-12-22 23:58:41 +00:00
|
|
|
return 0;
|
|
|
|
case V4L2_CHIP_MATCH_I2C_ADDR:
|
2009-08-09 22:39:23 +00:00
|
|
|
/* TODO: is this correct? */
|
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
|
|
|
|
return 0;
|
2008-12-22 23:58:41 +00:00
|
|
|
default:
|
2008-12-30 10:14:19 +00:00
|
|
|
if (!v4l2_chip_match_host(®->match))
|
2008-12-22 23:58:41 +00:00
|
|
|
return -EINVAL;
|
2008-12-22 16:18:27 +00:00
|
|
|
}
|
|
|
|
|
2008-12-22 23:58:41 +00:00
|
|
|
/* Match host */
|
2008-12-30 10:14:19 +00:00
|
|
|
buf = cpu_to_le16(reg->val);
|
2008-02-06 12:00:41 +00:00
|
|
|
|
2008-12-17 01:04:56 +00:00
|
|
|
mutex_lock(&dev->lock);
|
|
|
|
rc = em28xx_write_regs(dev, reg->reg, (char *)&buf,
|
|
|
|
em28xx_reg_len(reg->reg));
|
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
|
|
|
|
return rc;
|
2008-02-06 12:00:41 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2007-11-11 16:17:17 +00: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 05:37:07 +00:00
|
|
|
return -EINVAL;
|
|
|
|
|
2007-11-11 16:17:17 +00: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;
|
2009-09-03 03:23:27 +00:00
|
|
|
int rc = -EINVAL;
|
2007-11-11 16:17:17 +00:00
|
|
|
|
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
2009-09-03 03:23:27 +00:00
|
|
|
if (unlikely(type != fh->type))
|
|
|
|
return -EINVAL;
|
2007-11-11 16:17:17 +00:00
|
|
|
|
2009-09-03 03:23:27 +00:00
|
|
|
em28xx_videodbg("vidioc_streamon fh=%p t=%d fh->res=%d dev->res=%d\n",
|
|
|
|
fh, type, fh->resources, dev->resources);
|
2008-12-16 23:19:24 +00:00
|
|
|
|
2009-09-15 03:18:06 +00:00
|
|
|
if (unlikely(!res_get(fh, get_ressource(fh))))
|
2009-09-03 03:23:27 +00:00
|
|
|
return -EBUSY;
|
2008-12-17 01:04:56 +00:00
|
|
|
|
2009-09-03 03:23:27 +00:00
|
|
|
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
|
|
|
rc = videobuf_streamon(&fh->vb_vidq);
|
|
|
|
else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
|
|
|
|
rc = videobuf_streamon(&fh->vb_vbiq);
|
2008-12-17 01:04:56 +00:00
|
|
|
|
|
|
|
return rc;
|
2007-11-11 16:17:17 +00: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;
|
|
|
|
|
2009-09-01 04:54:54 +00:00
|
|
|
if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
|
|
|
|
fh->type != V4L2_BUF_TYPE_VBI_CAPTURE)
|
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-13 17:37:52 +00:00
|
|
|
return -EINVAL;
|
|
|
|
if (type != fh->type)
|
2007-11-11 16:17:17 +00:00
|
|
|
return -EINVAL;
|
|
|
|
|
2009-09-03 03:23:27 +00:00
|
|
|
em28xx_videodbg("vidioc_streamoff fh=%p t=%d fh->res=%d dev->res=%d\n",
|
|
|
|
fh, type, fh->resources, dev->resources);
|
2008-12-17 01:04:56 +00:00
|
|
|
|
2009-09-03 03:23:27 +00:00
|
|
|
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
|
2009-09-01 04:54:54 +00:00
|
|
|
videobuf_streamoff(&fh->vb_vidq);
|
2009-09-03 03:23:27 +00:00
|
|
|
res_free(fh, EM28XX_RESOURCE_VIDEO);
|
|
|
|
} else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
|
2009-09-01 04:54:54 +00:00
|
|
|
videobuf_streamoff(&fh->vb_vbiq);
|
2009-09-03 03:23:27 +00:00
|
|
|
res_free(fh, EM28XX_RESOURCE_VBI);
|
|
|
|
}
|
2005-11-09 05:37:07 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
static int vidioc_querycap(struct file *file, void *priv,
|
|
|
|
struct v4l2_capability *cap)
|
2005-11-09 05:37:07 +00:00
|
|
|
{
|
2007-11-11 16:17:17 +00: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));
|
2009-01-20 21:01:33 +00:00
|
|
|
usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
|
2007-11-11 16:17:17 +00:00
|
|
|
|
|
|
|
cap->version = EM28XX_VERSION_CODE;
|
|
|
|
|
|
|
|
cap->capabilities =
|
|
|
|
V4L2_CAP_SLICED_VBI_CAPTURE |
|
|
|
|
V4L2_CAP_VIDEO_CAPTURE |
|
|
|
|
V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
|
|
|
|
|
2009-09-11 03:08:44 +00:00
|
|
|
if (dev->vbi_dev)
|
|
|
|
cap->capabilities |= V4L2_CAP_VBI_CAPTURE;
|
|
|
|
|
2009-08-04 22:52:37 +00:00
|
|
|
if (dev->audio_mode.has_audio)
|
|
|
|
cap->capabilities |= V4L2_CAP_AUDIO;
|
|
|
|
|
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 09:59:20 +00:00
|
|
|
if (dev->tuner_type != TUNER_ABSENT)
|
2007-11-11 16:17:17 +00:00
|
|
|
cap->capabilities |= V4L2_CAP_TUNER;
|
|
|
|
|
|
|
|
return 0;
|
2006-01-09 17:25:14 +00:00
|
|
|
}
|
|
|
|
|
2008-05-28 15:16:41 +00:00
|
|
|
static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
|
2008-12-20 12:06:37 +00:00
|
|
|
struct v4l2_fmtdesc *f)
|
2005-11-09 05:37:07 +00:00
|
|
|
{
|
2008-12-20 12:06:37 +00:00
|
|
|
if (unlikely(f->index >= ARRAY_SIZE(format)))
|
2006-01-09 17:25:14 +00:00
|
|
|
return -EINVAL;
|
2007-11-11 16:17:17 +00:00
|
|
|
|
2008-12-20 12:06:37 +00:00
|
|
|
strlcpy(f->description, format[f->index].name, sizeof(f->description));
|
|
|
|
f->pixelformat = format[f->index].fourcc;
|
2007-11-11 16:17:17 +00:00
|
|
|
|
|
|
|
return 0;
|
2006-01-09 17:25:14 +00:00
|
|
|
}
|
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
/* Sliced VBI ioctls */
|
2008-05-28 15:16:41 +00:00
|
|
|
static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv,
|
2007-11-11 16:17:17 +00:00
|
|
|
struct v4l2_format *f)
|
2005-11-09 05:37:07 +00:00
|
|
|
{
|
2007-11-11 16:17:17 +00:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc;
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
mutex_lock(&dev->lock);
|
|
|
|
|
|
|
|
f->fmt.sliced.service_set = 0;
|
2009-03-31 20:10:58 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, video, g_fmt, f);
|
2007-11-11 16:17:17 +00:00
|
|
|
|
|
|
|
if (f->fmt.sliced.service_set == 0)
|
|
|
|
rc = -EINVAL;
|
|
|
|
|
|
|
|
mutex_unlock(&dev->lock);
|
2009-03-31 20:10:58 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2008-05-28 15:16:41 +00:00
|
|
|
static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
|
2007-11-11 16:17:17 +00: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);
|
2009-03-31 20:10:58 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, video, g_fmt, f);
|
2007-11-11 16:17:17 +00:00
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
|
|
|
|
if (f->fmt.sliced.service_set == 0)
|
|
|
|
return -EINVAL;
|
2005-11-09 05:37:07 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-09-01 04:54:54 +00:00
|
|
|
/* RAW VBI ioctls */
|
|
|
|
|
|
|
|
static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
|
|
|
|
struct v4l2_format *format)
|
|
|
|
{
|
2009-11-25 02:17:25 +00:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
|
|
|
|
format->fmt.vbi.samples_per_line = dev->vbi_width;
|
2009-09-01 04:54:54 +00:00
|
|
|
format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
|
|
|
|
format->fmt.vbi.offset = 0;
|
|
|
|
format->fmt.vbi.flags = 0;
|
2009-11-25 02:17:25 +00:00
|
|
|
format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
|
|
|
|
format->fmt.vbi.count[0] = dev->vbi_height;
|
|
|
|
format->fmt.vbi.count[1] = dev->vbi_height;
|
2009-09-01 04:54:54 +00:00
|
|
|
|
|
|
|
/* Varies by video standard (NTSC, PAL, etc.) */
|
2009-11-25 02:17:25 +00:00
|
|
|
if (dev->norm & V4L2_STD_525_60) {
|
|
|
|
/* NTSC */
|
|
|
|
format->fmt.vbi.start[0] = 10;
|
|
|
|
format->fmt.vbi.start[1] = 273;
|
|
|
|
} else if (dev->norm & V4L2_STD_625_50) {
|
|
|
|
/* PAL */
|
|
|
|
format->fmt.vbi.start[0] = 6;
|
|
|
|
format->fmt.vbi.start[1] = 318;
|
|
|
|
}
|
2009-09-01 04:54:54 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv,
|
|
|
|
struct v4l2_format *format)
|
|
|
|
{
|
2009-11-25 02:17:25 +00:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
|
|
|
|
format->fmt.vbi.samples_per_line = dev->vbi_width;
|
2009-09-01 04:54:54 +00:00
|
|
|
format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
|
|
|
|
format->fmt.vbi.offset = 0;
|
|
|
|
format->fmt.vbi.flags = 0;
|
2009-11-25 02:17:25 +00:00
|
|
|
format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
|
|
|
|
format->fmt.vbi.count[0] = dev->vbi_height;
|
|
|
|
format->fmt.vbi.count[1] = dev->vbi_height;
|
2009-09-01 04:54:54 +00:00
|
|
|
|
|
|
|
/* Varies by video standard (NTSC, PAL, etc.) */
|
2009-11-25 02:17:25 +00:00
|
|
|
if (dev->norm & V4L2_STD_525_60) {
|
|
|
|
/* NTSC */
|
|
|
|
format->fmt.vbi.start[0] = 10;
|
|
|
|
format->fmt.vbi.start[1] = 273;
|
|
|
|
} else if (dev->norm & V4L2_STD_625_50) {
|
|
|
|
/* PAL */
|
|
|
|
format->fmt.vbi.start[0] = 6;
|
|
|
|
format->fmt.vbi.start[1] = 318;
|
|
|
|
}
|
2009-09-01 04:54:54 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2007-11-11 16:17:17 +00:00
|
|
|
|
|
|
|
static int vidioc_reqbufs(struct file *file, void *priv,
|
|
|
|
struct v4l2_requestbuffers *rb)
|
2005-11-09 05:37:07 +00:00
|
|
|
{
|
2007-11-11 16:17:17 +00:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc;
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2009-09-01 04:54:54 +00:00
|
|
|
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
|
|
|
return videobuf_reqbufs(&fh->vb_vidq, rb);
|
|
|
|
else
|
|
|
|
return videobuf_reqbufs(&fh->vb_vbiq, rb);
|
2005-11-09 05:37:07 +00:00
|
|
|
}
|
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
static int vidioc_querybuf(struct file *file, void *priv,
|
|
|
|
struct v4l2_buffer *b)
|
2006-01-23 19:11:08 +00:00
|
|
|
{
|
2007-11-11 16:17:17 +00:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc;
|
2006-01-23 19:11:08 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
2006-01-23 19:11:08 +00:00
|
|
|
|
2009-09-01 04:54:54 +00:00
|
|
|
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
|
|
|
return videobuf_querybuf(&fh->vb_vidq, b);
|
|
|
|
else {
|
|
|
|
/* FIXME: I'm not sure yet whether this is a bug in zvbi or
|
|
|
|
the videobuf framework, but we probably shouldn't be
|
|
|
|
returning a buffer larger than that which was asked for.
|
|
|
|
At a minimum, it causes a crash in zvbi since it does
|
|
|
|
a memcpy based on the source buffer length */
|
|
|
|
int result = videobuf_querybuf(&fh->vb_vbiq, b);
|
2009-11-25 02:17:25 +00:00
|
|
|
b->length = dev->vbi_width * dev->vbi_height * 2;
|
|
|
|
|
2009-09-01 04:54:54 +00:00
|
|
|
return result;
|
|
|
|
}
|
2007-11-11 16:17:17 +00: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;
|
|
|
|
|
2009-09-01 04:54:54 +00:00
|
|
|
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
|
|
|
return videobuf_qbuf(&fh->vb_vidq, b);
|
2009-09-15 03:18:06 +00:00
|
|
|
else
|
2009-09-01 04:54:54 +00:00
|
|
|
return videobuf_qbuf(&fh->vb_vbiq, b);
|
2006-01-23 19:11:08 +00:00
|
|
|
}
|
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
|
2006-01-23 19:11:08 +00:00
|
|
|
{
|
2007-11-11 16:17:17 +00:00
|
|
|
struct em28xx_fh *fh = priv;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
2006-01-23 19:11:08 +00:00
|
|
|
|
2009-09-01 04:54:54 +00:00
|
|
|
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
|
|
|
return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags &
|
|
|
|
O_NONBLOCK);
|
|
|
|
else
|
|
|
|
return videobuf_dqbuf(&fh->vb_vbiq, b, file->f_flags &
|
|
|
|
O_NONBLOCK);
|
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-13 17:37:52 +00:00
|
|
|
}
|
2006-01-23 19:11:08 +00: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-13 17:37:52 +00:00
|
|
|
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
2008-04-13 17:41:23 +00: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-13 17:37:52 +00:00
|
|
|
{
|
2008-04-13 17:41:23 +00:00
|
|
|
struct em28xx_fh *fh = priv;
|
2006-01-23 19:11:08 +00:00
|
|
|
|
2009-09-01 04:54:54 +00:00
|
|
|
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
|
|
|
return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
|
|
|
|
else
|
|
|
|
return videobuf_cgmbuf(&fh->vb_vbiq, mbuf, 8);
|
2007-11-11 16:17:17 +00: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-13 17:37:52 +00:00
|
|
|
#endif
|
|
|
|
|
2006-01-23 19:11:08 +00:00
|
|
|
|
2008-01-05 20:22:01 +00: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));
|
2009-01-20 21:01:33 +00:00
|
|
|
usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
|
2008-01-05 20:22:01 +00: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;
|
|
|
|
|
2008-12-17 01:04:56 +00:00
|
|
|
mutex_lock(&dev->lock);
|
2009-03-31 20:10:58 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
|
2008-12-17 01:04:56 +00:00
|
|
|
mutex_unlock(&dev->lock);
|
|
|
|
|
2008-01-05 20:22:01 +00:00
|
|
|
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;
|
|
|
|
|
2008-12-17 01:04:56 +00:00
|
|
|
mutex_lock(&dev->lock);
|
2009-03-31 20:10:58 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
|
2008-12-17 01:04:56 +00:00
|
|
|
mutex_unlock(&dev->lock);
|
2008-01-05 20:22:01 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2009-07-19 12:10:06 +00:00
|
|
|
for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++) {
|
|
|
|
if (qc->id && qc->id == ac97_qctrl[i].id) {
|
|
|
|
memcpy(qc, &(ac97_qctrl[i]), sizeof(*qc));
|
2008-01-05 20:22:01 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
/*
|
|
|
|
* em28xx_v4l2_open()
|
|
|
|
* inits the device and starts isoc transfer
|
|
|
|
*/
|
2008-12-30 09:58:20 +00:00
|
|
|
static int em28xx_v4l2_open(struct file *filp)
|
2007-11-11 16:17:17 +00:00
|
|
|
{
|
2009-12-10 13:44:04 +00:00
|
|
|
int errCode = 0, radio = 0;
|
|
|
|
struct video_device *vdev = video_devdata(filp);
|
|
|
|
struct em28xx *dev = video_drvdata(filp);
|
|
|
|
enum v4l2_buf_type fh_type = 0;
|
2007-11-11 16:17:17 +00:00
|
|
|
struct em28xx_fh *fh;
|
2009-08-08 06:14:55 +00:00
|
|
|
enum v4l2_field field;
|
2006-01-23 19:11:08 +00:00
|
|
|
|
2009-12-10 13:44:04 +00:00
|
|
|
switch (vdev->vfl_type) {
|
|
|
|
case VFL_TYPE_GRABBER:
|
|
|
|
fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
|
|
|
break;
|
|
|
|
case VFL_TYPE_VBI:
|
|
|
|
fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
|
|
|
|
break;
|
|
|
|
case VFL_TYPE_RADIO:
|
|
|
|
radio = 1;
|
|
|
|
break;
|
|
|
|
}
|
2008-11-20 13:30:26 +00:00
|
|
|
|
|
|
|
mutex_lock(&dev->lock);
|
2006-01-23 19:11:08 +00:00
|
|
|
|
2009-12-10 13:47:13 +00:00
|
|
|
em28xx_videodbg("open dev=%s type=%s users=%d\n",
|
|
|
|
video_device_node_name(vdev), v4l2_type_names[fh_type],
|
|
|
|
dev->users);
|
2006-01-23 19:11:08 +00:00
|
|
|
|
2006-01-23 19:11:09 +00:00
|
|
|
|
2008-04-18 00:48:00 +00:00
|
|
|
fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
|
2007-11-11 16:17:17 +00:00
|
|
|
if (!fh) {
|
|
|
|
em28xx_errdev("em28xx-video.c: Out of memory?!\n");
|
2008-11-20 13:30:26 +00:00
|
|
|
mutex_unlock(&dev->lock);
|
2007-11-11 16:17:17 +00:00
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
fh->dev = dev;
|
2008-01-05 20:22:01 +00:00
|
|
|
fh->radio = radio;
|
2008-04-13 17:38:47 +00:00
|
|
|
fh->type = fh_type;
|
2007-11-11 16:17:17 +00:00
|
|
|
filp->private_data = fh;
|
2006-01-23 19:11:09 +00:00
|
|
|
|
2008-04-13 17:38:47 +00:00
|
|
|
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
|
2008-04-18 00:48:00 +00: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-08 18:44:25 +00:00
|
|
|
em28xx_set_alternate(dev);
|
2007-11-11 16:17:17 +00:00
|
|
|
em28xx_resolution_set(dev);
|
2006-01-23 19:11:08 +00:00
|
|
|
|
2008-04-18 00:48:00 +00:00
|
|
|
/* Needed, since GPIO might have disabled power of
|
|
|
|
some i2c device
|
|
|
|
*/
|
2008-12-29 01:18:14 +00:00
|
|
|
em28xx_wake_i2c(dev);
|
2008-04-18 00:48:00 +00:00
|
|
|
|
2006-01-23 19:11:08 +00:00
|
|
|
}
|
2008-01-05 20:22:01 +00:00
|
|
|
if (fh->radio) {
|
|
|
|
em28xx_videodbg("video_open: setting radio device\n");
|
2009-03-31 20:10:58 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_radio);
|
2008-01-05 20:22:01 +00:00
|
|
|
}
|
2006-01-23 19:11:08 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
dev->users++;
|
2006-01-23 19:11:08 +00:00
|
|
|
|
2009-08-08 06:14:55 +00:00
|
|
|
if (dev->progressive)
|
|
|
|
field = V4L2_FIELD_NONE;
|
|
|
|
else
|
|
|
|
field = V4L2_FIELD_INTERLACED;
|
|
|
|
|
2009-09-03 03:23:27 +00:00
|
|
|
videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops,
|
|
|
|
NULL, &dev->slock,
|
|
|
|
V4L2_BUF_TYPE_VIDEO_CAPTURE, field,
|
|
|
|
sizeof(struct em28xx_buffer), fh);
|
2009-09-01 04:54:54 +00:00
|
|
|
|
2009-09-03 03:23:27 +00:00
|
|
|
videobuf_queue_vmalloc_init(&fh->vb_vbiq, &em28xx_vbi_qops,
|
|
|
|
NULL, &dev->slock,
|
|
|
|
V4L2_BUF_TYPE_VBI_CAPTURE,
|
|
|
|
V4L2_FIELD_SEQ_TB,
|
|
|
|
sizeof(struct em28xx_buffer), fh);
|
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-13 17:37:52 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
mutex_unlock(&dev->lock);
|
2008-04-18 00:48:00 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
return errCode;
|
2006-01-23 19:11:08 +00:00
|
|
|
}
|
2006-01-23 19:11:08 +00:00
|
|
|
|
2005-11-09 05:37:07 +00:00
|
|
|
/*
|
2007-11-11 16:17:17 +00:00
|
|
|
* em28xx_realease_resources()
|
|
|
|
* unregisters the v4l2,i2c and usb devices
|
|
|
|
* called when the device gets disconected or at module unload
|
|
|
|
*/
|
2008-12-29 01:18:14 +00:00
|
|
|
void em28xx_release_analog_resources(struct em28xx *dev)
|
2005-11-09 05:37:07 +00:00
|
|
|
{
|
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
/*FIXME: I2C IR should be disconnected */
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2008-01-05 20:22:01 +00:00
|
|
|
if (dev->radio_dev) {
|
2009-11-27 16:57:30 +00:00
|
|
|
if (video_is_registered(dev->radio_dev))
|
2008-01-05 20:22:01 +00:00
|
|
|
video_unregister_device(dev->radio_dev);
|
|
|
|
else
|
|
|
|
video_device_release(dev->radio_dev);
|
|
|
|
dev->radio_dev = NULL;
|
|
|
|
}
|
|
|
|
if (dev->vbi_dev) {
|
2009-11-27 16:57:15 +00:00
|
|
|
em28xx_info("V4L2 device %s deregistered\n",
|
|
|
|
video_device_node_name(dev->vbi_dev));
|
2009-11-27 16:57:30 +00:00
|
|
|
if (video_is_registered(dev->vbi_dev))
|
2008-01-05 20:22:01 +00:00
|
|
|
video_unregister_device(dev->vbi_dev);
|
|
|
|
else
|
|
|
|
video_device_release(dev->vbi_dev);
|
|
|
|
dev->vbi_dev = NULL;
|
|
|
|
}
|
|
|
|
if (dev->vdev) {
|
2009-11-27 16:57:15 +00:00
|
|
|
em28xx_info("V4L2 device %s deregistered\n",
|
|
|
|
video_device_node_name(dev->vdev));
|
2009-11-27 16:57:30 +00:00
|
|
|
if (video_is_registered(dev->vdev))
|
2008-01-05 20:22:01 +00:00
|
|
|
video_unregister_device(dev->vdev);
|
|
|
|
else
|
|
|
|
video_device_release(dev->vdev);
|
|
|
|
dev->vdev = NULL;
|
|
|
|
}
|
2007-11-11 16:17:17 +00:00
|
|
|
}
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
/*
|
|
|
|
* em28xx_v4l2_close()
|
2008-04-18 00:41:10 +00:00
|
|
|
* stops streaming and deallocates all resources allocated by the v4l2
|
|
|
|
* calls and ioctls
|
2007-11-11 16:17:17 +00:00
|
|
|
*/
|
2008-12-30 09:58:20 +00:00
|
|
|
static int em28xx_v4l2_close(struct file *filp)
|
2007-11-11 16:17:17 +00:00
|
|
|
{
|
|
|
|
struct em28xx_fh *fh = filp->private_data;
|
|
|
|
struct em28xx *dev = fh->dev;
|
|
|
|
int errCode;
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
em28xx_videodbg("users=%d\n", dev->users);
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2009-09-03 03:23:27 +00:00
|
|
|
if (res_check(fh, EM28XX_RESOURCE_VIDEO)) {
|
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-13 17:37:52 +00:00
|
|
|
videobuf_stop(&fh->vb_vidq);
|
2009-09-03 03:23:27 +00:00
|
|
|
res_free(fh, EM28XX_RESOURCE_VIDEO);
|
|
|
|
}
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2009-09-03 03:23:27 +00:00
|
|
|
if (res_check(fh, EM28XX_RESOURCE_VBI)) {
|
|
|
|
videobuf_stop(&fh->vb_vbiq);
|
|
|
|
res_free(fh, EM28XX_RESOURCE_VBI);
|
|
|
|
}
|
|
|
|
|
2009-09-15 03:18:06 +00:00
|
|
|
if (dev->users == 1) {
|
2007-11-11 16:17:17 +00:00
|
|
|
/* the device is already disconnect,
|
|
|
|
free the remaining resources */
|
|
|
|
if (dev->state & DEV_DISCONNECTED) {
|
|
|
|
em28xx_release_resources(dev);
|
|
|
|
kfree(dev);
|
|
|
|
return 0;
|
|
|
|
}
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2008-12-05 13:39:12 +00:00
|
|
|
/* Save some power by putting tuner to sleep */
|
2009-10-05 13:48:17 +00:00
|
|
|
v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
|
2008-12-05 13:39:12 +00:00
|
|
|
|
2008-04-13 17:38:47 +00:00
|
|
|
/* do this before setting alternate! */
|
|
|
|
em28xx_uninit_isoc(dev);
|
2008-11-27 12:10:40 +00:00
|
|
|
em28xx_set_mode(dev, EM28XX_SUSPEND);
|
2008-04-13 17:38:47 +00:00
|
|
|
|
2007-11-11 16:17:17 +00: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-23 19:11:09 +00:00
|
|
|
}
|
2009-09-01 04:54:54 +00:00
|
|
|
|
2009-09-03 03:23:27 +00:00
|
|
|
videobuf_mmap_free(&fh->vb_vidq);
|
|
|
|
videobuf_mmap_free(&fh->vb_vbiq);
|
2007-11-11 16:17:17 +00:00
|
|
|
kfree(fh);
|
|
|
|
dev->users--;
|
|
|
|
wake_up_interruptible_nr(&dev->open, 1);
|
|
|
|
return 0;
|
|
|
|
}
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
/*
|
|
|
|
* em28xx_v4l2_read()
|
|
|
|
* will allocate buffers when called for the first time
|
|
|
|
*/
|
|
|
|
static ssize_t
|
2008-04-18 00:41:10 +00:00
|
|
|
em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count,
|
2008-04-13 17:41:23 +00:00
|
|
|
loff_t *pos)
|
2007-11-11 16:17:17 +00: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-13 17:37:52 +00:00
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
/* FIXME: read() is not prepared to allow changing the video
|
|
|
|
resolution while streaming. Seems a bug at em28xx_set_fmt
|
|
|
|
*/
|
2005-11-09 05:37:07 +00: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-13 17:37:52 +00:00
|
|
|
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
|
2009-09-03 03:23:27 +00:00
|
|
|
if (res_locked(dev, EM28XX_RESOURCE_VIDEO))
|
|
|
|
return -EBUSY;
|
2007-11-11 16:17:17 +00: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-13 17:37:52 +00:00
|
|
|
return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
|
|
|
|
filp->f_flags & O_NONBLOCK);
|
2007-11-11 16:17:17 +00:00
|
|
|
}
|
2009-09-01 04:54:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
|
2009-09-03 03:23:27 +00:00
|
|
|
if (!res_get(fh, EM28XX_RESOURCE_VBI))
|
|
|
|
return -EBUSY;
|
2009-09-01 04:54:54 +00:00
|
|
|
|
|
|
|
return videobuf_read_stream(&fh->vb_vbiq, buf, count, pos, 0,
|
|
|
|
filp->f_flags & O_NONBLOCK);
|
|
|
|
}
|
|
|
|
|
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-13 17:37:52 +00:00
|
|
|
return 0;
|
2005-11-09 05:37:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2007-11-11 16:17:17 +00:00
|
|
|
* em28xx_v4l2_poll()
|
|
|
|
* will allocate buffers when called for the first time
|
2005-11-09 05:37:07 +00:00
|
|
|
*/
|
2009-02-11 02:28:24 +00:00
|
|
|
static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table *wait)
|
2005-11-09 05:37:07 +00:00
|
|
|
{
|
2007-11-11 01:21:01 +00:00
|
|
|
struct em28xx_fh *fh = filp->private_data;
|
2007-11-11 16:17:17 +00: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-13 17:37:52 +00:00
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2009-09-03 03:23:27 +00:00
|
|
|
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
|
|
|
|
if (!res_get(fh, EM28XX_RESOURCE_VIDEO))
|
|
|
|
return POLLERR;
|
2009-09-01 04:54:54 +00:00
|
|
|
return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
|
2009-09-03 03:23:27 +00:00
|
|
|
} else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
|
|
|
|
if (!res_get(fh, EM28XX_RESOURCE_VBI))
|
|
|
|
return POLLERR;
|
2009-09-01 04:54:54 +00:00
|
|
|
return videobuf_poll_stream(filp, &fh->vb_vbiq, wait);
|
2009-09-03 03:23:27 +00:00
|
|
|
} else {
|
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-13 17:37:52 +00:00
|
|
|
return POLLERR;
|
2009-09-03 03:23:27 +00:00
|
|
|
}
|
2007-11-11 16:17:17 +00:00
|
|
|
}
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2007-11-11 16:17:17 +00: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-13 17:37:52 +00:00
|
|
|
int rc;
|
2005-11-09 05:37:07 +00: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-13 17:37:52 +00:00
|
|
|
rc = check_dev(dev);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2009-09-03 01:23:23 +00:00
|
|
|
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
|
|
|
rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
|
|
|
|
else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
|
|
|
|
rc = videobuf_mmap_mapper(&fh->vb_vbiq, vma);
|
2005-11-09 05:37:07 +00: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-13 17:37:52 +00: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 05:37:07 +00: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-13 17:37:52 +00:00
|
|
|
return rc;
|
2005-11-09 05:37:07 +00:00
|
|
|
}
|
|
|
|
|
2008-12-30 09:58:20 +00:00
|
|
|
static const struct v4l2_file_operations em28xx_v4l_fops = {
|
2007-11-11 16:17:17 +00: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,
|
|
|
|
};
|
2006-01-09 17:24:58 +00:00
|
|
|
|
2008-07-21 05:57:38 +00:00
|
|
|
static const struct v4l2_ioctl_ops video_ioctl_ops = {
|
2007-11-11 16:17:17 +00:00
|
|
|
.vidioc_querycap = vidioc_querycap,
|
2008-05-28 15:16:41 +00: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,
|
2009-09-01 04:54:54 +00:00
|
|
|
.vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
|
|
|
|
.vidioc_s_fmt_vbi_cap = vidioc_s_fmt_vbi_cap,
|
2007-11-11 16:17:17 +00:00
|
|
|
.vidioc_g_audio = vidioc_g_audio,
|
|
|
|
.vidioc_s_audio = vidioc_s_audio,
|
|
|
|
.vidioc_cropcap = vidioc_cropcap,
|
|
|
|
|
2008-05-28 15:16:41 +00: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-11 16:17:17 +00:00
|
|
|
|
|
|
|
.vidioc_reqbufs = vidioc_reqbufs,
|
|
|
|
.vidioc_querybuf = vidioc_querybuf,
|
|
|
|
.vidioc_qbuf = vidioc_qbuf,
|
|
|
|
.vidioc_dqbuf = vidioc_dqbuf,
|
2009-09-11 03:40:18 +00:00
|
|
|
.vidioc_g_std = vidioc_g_std,
|
2007-11-11 16:17:17 +00:00
|
|
|
.vidioc_s_std = vidioc_s_std,
|
2009-08-07 00:53:59 +00:00
|
|
|
.vidioc_g_parm = vidioc_g_parm,
|
|
|
|
.vidioc_s_parm = vidioc_s_parm,
|
2007-11-11 16:17:17 +00:00
|
|
|
.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 12:00:41 +00:00
|
|
|
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
|
|
|
.vidioc_g_register = vidioc_g_register,
|
|
|
|
.vidioc_s_register = vidioc_s_register,
|
2008-12-22 23:58:41 +00:00
|
|
|
.vidioc_g_chip_ident = vidioc_g_chip_ident,
|
2008-02-06 12:00:41 +00:00
|
|
|
#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-13 17:37:52 +00:00
|
|
|
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
|
|
|
.vidiocgmbuf = vidiocgmbuf,
|
|
|
|
#endif
|
2008-07-21 05:57:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const struct video_device em28xx_video_template = {
|
|
|
|
.fops = &em28xx_v4l_fops,
|
|
|
|
.release = video_device_release,
|
|
|
|
.ioctl_ops = &video_ioctl_ops,
|
|
|
|
|
2007-11-11 16:17:17 +00:00
|
|
|
.tvnorms = V4L2_STD_ALL,
|
2009-09-11 03:40:18 +00:00
|
|
|
.current_norm = V4L2_STD_PAL,
|
2005-11-09 05:37:07 +00:00
|
|
|
};
|
|
|
|
|
2008-12-30 09:58:20 +00:00
|
|
|
static const struct v4l2_file_operations radio_fops = {
|
2008-07-21 05:57:38 +00:00
|
|
|
.owner = THIS_MODULE,
|
|
|
|
.open = em28xx_v4l2_open,
|
|
|
|
.release = em28xx_v4l2_close,
|
|
|
|
.ioctl = video_ioctl2,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct v4l2_ioctl_ops radio_ioctl_ops = {
|
2008-01-05 20:22:01 +00: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 12:00:41 +00:00
|
|
|
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
|
|
|
.vidioc_g_register = vidioc_g_register,
|
|
|
|
.vidioc_s_register = vidioc_s_register,
|
|
|
|
#endif
|
2008-01-05 20:22:01 +00:00
|
|
|
};
|
|
|
|
|
2008-07-21 05:57:38 +00:00
|
|
|
static struct video_device em28xx_radio_template = {
|
|
|
|
.name = "em28xx-radio",
|
|
|
|
.fops = &radio_fops,
|
|
|
|
.ioctl_ops = &radio_ioctl_ops,
|
|
|
|
};
|
|
|
|
|
2008-04-18 00:41:10 +00:00
|
|
|
/******************************** usb interface ******************************/
|
2005-11-09 05:37:07 +00:00
|
|
|
|
2008-01-05 12:57:31 +00:00
|
|
|
|
|
|
|
|
2008-01-29 01:10:48 +00:00
|
|
|
static struct video_device *em28xx_vdev_init(struct em28xx *dev,
|
2009-02-11 02:28:24 +00:00
|
|
|
const struct video_device *template,
|
|
|
|
const char *type_name)
|
2008-01-05 20:22:01 +00:00
|
|
|
{
|
|
|
|
struct video_device *vfd;
|
|
|
|
|
|
|
|
vfd = video_device_alloc();
|
|
|
|
if (NULL == vfd)
|
|
|
|
return NULL;
|
2009-03-31 20:10:58 +00:00
|
|
|
|
|
|
|
*vfd = *template;
|
|
|
|
vfd->v4l2_dev = &dev->v4l2_dev;
|
|
|
|
vfd->release = video_device_release;
|
|
|
|
vfd->debug = video_debug;
|
2008-01-05 20:22:01 +00:00
|
|
|
|
|
|
|
snprintf(vfd->name, sizeof(vfd->name), "%s %s",
|
|
|
|
dev->name, type_name);
|
|
|
|
|
2009-12-10 13:44:04 +00:00
|
|
|
video_set_drvdata(vfd, dev);
|
2008-01-05 20:22:01 +00:00
|
|
|
return vfd;
|
|
|
|
}
|
|
|
|
|
2008-12-29 01:26:36 +00:00
|
|
|
int em28xx_register_analog_devices(struct em28xx *dev)
|
2008-12-29 01:18:14 +00:00
|
|
|
{
|
2009-01-19 00:59:34 +00:00
|
|
|
u8 val;
|
2008-12-29 01:26:36 +00:00
|
|
|
int ret;
|
|
|
|
|
2008-12-29 01:18:14 +00:00
|
|
|
printk(KERN_INFO "%s: v4l2 driver version %d.%d.%d\n",
|
|
|
|
dev->name,
|
|
|
|
(EM28XX_VERSION_CODE >> 16) & 0xff,
|
|
|
|
(EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff);
|
|
|
|
|
2009-01-08 01:49:25 +00:00
|
|
|
/* set default norm */
|
|
|
|
dev->norm = em28xx_video_template.current_norm;
|
|
|
|
dev->interlaced = EM28XX_INTERLACED_DEFAULT;
|
|
|
|
dev->ctl_input = 0;
|
|
|
|
|
2008-12-29 01:18:14 +00:00
|
|
|
/* Analog specific initialization */
|
|
|
|
dev->format = &format[0];
|
2009-07-02 20:34:04 +00:00
|
|
|
em28xx_set_video_format(dev, format[0].fourcc,
|
|
|
|
norm_maxw(dev), norm_maxh(dev));
|
|
|
|
|
2009-01-08 01:49:25 +00:00
|
|
|
video_mux(dev, dev->ctl_input);
|
|
|
|
|
|
|
|
/* Audio defaults */
|
|
|
|
dev->mute = 1;
|
|
|
|
dev->volume = 0x1f;
|
2008-12-29 01:18:14 +00:00
|
|
|
|
|
|
|
/* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
|
2009-02-11 02:28:24 +00:00
|
|
|
val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
|
|
|
|
em28xx_write_reg(dev, EM28XX_R0F_XCLK,
|
|
|
|
(EM28XX_XCLK_AUDIO_UNMUTE | val));
|
2008-12-29 01:18:14 +00:00
|
|
|
|
|
|
|
em28xx_set_outfmt(dev);
|
|
|
|
em28xx_colorlevels_set_default(dev);
|
|
|
|
em28xx_compression_disable(dev);
|
|
|
|
|
2008-11-20 13:30:26 +00:00
|
|
|
/* 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 */
|
2009-09-11 03:01:06 +00:00
|
|
|
if (em28xx_vbi_supported(dev) == 1) {
|
|
|
|
dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template,
|
|
|
|
"vbi");
|
2008-11-20 13:30:26 +00:00
|
|
|
|
2009-09-11 03:01:06 +00:00
|
|
|
/* 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;
|
|
|
|
}
|
2008-11-20 13:30:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
|
2009-02-11 02:28:24 +00:00
|
|
|
dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template,
|
|
|
|
"radio");
|
2008-11-20 13:30:26 +00:00
|
|
|
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;
|
|
|
|
}
|
2009-11-27 16:57:15 +00:00
|
|
|
em28xx_info("Registered radio device as %s\n",
|
|
|
|
video_device_node_name(dev->radio_dev));
|
2008-11-20 13:30:26 +00:00
|
|
|
}
|
|
|
|
|
2009-11-27 16:57:15 +00:00
|
|
|
em28xx_info("V4L2 video device registered as %s\n",
|
|
|
|
video_device_node_name(dev->vdev));
|
2009-09-11 03:01:06 +00:00
|
|
|
|
|
|
|
if (dev->vbi_dev)
|
2009-11-27 16:57:15 +00:00
|
|
|
em28xx_info("V4L2 VBI device registered as %s\n",
|
|
|
|
video_device_node_name(dev->vbi_dev));
|
2008-11-20 13:30:26 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|