summaryrefslogtreecommitdiff
path: root/drivers/media/video/em28xx/em28xx.h
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2008-04-13 14:37:52 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 14:08:00 -0300
commitad0ebb96c220c461386e9a765fca3daf5590d01e (patch)
tree4c13c24682703cbb94f415eb944c573ac0835ccc /drivers/media/video/em28xx/em28xx.h
parent78e92006f410a4044f8c1760c25ac9d11d259aa2 (diff)
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>
Diffstat (limited to 'drivers/media/video/em28xx/em28xx.h')
-rw-r--r--drivers/media/video/em28xx/em28xx.h94
1 files changed, 68 insertions, 26 deletions
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 04e0e48ecabe..dd18ceb30a43 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -26,12 +26,12 @@
#define _EM28XX_H
#include <linux/videodev2.h>
+#include <media/videobuf-vmalloc.h>
+
#include <linux/i2c.h>
#include <linux/mutex.h>
#include <media/ir-kbd-i2c.h>
-#define UNSET -1
-
/* maximum number of em28xx boards */
#define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */
@@ -81,31 +81,69 @@
/* time in msecs to wait for i2c writes to finish */
#define EM2800_I2C_WRITE_TIMEOUT 20
-/* the various frame states */
-enum em28xx_frame_state {
- F_UNUSED = 0,
- F_QUEUED,
- F_GRABBING,
- F_DONE,
- F_ERROR,
-};
-
-/* stream states */
enum em28xx_stream_state {
STREAM_OFF,
STREAM_INTERRUPT,
STREAM_ON,
};
-/* frames */
-struct em28xx_frame_t {
- void *bufmem;
- struct v4l2_buffer buf;
- enum em28xx_frame_state state;
+struct em28xx_usb_isoc_ctl {
+ /* max packet size of isoc transaction */
+ int max_pkt_size;
+
+ /* number of allocated urbs */
+ int num_bufs;
+
+ /* urb for isoc transfers */
+ struct urb **urb;
+
+ /* transfer buffers for isoc transfer */
+ char **transfer_buffer;
+
+ /* Last buffer command and region */
+ u8 cmd;
+ int pos, size, pktsize;
+
+ /* Last field: ODD or EVEN? */
+ int field;
+
+ /* Stores incomplete commands */
+ u32 tmp_buf;
+ int tmp_buf_len;
+
+ /* Stores already requested buffers */
+ struct em28xx_buffer *buf;
+
+ /* Stores the number of received fields */
+ int nfields;
+};
+
+struct em28xx_fmt {
+ char *name;
+ u32 fourcc; /* v4l2 format id */
+};
+
+/* buffer for one video frame */
+struct em28xx_buffer {
+ /* common v4l buffer stuff -- must be first */
+ struct videobuf_buffer vb;
+
+ struct em28xx_fmt *fmt;
+
struct list_head frame;
- unsigned long vma_use_count;
int top_field;
- int fieldbytesused;
+ int receiving;
+};
+
+struct em28xx_dmaqueue {
+ struct list_head active;
+ struct list_head queued;
+ struct timer_list timeout;
+
+ wait_queue_head_t wq;
+
+ /* Counters to control buffer fill */
+ int pos;
};
/* io methods */
@@ -255,10 +293,6 @@ struct em28xx {
int mute;
int volume;
/* frame properties */
- struct em28xx_frame_t frame[EM28XX_NUM_FRAMES]; /* list of frames */
- int num_frames; /* number of frames currently in use */
- unsigned int frame_count; /* total number of transfered frames */
- struct em28xx_frame_t *frame_current; /* the frame that is being filled */
int width; /* current frame width */
int height; /* current frame height */
int frame_size; /* current frame size */
@@ -277,7 +311,6 @@ struct em28xx {
/* states */
enum em28xx_dev_state state;
- enum em28xx_stream_state stream;
enum em28xx_io_method io;
struct work_struct request_module_wk;
@@ -292,6 +325,11 @@ struct em28xx {
unsigned char eedata[256];
+ /* Isoc control struct */
+ struct em28xx_dmaqueue vidq;
+ struct em28xx_usb_isoc_ctl isoc_ctl;
+ spinlock_t slock;
+
/* usb transfer */
struct usb_device *udev; /* the usb device */
int alt; /* alternate */
@@ -315,6 +353,12 @@ struct em28xx_fh {
struct em28xx *dev;
unsigned int stream_on:1; /* Locks streams */
int radio;
+
+ unsigned int width, height;
+ struct videobuf_queue vb_vidq;
+ struct em28xx_fmt *fmt;
+
+ enum v4l2_buf_type type;
};
struct em28xx_ops {
@@ -351,8 +395,6 @@ int em28xx_colorlevels_set_default(struct em28xx *dev);
int em28xx_capture_start(struct em28xx *dev, int start);
int em28xx_outfmt_set_yuv422(struct em28xx *dev);
int em28xx_resolution_set(struct em28xx *dev);
-int em28xx_init_isoc(struct em28xx *dev);
-void em28xx_uninit_isoc(struct em28xx *dev);
int em28xx_set_alternate(struct em28xx *dev);
/* Provided by em28xx-video.c */