summaryrefslogtreecommitdiff
path: root/linux/drivers/media/common
diff options
context:
space:
mode:
authorMichael Hunold <devnull@localhost>2002-12-30 21:10:58 +0000
committerMichael Hunold <devnull@localhost>2002-12-30 21:10:58 +0000
commitd425bfb33eedb26e9878187a4f8506db80cee364 (patch)
treed85c70f34dcb9829043d9b22248a9b2693a1a361 /linux/drivers/media/common
parent4ac441dd0b30a80cdcf026cc2952cc547bf5dbad (diff)
downloadmediapointer-dvb-s2-d425bfb33eedb26e9878187a4f8506db80cee364.tar.gz
mediapointer-dvb-s2-d425bfb33eedb26e9878187a4f8506db80cee364.tar.bz2
Next chunk of big splitup / cleanup:
(tested on 2.4.18 and 2.5.53 -- the budget driver is untested, Holger will test it the next week) saa7146: - completely separated the saa7146 driver into a core-driver (saa7146.o) and a video/vbi part (saa7146_vv.o). this allows you to build the budget driver without av7110 and videodev bloat (see below) The following thinks have been approved by Holger Waechtler: av7110 (now ttpci): - for 2.5.x: removed the av7110 directory and put everything into ttpci. - removed all budget card support from this driver - compile and build fixes for the saa7146 changes ttpci-budget (new): - for 2.5.x: created a new ttpci-budget directory, added a new driver for the budget cards mxb: - compile and build fixes for the saa7146 changes Changed the build and compile files for both 2.5.x and build-2.4 of course...
Diffstat (limited to 'linux/drivers/media/common')
-rw-r--r--linux/drivers/media/common/saa7146.h306
-rw-r--r--linux/drivers/media/common/saa7146_core.c47
-rw-r--r--linux/drivers/media/common/saa7146_fops.c139
-rw-r--r--linux/drivers/media/common/saa7146_hlp.c82
-rw-r--r--linux/drivers/media/common/saa7146_vbi.c69
-rw-r--r--linux/drivers/media/common/saa7146_video.c186
-rw-r--r--linux/drivers/media/common/saa7146_vv.h269
7 files changed, 623 insertions, 475 deletions
diff --git a/linux/drivers/media/common/saa7146.h b/linux/drivers/media/common/saa7146.h
index b35b14672..81b06e9c7 100644
--- a/linux/drivers/media/common/saa7146.h
+++ b/linux/drivers/media/common/saa7146.h
@@ -17,13 +17,6 @@ from flaws in video-buf.c => Gerd Knorr */
#include <asm/io.h> /* for accessing devices */
#include <linux/stringify.h>
-#include <linux/videodev2.h>
-#include "video-buf.h"
-
-#define MAX_SAA7146_CAPTURE_BUFFERS 32 /* arbitrary */
-
-#define BUFFER_TIMEOUT (HZ/2) /* 0.5 seconds */
-
#define SAA7146_VERSION_CODE KERNEL_VERSION(0,5,0)
#define saa7146_write(sxy,adr,dat) writel((dat),(sxy->mem+(adr)))
@@ -57,37 +50,29 @@ extern unsigned int saa7146_debug;
saa7146_write(x, IER, saa7146_read(x, IER) | (y));
struct saa7146_dev;
-struct saa7146_fh;
-struct saa7146_standard;
-
-struct saa7146_extension_ioctls
-{
- unsigned int cmd;
- int flags;
-};
+struct saa7146_extension;
+struct saa7146_vv;
struct saa7146_sub_info {
unsigned int subvendor, subdevice;
};
-#define SAA7146_EXCLUSIVE 0x1
-#define SAA7146_BEFORE 0x2
-#define SAA7146_AFTER 0x4
-
-/* flags */
-#define SAA7146_EXT_SWAP_ODD_EVEN 0x1 /* needs odd/even fields swapped */
+/* saa7146 page table */
+struct saa7146_pgtable {
+ unsigned int size;
+ u32 *cpu;
+ dma_addr_t dma;
+ /* used for offsets for u,v planes for planar capture modes */
+ unsigned long offset;
+};
struct saa7146_extension
{
char name[32]; /* name of the device */
- int inputs;
- int audios;
- u32 capabilities;
-
- int flags;
+ struct saa7146_ext_vv *ext_vv_data;
struct list_head item;
-
+
/* pairs of subvendor and subdevice ids for
supported devices, last entry 0xffff, 0xfff */
struct saa7146_sub_info *devices;
@@ -98,13 +83,6 @@ struct saa7146_extension
void (*inc_use)(struct saa7146_dev*);
void (*dec_use)(struct saa7146_dev*);
#endif
-
- /* additionally supported transmission standards */
- struct saa7146_standard *stds;
- int num_stds;
- int (*std_callback)(struct saa7146_dev*, struct saa7146_standard *);
-
- struct saa7146_extension_ioctls *ioctls;
/* extension functions */
int (*preinit)(struct saa7146_dev*);
@@ -113,106 +91,12 @@ struct saa7146_extension
int (*attach)(struct saa7146_dev*);
int (*detach)(struct saa7146_dev*);
- int (*ioctl)(struct saa7146_dev*, unsigned int cmd, void *arg);
-
u32 irq_mask; /* mask to indicate, which irq-events are handled by the extension */
void (*irq_func)(struct saa7146_dev*, u32* irq_mask);
};
-struct saa7146_video_dma {
- u32 base_odd;
- u32 base_even;
- u32 prot_addr;
- u32 pitch;
- u32 base_page;
- u32 num_line_byte;
-};
-
-struct saa7146_format {
- char *name;
- int pixelformat;
- u32 trans;
- u8 depth;
- unsigned long flags;
-};
-
-struct saa7146_standard
-{
- char *name;
- v4l2_std_id id;
-
- int v_offset;
- int v_field;
- int v_calc;
-
- int h_offset;
- int h_pixels;
- int h_calc;
-
- int v_max_out;
- int h_max_out;
-};
-
-/* saa7146 page table */
-struct saa7146_pgtable {
- unsigned int size;
- u32 *cpu;
- dma_addr_t dma;
- /* used for offsets for u,v planes for planar capture modes */
- unsigned long offset;
-};
-
-/* buffer for one video/vbi frame */
-struct saa7146_buf {
- /* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
-
- /* saa7146 specific */
- struct v4l2_pix_format *fmt;
- int (*activate)(struct saa7146_dev *dev,
- struct saa7146_buf *buf,
- struct saa7146_buf *next);
-
- /* page tables */
- struct saa7146_pgtable pt[3];
-};
-
-struct saa7146_dmaqueue {
- struct saa7146_dev *dev;
- struct saa7146_buf *curr;
- struct list_head queue;
- struct timer_list timeout;
-};
-
-struct saa7146_overlay {
- struct saa7146_fh *fh;
- struct v4l2_window win;
- struct v4l2_clip clips[16];
- int nclips;
-};
-
-/* per open data */
-struct saa7146_fh {
- struct saa7146_dev *dev;
- /* if this is a vbi or capture open */
- enum v4l2_buf_type type;
-
- /* video overlay */
- struct saa7146_overlay ov;
-
- /* video capture */
- struct videobuf_queue video_q;
- struct v4l2_pix_format video_fmt;
-
- /* vbi capture */
- struct videobuf_queue vbi_q;
- struct v4l2_vbi_format vbi_fmt;
- struct timer_list vbi_read_timeout;
-};
-
struct saa7146_dev
{
- /* used for loadable modules */
struct module *module;
struct list_head item;
@@ -220,7 +104,6 @@ struct saa7146_dev
/* different device locks */
spinlock_t slock;
struct semaphore lock;
- struct semaphore i2c_lock;
unsigned char *mem; /* pointer to mapped IO memory */
int revision; /* chip revision; needed for bug-workarounds*/
@@ -232,147 +115,41 @@ struct saa7146_dev
/* extension handling */
struct saa7146_extension *ext; /* indicates if handled by extension */
void *ext_priv; /* pointer for extension private use (most likely some private data) */
- int video_minor, vbi_minor;
- void (*video_irq_done)(struct saa7146_dev *dev, unsigned long status);
- void (*vbi_irq_done)(struct saa7146_dev *dev, unsigned long status);
+ /* per device video/vbi informations (if available) */
+ struct saa7146_vv *vv_data;
+ void (*vv_callback)(struct saa7146_dev *dev, unsigned long status);
/* i2c-stuff */
- u32 i2c_bitrate;
- u32 *i2c_mem; /* pointer to i2c memory */
- wait_queue_head_t i2c_wq;
- int i2c_op;
+ struct semaphore i2c_lock;
+ u32 i2c_bitrate;
+ u32 *i2c_mem; /* pointer to i2c memory */
+ wait_queue_head_t i2c_wq;
+ int i2c_op;
/* memories */
- u32 *clipping; /* pointer to clipping memory */
- u32 *rps0;
- u32 *rps1;
-
- /* vbi capture */
- struct saa7146_dmaqueue vbi_q;
- /* vbi workaround interrupt queue */
- wait_queue_head_t vbi_wq;
- int vbi_fieldcount;
- struct saa7146_fh *vbi_streaming;
-
- /* video overlay */
- struct v4l2_framebuffer ov_fb;
- struct saa7146_format *ov_fmt;
- struct saa7146_overlay *ov_data;
-
- /* video capture */
- struct saa7146_dmaqueue video_q;
- struct saa7146_fh *streaming;
-
- /* common: fixme? shouldn't this be in saa7146_fh?
- (this leads to a more complicated question: shall the driver
- store the different settings (for example S_INPUT) for every open
- and restore it appropriately, or should all settings be common for
- all opens? currently, we do the latter, like all other
- drivers do... */
- struct saa7146_standard *standard;
-
- int vflip;
- int hflip;
- int current_hps_source;
- int current_hps_sync;
-
-};
-
-struct saa7146_use_ops {
- void (*init)(struct saa7146_dev *dev);
- void(*open)(struct saa7146_dev *dev, struct saa7146_fh *fh);
- void (*release)(struct saa7146_dev *dev, struct saa7146_fh *fh,struct file *file);
- void (*irq_done)(struct saa7146_dev *dev, unsigned long status);
- ssize_t (*read)(struct file *file, char *data, size_t count, loff_t *ppos);
- int (*capture_begin)(struct saa7146_fh *fh);
- int (*capture_end)(struct saa7146_fh *fh);
+ u32 *rps0;
+ u32 *rps1;
};
-/* from saa7146_fops.c */
-int saa7146_register_device(struct video_device *vid, struct saa7146_dev* dev, char *name, int type);
-int saa7146_unregister_device(struct video_device *vid, struct saa7146_dev* dev);
-
/* from saa7146_i2c.c */
int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c_adapter, u32 bitrate);
int saa7146_i2c_transfer(struct saa7146_dev *saa, const struct i2c_msg msgs[], int num, int retries);
-/* from saa7146_hlp.c */
-void saa7146_set_overlay(struct saa7146_dev *dev, struct saa7146_fh *fh, int v);
-void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next);
-void saa7146_write_out_dma(struct saa7146_dev* dev, int which, struct saa7146_video_dma* vdma) ;
-
-void saa7146_set_hps_source_and_sync(struct saa7146_dev *saa, int source, int sync);
-void saa7146_set_gpio(struct saa7146_dev *saa, u8 pin, u8 data);
-
/* from saa7146_core.c */
extern struct list_head saa7146_devices;
extern struct semaphore saa7146_devices_lock;
-
int saa7146_register_extension(struct saa7146_extension*);
int saa7146_unregister_extension(struct saa7146_extension*);
struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc);
-
-void saa7146_buffer_finish(struct saa7146_dev *dev, struct saa7146_dmaqueue *q, int state);
-void saa7146_buffer_next(struct saa7146_dev *dev, struct saa7146_dmaqueue *q,int vbi);
-int saa7146_buffer_queue(struct saa7146_dev *dev, struct saa7146_dmaqueue *q, struct saa7146_buf *buf);
-void saa7146_buffer_timeout(unsigned long data);
-void saa7146_dma_free(struct saa7146_dev *dev,struct saa7146_buf *buf);
-
int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt);
void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt);
void saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt, struct scatterlist *list, int length );
-
-/* from saa7146_video.c */
-extern struct saa7146_use_ops saa7146_video_uops;
-
-/* from saa7146_vbi.c */
-extern struct saa7146_use_ops saa7146_vbi_uops;
-
-/* saa7146 source inputs */
-#define SAA7146_HPS_SOURCE_PORT_A 0x00
-#define SAA7146_HPS_SOURCE_PORT_B 0x01
-#define SAA7146_HPS_SOURCE_YPB_CPA 0x02
-#define SAA7146_HPS_SOURCE_YPA_CPB 0x03
-
-/* sync inputs */
-#define SAA7146_HPS_SYNC_PORT_A 0x00
-#define SAA7146_HPS_SYNC_PORT_B 0x01
-
-/* number of vertical active lines */
-#define V_ACTIVE_LINES_PAL 576
-#define V_ACTIVE_LINES_NTSC 480
-#define V_ACTIVE_LINES_SECAM 576
-
-/* number of lines in a field for HPS to process */
-#define V_FIELD_PAL 288
-#define V_FIELD_NTSC 240
-#define V_FIELD_SECAM 288
-
-/* number of lines of vertical offset before processing */
-#define V_OFFSET_PAL 0x17
-#define V_OFFSET_NTSC 0x16
-#define V_OFFSET_SECAM 0x14
-
-/* number of horizontal pixels to process */
-#define H_PIXELS_PAL 680
-#define H_PIXELS_NTSC 708
-#define H_PIXELS_SECAM 720
-
-/* horizontal offset of processing window */
-#define H_OFFSET_PAL 0x14
-#define H_OFFSET_NTSC 0x06
-#define H_OFFSET_SECAM 0x14
-
-#define SAA7146_PAL_VALUES V_OFFSET_PAL, V_FIELD_PAL, V_ACTIVE_LINES_PAL, H_OFFSET_PAL, H_PIXELS_PAL, H_PIXELS_PAL+1, V_ACTIVE_LINES_PAL, 768
-#define SAA7146_NTSC_VALUES V_OFFSET_NTSC, V_FIELD_NTSC, V_ACTIVE_LINES_NTSC, H_OFFSET_NTSC, H_PIXELS_NTSC, H_PIXELS_NTSC+1, V_ACTIVE_LINES_NTSC, 640
-#define SAA7146_SECAM_VALUES V_OFFSET_SECAM, V_FIELD_SECAM, V_ACTIVE_LINES_SECAM, H_OFFSET_SECAM, H_PIXELS_SECAM, H_PIXELS_SECAM+1, V_ACTIVE_LINES_SECAM, 768
+void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data);
/* some memory sizes */
-#define SAA7146_CLIPPING_MEM (14*PAGE_SIZE)
-#define SAA7146_RPS_MEM ( 1*PAGE_SIZE)
#define SAA7146_I2C_MEM ( 1*PAGE_SIZE)
-#define SAA7146_DEBI_MEM ( 8*PAGE_SIZE)
+#define SAA7146_RPS_MEM ( 1*PAGE_SIZE)
/* some i2c constants */
#define SAA7146_I2C_TIMEOUT 100 /* i2c-timeout-value in ms */
@@ -383,11 +160,13 @@ extern struct saa7146_use_ops saa7146_vbi_uops;
#define ME1 0x0000000800
#define PV1 0x0000000008
-/* some defines for the various clipping-modes */
-#define SAA7146_CLIPPING_RECT 0x4
-#define SAA7146_CLIPPING_RECT_INVERTED 0x5
-#define SAA7146_CLIPPING_MASK 0x6
-#define SAA7146_CLIPPING_MASK_INVERTED 0x7
+/* gpio defines */
+#define SAA7146_GPIO_INPUT 0x00
+#define SAA7146_GPIO_IRQHI 0x10
+#define SAA7146_GPIO_IRQLO 0x20
+#define SAA7146_GPIO_IRQHL 0x30
+#define SAA7146_GPIO_OUTLO 0x40
+#define SAA7146_GPIO_OUTHI 0x50
/* define for the register programming sequencer (rps) */
#define CMD_NOP 0x00000000 /* No operation */
@@ -415,29 +194,6 @@ extern struct saa7146_use_ops saa7146_vbi_uops;
#define CMD_O_FID_A MASK_12
#define CMD_E_FID_A MASK_11
-/* output formats: each entry holds four informations */
-#define RGB08_COMPOSED 0x0217 /* composed is used in the sense of "not-planar" */
-/* this means: planar?=0, yuv2rgb-conversation-mode=2, dither=yes(=1), format-mode = 7 */
-#define RGB15_COMPOSED 0x0213
-#define RGB16_COMPOSED 0x0210
-#define RGB24_COMPOSED 0x0201
-#define RGB32_COMPOSED 0x0202
-
-#define Y8 0x0006
-#define YUV411_COMPOSED 0x0003
-#define YUV422_COMPOSED 0x0000
-/* this means: planar?=1, yuv2rgb-conversion-mode=0, dither=no(=0), format-mode = b */
-#define YUV411_DECOMPOSED 0x100b
-#define YUV422_DECOMPOSED 0x1009
-#define YUV420_DECOMPOSED 0x100a
-
-#define IS_PLANAR(x) (x & 0xf000)
-
-/* misc defines */
-#define SAA7146_NO_SWAP (0x0)
-#define SAA7146_TWO_BYTE_SWAP (0x1)
-#define SAA7146_FOUR_BYTE_SWAP (0x2)
-
/* Bit mask constants */
#define MASK_00 0x00000001 /* Mask value for bit 0 */
#define MASK_01 0x00000002 /* Mask value for bit 1 */
diff --git a/linux/drivers/media/common/saa7146_core.c b/linux/drivers/media/common/saa7146_core.c
index 1ebb7ed36..1b4ca2222 100644
--- a/linux/drivers/media/common/saa7146_core.c
+++ b/linux/drivers/media/common/saa7146_core.c
@@ -116,9 +116,21 @@ void saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *p
}
/********************************************************************************/
+/* gpio functions */
+
+void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data)
+{
+ u32 val = 0;
+
+ val=saa7146_read(dev,GPIO_CTRL);
+ val&=~(0xff << (8*(port)));
+ val|=(data)<<(8*(port));
+ saa7146_write(dev, GPIO_CTRL, val);
+}
+
+/********************************************************************************/
/* interrupt handler */
-/* FIXME: here are dependencies to the video and vbi code... */
static void interrupt_hw(int irq, void *dev_id, struct pt_regs *regs)
{
struct saa7146_dev *dev = (struct saa7146_dev*)dev_id;
@@ -146,24 +158,16 @@ static void interrupt_hw(int irq, void *dev_id, struct pt_regs *regs)
}
if (0 != (isr & (MASK_27))) {
DEB_INT(("irq: RPS0 (0x%08x).\n",isr));
- if( 0 != dev->video_irq_done ) {
- dev->video_irq_done(dev,isr);
+ if( 0 != dev->vv_data && 0 != dev->vv_callback) {
+ dev->vv_callback(dev,isr);
}
isr &= ~MASK_27;
}
if (0 != (isr & (MASK_28))) {
- u32 mc2 = saa7146_read(dev, MC2);
- isr &= ~MASK_28;
- if( 0 != (mc2 & MASK_15)) {
- DEB_INT(("irq: RPS1 vbi workaround (0x%08x).\n",isr));
- wake_up(&dev->vbi_wq);
- saa7146_write(dev,MC2, MASK_31);
- return;
- }
- DEB_INT(("irq: RPS1 (0x%08x).\n",isr));
- if( 0 != dev->vbi_irq_done ) {
- dev->vbi_irq_done(dev,isr);
+ if( 0 != dev->vv_data && 0 != dev->vv_callback) {
+ dev->vv_callback(dev,isr);
}
+ isr &= ~MASK_28;
}
if (0 != (isr & (MASK_16|MASK_17))) {
u32 status = saa7146_read(dev, I2C_STATUS);
@@ -427,14 +431,9 @@ static int config_a_device(struct pci_dev *pci)
goto kmalloc_error_2;
memset(dev->rps1, 0x0, SAA7146_RPS_MEM);
- dev->clipping = (u32*)kmalloc(SAA7146_CLIPPING_MEM, GFP_KERNEL);
- if( NULL == dev->clipping )
- goto kmalloc_error_3;
- memset(dev->clipping, 0x0, SAA7146_CLIPPING_MEM);
-
dev->i2c_mem = (u32*)kmalloc(SAA7146_I2C_MEM, GFP_KERNEL);
if( NULL == dev->i2c_mem )
- goto kmalloc_error_4;
+ goto kmalloc_error_3;
memset(dev->i2c_mem, 0x00, SAA7146_I2C_MEM);
/* the rest + print status message */
@@ -459,13 +458,8 @@ static int config_a_device(struct pci_dev *pci)
dev->module = THIS_MODULE;
init_waitqueue_head(&dev->i2c_wq);
- dev->video_minor = -1;
- dev->vbi_minor = -1;
-
return try_match_device_to_extension(dev);
-kmalloc_error_4:
- kfree( dev->clipping );
kmalloc_error_3:
kfree( dev->rps1 );
kmalloc_error_2:
@@ -494,7 +488,6 @@ static void unconfig_a_device(struct saa7146_dev* dev)
/* free kernel memory */
kfree(dev->rps0 );
kfree(dev->rps1 );
- kfree(dev->clipping);
kfree(dev->i2c_mem);
iounmap(dev->mem);
@@ -586,6 +579,8 @@ EXPORT_SYMBOL_GPL(saa7146_pgtable_alloc);
EXPORT_SYMBOL_GPL(saa7146_pgtable_free);
EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single);
+EXPORT_SYMBOL_GPL(saa7146_setgpio);
+
EXPORT_SYMBOL_GPL(saa7146_i2c_transfer);
EXPORT_SYMBOL_GPL(saa7146_i2c_adapter_prepare);
EXPORT_SYMBOL_GPL(saa7146_debug);
diff --git a/linux/drivers/media/common/saa7146_fops.c b/linux/drivers/media/common/saa7146_fops.c
index d8202c65f..594b6a379 100644
--- a/linux/drivers/media/common/saa7146_fops.c
+++ b/linux/drivers/media/common/saa7146_fops.c
@@ -1,9 +1,10 @@
-#include "saa7146.h"
+#include "saa7146_vv.h"
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
#define KBUILD_MODNAME saa7146
#endif
-#define BOARD_CAN_DO_VBI(dev) (dev->revision != 0 && dev->vbi_minor != -1)
+#define BOARD_CAN_DO_VBI(dev) (dev->revision != 0 && dev->vv_data->vbi_minor != -1)
/********************************************************************************/
/* common dma functions */
@@ -148,7 +149,7 @@ void saa7146_buffer_timeout(unsigned long data)
/* file operations */
static
-int video_open(struct inode *inode, struct file *file)
+int fops_open(struct inode *inode, struct file *file)
{
unsigned int minor = minor(inode->i_rdev);
struct saa7146_dev *h = NULL, *dev = NULL;
@@ -165,11 +166,16 @@ int video_open(struct inode *inode, struct file *file)
list_for_each(list,&saa7146_devices) {
h = list_entry(list, struct saa7146_dev, item);
- DEB_D(("trying: %p @ major %d,%d\n",h,h->video_minor,h->vbi_minor));
- if (h->video_minor == minor) {
+ if( NULL == h->vv_data ) {
+ DEB_D(("device %p has not registered video devices.\n",h));
+ continue;
+ }
+ DEB_D(("trying: %p @ major %d,%d\n",h,h->vv_data->video_minor,h->vv_data->vbi_minor));
+
+ if (h->vv_data->video_minor == minor) {
dev = h;
}
- if (h->vbi_minor == minor) {
+ if (h->vv_data->vbi_minor == minor) {
type = V4L2_BUF_TYPE_VBI_CAPTURE;
dev = h;
}
@@ -212,10 +218,6 @@ int video_open(struct inode *inode, struct file *file)
fh->dev = dev;
fh->type = type;
- /* FIXME: what's this? */
- dev->current_hps_source = SAA7146_HPS_SOURCE_PORT_A;
- dev->current_hps_sync = SAA7146_HPS_SYNC_PORT_A;
-
saa7146_video_uops.open(dev,fh);
if( 0 != BOARD_CAN_DO_VBI(dev) ) {
saa7146_vbi_uops.open(dev,fh);
@@ -230,7 +232,7 @@ out:
return result;
}
-static int video_release(struct inode *inode, struct file *file)
+static int fops_release(struct inode *inode, struct file *file)
{
struct saa7146_fh *fh = file->private_data;
struct saa7146_dev *dev = fh->dev;
@@ -261,7 +263,7 @@ static int video_release(struct inode *inode, struct file *file)
}
int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg);
-static int video_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static int fops_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
/*
DEB_EE(("inode:%p, file:%p, cmd:%d, arg:%li\n",inode, file, cmd, arg));
@@ -269,7 +271,7 @@ static int video_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
return video_usercopy(inode, file, cmd, arg, saa7146_video_do_ioctl);
}
-static int video_mmap(struct file *file, struct vm_area_struct * vma)
+static int fops_mmap(struct file *file, struct vm_area_struct * vma)
{
struct saa7146_fh *fh = file->private_data;
struct saa7146_dev *dev = fh->dev;
@@ -293,7 +295,7 @@ static int video_mmap(struct file *file, struct vm_area_struct * vma)
return videobuf_mmap_mapper(vma,q);
}
-static unsigned int video_poll(struct file *file, struct poll_table_struct *wait)
+static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
{
struct saa7146_fh *fh = file->private_data;
struct saa7146_dev *dev = fh->dev;
@@ -325,7 +327,7 @@ static unsigned int video_poll(struct file *file, struct poll_table_struct *wait
return 0;
}
-static ssize_t video_read(struct file *file, char *data, size_t count, loff_t *ppos)
+static ssize_t fops_read(struct file *file, char *data, size_t count, loff_t *ppos)
{
struct saa7146_fh *fh = file->private_data;
struct saa7146_dev *dev = fh->dev;
@@ -349,15 +351,39 @@ static ssize_t video_read(struct file *file, char *data, size_t count, loff_t *p
static struct file_operations video_fops =
{
owner: THIS_MODULE,
- open: video_open,
- release: video_release,
- read: video_read,
- poll: video_poll,
- mmap: video_mmap,
- ioctl: video_ioctl,
+ open: fops_open,
+ release: fops_release,
+ read: fops_read,
+ poll: fops_poll,
+ mmap: fops_mmap,
+ ioctl: fops_ioctl,
llseek: no_llseek,
};
+void vv_callback(struct saa7146_dev *dev, unsigned long status)
+{
+ u32 isr = status;
+
+ DEB_EE(("dev:%p, isr:0x%08x\n",dev,status));
+
+ if (0 != (isr & (MASK_27))) {
+ DEB_INT(("irq: RPS0 (0x%08x).\n",isr));
+ saa7146_video_uops.irq_done(dev,isr);
+ }
+
+ if (0 != (isr & (MASK_28))) {
+ u32 mc2 = saa7146_read(dev, MC2);
+ if( 0 != (mc2 & MASK_15)) {
+ DEB_INT(("irq: RPS1 vbi workaround (0x%08x).\n",isr));
+ wake_up(&dev->vv_data->vbi_wq);
+ saa7146_write(dev,MC2, MASK_31);
+ return;
+ }
+ DEB_INT(("irq: RPS1 (0x%08x).\n",isr));
+ saa7146_vbi_uops.irq_done(dev,isr);
+ }
+}
+
static struct video_device device_template =
{
.hardware = VID_HARDWARE_SAA7146,
@@ -365,9 +391,57 @@ static struct video_device device_template =
.minor = -1,
};
+int saa7146_vv_init(struct saa7146_dev* dev)
+{
+ struct saa7146_vv *vv = kmalloc (sizeof(struct saa7146_vv),GFP_KERNEL);
+ if( NULL == vv ) {
+ ERR(("out of memory. aborting.\n"));
+ return -1;
+ }
+ memset(vv, 0x0, sizeof(*vv));
+
+ DEB_EE(("dev:%p\n",dev));
+
+ vv->video_minor = -1;
+ vv->vbi_minor = -1;
+
+ vv->clipping = (u32*)kmalloc(SAA7146_CLIPPING_MEM, GFP_KERNEL);
+ if( NULL == vv->clipping ) {
+ ERR(("out of memory. aborting.\n"));
+ kfree(vv);
+ return -1;
+ }
+ memset(vv->clipping, 0x0, SAA7146_CLIPPING_MEM);
+
+ saa7146_video_uops.init(dev,vv);
+ saa7146_vbi_uops.init(dev,vv);
+
+ dev->vv_data = vv;
+ dev->vv_callback = &vv_callback;
+
+ return 0;
+}
+
+int saa7146_vv_release(struct saa7146_dev* dev)
+{
+ struct saa7146_vv *vv = dev->vv_data;
+
+ DEB_EE(("dev:%p\n",dev));
+
+ kfree(vv);
+ dev->vv_data = NULL;
+ dev->vv_callback = NULL;
+
+ return 0;
+}
+
int saa7146_register_device(struct video_device *vid, struct saa7146_dev* dev, char *name, int type)
{
- *vid = device_template;
+ struct saa7146_vv *vv = dev->vv_data;
+
+ DEB_EE(("dev:%p, name:'%s'\n",dev,name));
+
+ *vid = device_template;
strncpy(vid->name, name, 32);
vid->priv = dev;
@@ -378,25 +452,29 @@ int saa7146_register_device(struct video_device *vid, struct saa7146_dev* dev, c
}
if( VFL_TYPE_GRABBER == type ) {
- dev->video_minor = vid->minor;
+ vv->video_minor = vid->minor;
INFO(("%s: registered device video%d [v4l2]\n", dev->name,vid->minor & 0x1f));
} else {
- dev->vbi_minor = vid->minor;
+ vv->vbi_minor = vid->minor;
INFO(("%s: registered device vbi%d [v4l2]\n", dev->name,vid->minor & 0x1f));
}
+
return 0;
}
int saa7146_unregister_device(struct video_device *vid, struct saa7146_dev* dev)
{
+ struct saa7146_vv *vv = dev->vv_data;
+
+ DEB_EE(("dev:%p\n",dev));
+
if( VFL_TYPE_GRABBER == vid->type ) {
- dev->video_minor = -1;
- dev->video_irq_done = saa7146_video_uops.irq_done;
+ vv->video_minor = -1;
} else {
- dev->vbi_minor = -1;
- dev->vbi_irq_done = saa7146_vbi_uops.irq_done;
+ vv->vbi_minor = -1;
}
video_unregister_device(vid);
+
return 0;
}
@@ -419,8 +497,9 @@ EXPORT_SYMBOL_GPL(saa7146_set_hps_source_and_sync);
EXPORT_SYMBOL_GPL(saa7146_register_device);
EXPORT_SYMBOL_GPL(saa7146_unregister_device);
+EXPORT_SYMBOL_GPL(saa7146_vv_init);
+EXPORT_SYMBOL_GPL(saa7146_vv_release);
+
MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
MODULE_DESCRIPTION("video4linux driver for saa7146-based hardware");
MODULE_LICENSE("GPL");
-
-
diff --git a/linux/drivers/media/common/saa7146_hlp.c b/linux/drivers/media/common/saa7146_hlp.c
index 618ad3514..e2bb66125 100644
--- a/linux/drivers/media/common/saa7146_hlp.c
+++ b/linux/drivers/media/common/saa7146_hlp.c
@@ -1,4 +1,5 @@
-#include "saa7146.h"
+#include "saa7146_vv.h"
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
#define KBUILD_MODNAME saa7146
#endif
@@ -31,12 +32,12 @@ void calculate_hps_source_and_sync(struct saa7146_dev *dev, int source, int sync
}
static
-void calculate_hxo_and_hyo(struct saa7146_dev *dev, u32* hps_h_scale, u32* hps_ctrl)
+void calculate_hxo_and_hyo(struct saa7146_vv *vv, u32* hps_h_scale, u32* hps_ctrl)
{
int hyo = 0, hxo = 0;
- hyo = dev->standard->v_offset;
- hxo = dev->standard->h_offset;
+ hyo = vv->standard->v_offset;
+ hxo = vv->standard->h_offset;
*hps_h_scale &= ~(MASK_B0 | 0xf00);
*hps_h_scale |= (hxo << 0);
@@ -358,11 +359,12 @@ static
void calculate_clipping_registers_rect(struct saa7146_dev *dev, struct saa7146_fh *fh,
struct saa7146_video_dma *vdma2, u32* clip_format, u32* arbtr_ctrl, enum v4l2_field field)
{
- int td_flip = dev->vflip;
+ struct saa7146_vv *vv = dev->vv_data;
+ u32 *clipping = vv->clipping;
+
int width = fh->ov.win.w.width;
int height = fh->ov.win.w.height;
int clipcount = fh->ov.nclips;
- u32 *clipping = dev->clipping;
u32 line_list[32];
u32 pixel_list[32];
@@ -378,7 +380,6 @@ void calculate_clipping_registers_rect(struct saa7146_dev *dev, struct saa7146_f
memset(&pixel_list[0], 0x00, sizeof(u32)*32);
memset(clipping, 0x00, SAA7146_CLIPPING_MEM);
-
/* fill the line and pixel-lists */
for(i = 0; i < clipcount; i++) {
int l = 0, r = 0, t = 0, b = 0;
@@ -400,7 +401,7 @@ void calculate_clipping_registers_rect(struct saa7146_dev *dev, struct saa7146_f
if( y[i] < 0) {
h[i] += y[i]; y[i] = 0;
}
- if( 0 != td_flip ) {
+ if( 0 != vv->vflip ) {
y[i] = height - y[i] - h[i];
}
@@ -549,25 +550,26 @@ void saa7146_set_clipping_rect(struct saa7146_dev *dev, struct saa7146_fh *fh)
static
void saa7146_set_window(struct saa7146_dev *dev, int width, int height, enum v4l2_field field)
{
- int flip_lr = dev->hflip;
- int source = dev->current_hps_source;
- int sync = dev->current_hps_sync;
+ struct saa7146_vv *vv = dev->vv_data;
+
+ int source = vv->current_hps_source;
+ int sync = vv->current_hps_sync;
u32 hps_v_scale = 0, hps_v_gain = 0, hps_ctrl = 0, hps_h_prescale = 0, hps_h_scale = 0;
/* set vertical scale */
hps_v_scale = 0; /* all bits get set by the function-call */
hps_v_gain = 0; /* fixme: saa7146_read(dev, HPS_V_GAIN);*/
- calculate_v_scale_registers(dev, field, dev->standard->v_calc, height, &hps_v_scale, &hps_v_gain);
+ calculate_v_scale_registers(dev, field, vv->standard->v_calc, height, &hps_v_scale, &hps_v_gain);
/* set horizontal scale */
hps_ctrl = 0;
hps_h_prescale = 0; /* all bits get set in the function */
hps_h_scale = 0;
- calculate_h_scale_registers(dev, dev->standard->h_calc, width, flip_lr, &hps_ctrl, &hps_v_gain, &hps_h_prescale, &hps_h_scale);
+ calculate_h_scale_registers(dev, vv->standard->h_calc, width, vv->hflip, &hps_ctrl, &hps_v_gain, &hps_h_prescale, &hps_h_scale);
/* set hyo and hxo */
- calculate_hxo_and_hyo(dev, &hps_h_scale, &hps_ctrl);
+ calculate_hxo_and_hyo(vv, &hps_h_scale, &hps_ctrl);
calculate_hps_source_and_sync(dev, source, sync, &hps_ctrl);
/* write out new register contents */
@@ -585,16 +587,17 @@ void saa7146_set_window(struct saa7146_dev *dev, int width, int height, enum v4l
static
void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int w_height, enum v4l2_field field)
{
- int td_flip = dev->vflip;
- int b_depth = dev->ov_fmt->depth;
- int b_bpl = dev->ov_fb.fmt.bytesperline;
- u32 base = (u32)dev->ov_fb.base;
+ struct saa7146_vv *vv = dev->vv_data;
+
+ int b_depth = vv->ov_fmt->depth;
+ int b_bpl = vv->ov_fb.fmt.bytesperline;
+ u32 base = (u32)vv->ov_fb.base;
struct saa7146_video_dma vdma1;
/* calculate memory offsets for picture, look if we shall top-down-flip */
vdma1.pitch = 2*b_bpl;
- if ( 0 == td_flip ) {
+ if ( 0 == vv->vflip ) {
vdma1.base_even = (u32)base + (w_y * (vdma1.pitch/2)) + (w_x * (b_depth / 8));
vdma1.base_odd = vdma1.base_even + (vdma1.pitch / 2);
vdma1.prot_addr = vdma1.base_even + (w_height * (vdma1.pitch / 2));
@@ -615,12 +618,12 @@ void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int w_heigh
vdma1.pitch /= 2;
}
- if ( 0 != td_flip ) {
+ if ( 0 != vv->vflip ) {
vdma1.pitch *= -1;
}
vdma1.base_page = 0;
- vdma1.num_line_byte = (dev->standard->v_field<<16)+dev->standard->h_pixels;
+ vdma1.num_line_byte = (vv->standard->v_field<<16)+vv->standard->h_pixels;
saa7146_write_out_dma(dev, 1, &vdma1);
}
@@ -628,7 +631,7 @@ void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int w_heigh
static
void saa7146_set_output_format(struct saa7146_dev *dev, unsigned long palette)
{
- u32 clip_format = saa7146_read(dev, CLIP_FORMAT_CTRL);
+ u32 clip_format = saa7146_read(dev, CLIP_FORMAT_CTRL);
/* call helper function */
calculate_output_format_register(dev,palette,&clip_format);
@@ -653,6 +656,7 @@ void saa7146_set_picture_prop(struct saa7146_dev *dev, int brightness, int contr
/* select input-source */
void saa7146_set_hps_source_and_sync(struct saa7146_dev *dev, int source, int sync)
{
+ struct saa7146_vv *vv = dev->vv_data;
u32 hps_ctrl = 0;
/* read old state */
@@ -665,8 +669,8 @@ void saa7146_set_hps_source_and_sync(struct saa7146_dev *dev, int source, int sy
saa7146_write(dev, HPS_CTRL, hps_ctrl);
saa7146_write(dev, MC2, (MASK_05 | MASK_21));
- dev->current_hps_source = source;
- dev->current_hps_sync = sync;
+ vv->current_hps_source = source;
+ vv->current_hps_sync = sync;
}
/* write "data" to the gpio-pin "pin" */
@@ -690,6 +694,8 @@ void saa7146_set_gpio(struct saa7146_dev *dev, u8 pin, u8 data)
/* reprogram hps, enable(1) / disable(0) video */
void saa7146_set_overlay(struct saa7146_dev *dev, struct saa7146_fh *fh, int v)
{
+ struct saa7146_vv *vv = dev->vv_data;
+
/* enable ? */
if( 0 == v) {
/* disable video dma1 */
@@ -699,7 +705,7 @@ void saa7146_set_overlay(struct saa7146_dev *dev, struct saa7146_fh *fh, int v)
saa7146_set_window(dev, fh->ov.win.w.width, fh->ov.win.w.height, fh->ov.win.field);
saa7146_set_position(dev, fh->ov.win.w.left, fh->ov.win.w.top, fh->ov.win.w.height, fh->ov.win.field);
- saa7146_set_output_format(dev, dev->ov_fmt->trans);
+ saa7146_set_output_format(dev, vv->ov_fmt->trans);
saa7146_set_clipping_rect(dev, fh);
/* enable video dma1 */
@@ -708,6 +714,7 @@ void saa7146_set_overlay(struct saa7146_dev *dev, struct saa7146_fh *fh, int v)
void saa7146_write_out_dma(struct saa7146_dev* dev, int which, struct saa7146_video_dma* vdma)
{
+ struct saa7146_vv *vv = dev->vv_data;
int where = 0;
if( which < 1 || which > 3) {
@@ -717,7 +724,7 @@ void saa7146_write_out_dma(struct saa7146_dev* dev, int which, struct saa7146_vi
/* calculate starting address */
where = (which-1)*0x18;
- if( 0 != (dev->ext->flags & SAA7146_EXT_SWAP_ODD_EVEN)) {
+ if( 0 != (dev->ext->ext_vv_data->flags & SAA7146_EXT_SWAP_ODD_EVEN)) {
saa7146_write(dev, where, vdma->base_even);
saa7146_write(dev, where+0x04, vdma->base_odd);
} else {
@@ -743,12 +750,11 @@ void saa7146_write_out_dma(struct saa7146_dev* dev, int which, struct saa7146_vi
static
int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa7146_buf *buf)
{
+ struct saa7146_vv *vv = dev->vv_data;
struct saa7146_video_dma vdma1;
struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
- int flip_td = dev->vflip;
-
int width = buf->fmt->width;
int height = buf->fmt->height;
enum v4l2_field field = buf->fmt->field;
@@ -760,10 +766,10 @@ int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa7146_buf
width,height,v4l2_field_names[field],flags));
vdma1.pitch = (width*depth*2)/8;
- vdma1.num_line_byte = ((dev->standard->v_field<<16) + dev->standard->h_pixels);
+ vdma1.num_line_byte = ((vv->standard->v_field<<16) + vv->standard->h_pixels);
vdma1.base_page = buf->pt[0].dma | ME1 | flags;
- if( 0 != flip_td ) {
+ if( 0 != vv->vflip ) {
vdma1.prot_addr = buf->pt[0].offset;
vdma1.base_even = buf->pt[0].offset+(vdma1.pitch/2)*height;
vdma1.base_odd = vdma1.base_even - (vdma1.pitch/2);
@@ -783,7 +789,7 @@ int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa7146_buf
vdma1.pitch /= 2;
}
- if( 0 != flip_td ) {
+ if( 0 != vv->vflip ) {
vdma1.pitch *= -1;
}
@@ -794,14 +800,13 @@ int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa7146_buf
static
int calculate_video_dma_grab_planar(struct saa7146_dev* dev, struct saa7146_buf *buf)
{
+ struct saa7146_vv *vv = dev->vv_data;
struct saa7146_video_dma vdma1;
struct saa7146_video_dma vdma2;
struct saa7146_video_dma vdma3;
struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
- int flip_td = dev->vflip;
-
int width = buf->fmt->width;
int height = buf->fmt->height;
enum v4l2_field field = buf->fmt->field;
@@ -816,7 +821,7 @@ int calculate_video_dma_grab_planar(struct saa7146_dev* dev, struct saa7146_buf
width,height,v4l2_field_names[field],flags));
vdma1.pitch = width*2;
- vdma1.num_line_byte = ((dev->standard->v_field<<16) + dev->standard->h_pixels);
+ vdma1.num_line_byte = ((vv->standard->v_field<<16) + vv->standard->h_pixels);
vdma1.base_page = buf->pt[0].dma | ME1 | flags;
/* fscking saa7146! due to the "byte-swap bug", video-dma2
@@ -836,7 +841,7 @@ int calculate_video_dma_grab_planar(struct saa7146_dev* dev, struct saa7146_buf
most likely wrong, this version here only works for page-aligned
buffers, modifications to the pagetable-functions are necessary...*/
- if( 0 != flip_td ) {
+ if( 0 != vv->vflip ) {
vdma1.prot_addr = buf->pt[0].offset;
vdma1.base_even = ((vdma1.pitch/2)*height)+buf->pt[0].offset;
vdma1.base_odd = vdma1.base_even - (vdma1.pitch/2);
@@ -884,7 +889,7 @@ int calculate_video_dma_grab_planar(struct saa7146_dev* dev, struct saa7146_buf
vdma3.pitch /= 2;
}
- if( 0 != flip_td ) {
+ if( 0 != vv->vflip ) {
vdma1.pitch *= -1;
vdma2.pitch *= -1;
vdma3.pitch *= -1;
@@ -900,10 +905,11 @@ int calculate_video_dma_grab_planar(struct saa7146_dev* dev, struct saa7146_buf
static
void program_capture_engine(struct saa7146_dev *dev, int planar)
{
+ struct saa7146_vv *vv = dev->vv_data;
int count = 0;
- unsigned long e_wait = dev->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_E_FID_A : CMD_E_FID_B;
- unsigned long o_wait = dev->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B;
+ unsigned long e_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_E_FID_A : CMD_E_FID_B;
+ unsigned long o_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B;
/* write beginning of rps-program */
count = 0;
diff --git a/linux/drivers/media/common/saa7146_vbi.c b/linux/drivers/media/common/saa7146_vbi.c
index 1b880ff9c..96ab61028 100644
--- a/linux/drivers/media/common/saa7146_vbi.c
+++ b/linux/drivers/media/common/saa7146_vbi.c
@@ -1,4 +1,5 @@
-#include "saa7146.h"
+#include "saa7146_vv.h"
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
#define KBUILD_MODNAME saa7146
#endif
@@ -8,6 +9,8 @@ static int vbi_pixel_to_capture = 720 * 2;
static
int vbi_workaround(struct saa7146_dev *dev)
{
+ struct saa7146_vv *vv = dev->vv_data;
+
u32 *cpu;
dma_addr_t dma_addr;
@@ -88,7 +91,7 @@ int vbi_workaround(struct saa7146_dev *dev)
IER_ENABLE(dev,MASK_28);
/* prepare to wait to be woken up by the irq-handler */
- add_wait_queue(&dev->vbi_wq, &wait);
+ add_wait_queue(&vv->vbi_wq, &wait);
current->state = TASK_INTERRUPTIBLE;
/* start rps1 to enable workaround */
@@ -99,7 +102,7 @@ int vbi_workaround(struct saa7146_dev *dev)
DEB_VBI(("brs bug workaround %d/1.\n",i));
- remove_wait_queue(&dev->vbi_wq, &wait);
+ remove_wait_queue(&vv->vbi_wq, &wait);
current->state = TASK_RUNNING;
/* disable rps1 irqs */
@@ -126,11 +129,13 @@ int vbi_workaround(struct saa7146_dev *dev)
void saa7146_set_vbi_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next)
{
+ struct saa7146_vv *vv = dev->vv_data;
+
struct saa7146_video_dma vdma3;
int count = 0;
- unsigned long e_wait = dev->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_E_FID_A : CMD_E_FID_B;
- unsigned long o_wait = dev->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B;
+ unsigned long e_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_E_FID_A : CMD_E_FID_B;
+ unsigned long o_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B;
/*
vdma3.base_even = (u32)dev->ov_fb.base+2048*70;
@@ -196,12 +201,13 @@ int buffer_activate(struct saa7146_dev *dev,
struct saa7146_buf *buf,
struct saa7146_buf *next)
{
+ struct saa7146_vv *vv = dev->vv_data;
buf->vb.state = STATE_ACTIVE;
DEB_VBI(("dev:%p, buf:%p, next:%p\n",dev,buf,next));
saa7146_set_vbi_capture(dev,buf,next);
- mod_timer(&dev->vbi_q.timeout, jiffies+BUFFER_TIMEOUT);
+ mod_timer(&vv->vbi_q.timeout, jiffies+BUFFER_TIMEOUT);
return 0;
}
@@ -277,10 +283,11 @@ void buffer_queue(struct file *file, struct videobuf_buffer *vb)
{
struct saa7146_fh *fh = file->private_data;
struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
struct saa7146_buf *buf = (struct saa7146_buf *)vb;
DEB_VBI(("vb:%p\n",vb));
- saa7146_buffer_queue(dev,&dev->vbi_q,buf);
+ saa7146_buffer_queue(dev,&vv->vbi_q,buf);
}
static
@@ -308,6 +315,7 @@ static
void vbi_stop(struct saa7146_fh *fh)
{
struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
unsigned long flags;
DEB_VBI(("dev:%p, fh:%p\n",dev, fh));
@@ -322,7 +330,7 @@ void vbi_stop(struct saa7146_fh *fh)
/* shut down dma 3 transfers */
saa7146_write(dev, MC1, MASK_20);
- dev->vbi_streaming = NULL;
+ vv->vbi_streaming = NULL;
spin_unlock_irqrestore(&dev->slock, flags);
}
@@ -338,21 +346,25 @@ void vbi_read_timeout(unsigned long data)
}
static
-void vbi_init(struct saa7146_dev *dev)
+void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
{
- INIT_LIST_HEAD(&dev->vbi_q.queue);
+ DEB_VBI(("dev:%p\n",dev));
+
+ INIT_LIST_HEAD(&vv->vbi_q.queue);
- init_timer(&dev->vbi_q.timeout);
- dev->vbi_q.timeout.function = saa7146_buffer_timeout;
- dev->vbi_q.timeout.data = (unsigned long)(&dev->vbi_q);
- dev->vbi_q.dev = dev;
+ init_timer(&vv->vbi_q.timeout);
+ vv->vbi_q.timeout.function = saa7146_buffer_timeout;
+ vv->vbi_q.timeout.data = (unsigned long)(&vv->vbi_q);
+ vv->vbi_q.dev = dev;
- init_waitqueue_head(&dev->vbi_wq);
+ init_waitqueue_head(&vv->vbi_wq);
}
static
void vbi_open(struct saa7146_dev *dev, struct saa7146_fh *fh)
{
+ DEB_VBI(("dev:%p, fh:%p\n",dev,fh));
+
memset(&fh->vbi_fmt,0,sizeof(fh->vbi_fmt));
fh->vbi_fmt.sampling_rate = 27000000;
@@ -382,7 +394,10 @@ void vbi_open(struct saa7146_dev *dev, struct saa7146_fh *fh)
static
void vbi_close(struct saa7146_dev *dev, struct saa7146_fh *fh, struct file *file)
{
- if( fh == dev->vbi_streaming ) {
+ struct saa7146_vv *vv = dev->vv_data;
+ DEB_VBI(("dev:%p, fh:%p\n",dev,fh));
+
+ if( fh == vv->vbi_streaming ) {
vbi_stop(fh);
}
}
@@ -390,18 +405,19 @@ void vbi_close(struct saa7146_dev *dev, struct saa7146_fh *fh, struct file *file
static
void vbi_irq_done(struct saa7146_dev *dev, unsigned long status)
{
+ struct saa7146_vv *vv = dev->vv_data;
spin_lock(&dev->slock);
- if (dev->vbi_q.curr) {
- DEB_VBI(("dev:%p, curr:%p\n",dev,dev->vbi_q.curr));
+ if (vv->vbi_q.curr) {
+ DEB_VBI(("dev:%p, curr:%p\n",dev,vv->vbi_q.curr));
/* this must be += 2, one count for each field */
- dev->vbi_fieldcount+=2;
- dev->vbi_q.curr->vb.field_count = dev->vbi_fieldcount;
- saa7146_buffer_finish(dev,&dev->vbi_q,STATE_DONE);
+ vv->vbi_fieldcount+=2;
+ vv->vbi_q.curr->vb.field_count = vv->vbi_fieldcount;
+ saa7146_buffer_finish(dev,&vv->vbi_q,STATE_DONE);
} else {
DEB_VBI(("dev:%p\n",dev));
}
- saa7146_buffer_next(dev,&dev->vbi_q,1);
+ saa7146_buffer_next(dev,&vv->vbi_q,1);
spin_unlock(&dev->slock);
}
@@ -411,18 +427,19 @@ ssize_t vbi_read(struct file *file, char *data, size_t count, loff_t *ppos)
{
struct saa7146_fh *fh = file->private_data;
struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
ssize_t ret = 0;
DEB_VBI(("dev:%p, fh:%p\n",dev,fh));
- if( NULL == dev->vbi_streaming ) {
+ if( NULL == vv->vbi_streaming ) {
// fixme: check if dma3 is available
// fixme: activate vbi engine here if necessary. (really?)
- dev->vbi_streaming = fh;
+ vv->vbi_streaming = fh;
}
- if( fh != dev->vbi_streaming ) {
- DEB_VBI(("open %p is already using vbi capture.",dev->vbi_streaming));
+ if( fh != vv->vbi_streaming ) {
+ DEB_VBI(("open %p is already using vbi capture.",vv->vbi_streaming));
return -EBUSY;
}
diff --git a/linux/drivers/media/common/saa7146_video.c b/linux/drivers/media/common/saa7146_video.c
index 2038e4748..8a2d83c98 100644
--- a/linux/drivers/media/common/saa7146_video.c
+++ b/linux/drivers/media/common/saa7146_video.c
@@ -1,4 +1,5 @@
-#include "saa7146.h"
+#include "saa7146_vv.h"
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
#define KBUILD_MODNAME saa7146
#endif
@@ -76,16 +77,17 @@ int g_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
static
int try_win(struct saa7146_dev *dev, struct v4l2_window *win)
{
+ struct saa7146_vv *vv = dev->vv_data;
enum v4l2_field field;
int maxw, maxh;
DEB_EE(("dev:%p\n",dev));
- if (NULL == dev->ov_fb.base) {
+ if (NULL == vv->ov_fb.base) {
DEB_D(("no fb base set.\n"));
return -EINVAL;
}
- if (NULL == dev->ov_fmt) {
+ if (NULL == vv->ov_fmt) {
DEB_D(("no fb fmt set.\n"));
return -EINVAL;
}
@@ -99,8 +101,8 @@ int try_win(struct saa7146_dev *dev, struct v4l2_window *win)
}
field = win->field;
- maxw = dev->standard->h_max_out;
- maxh = dev->standard->v_max_out;
+ maxw = vv->standard->h_max_out;
+ maxh = vv->standard->v_max_out;
if (V4L2_FIELD_ANY == field) {
field = (win->w.height > maxh/2)
@@ -133,6 +135,7 @@ static
int try_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
{
struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
int err;
switch (f->type) {
@@ -150,8 +153,8 @@ int try_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
}
field = f->fmt.pix.field;
- maxw = dev->standard->h_max_out;
- maxh = dev->standard->v_max_out;
+ maxw = vv->standard->h_max_out;
+ maxh = vv->standard->v_max_out;
if (V4L2_FIELD_ANY == field) {
field = (f->fmt.pix.height > maxh/2)
@@ -197,6 +200,7 @@ static
int start_preview(struct saa7146_fh *fh)
{
struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
int err = 0;
DEB_EE(("dev:%p, fh:%p\n",dev,fh));
@@ -208,8 +212,8 @@ int start_preview(struct saa7146_fh *fh)
}
/* check if overlay is running */
- if( 0 != dev->ov_data ) {
- if( fh != dev->ov_data->fh ) {
+ if( 0 != vv->ov_data ) {
+ if( fh != vv->ov_data->fh ) {
DEB_D(("overlay is running in another open.\n"));
return -EAGAIN;
}
@@ -217,7 +221,7 @@ int start_preview(struct saa7146_fh *fh)
return 0;
}
- if( 0 != dev->streaming ) {
+ if( 0 != vv->streaming ) {
DEB_D(("streaming capture is active.\n"));
return -EBUSY;
}
@@ -227,12 +231,12 @@ int start_preview(struct saa7146_fh *fh)
return err;
}
- dev->ov_data = &fh->ov;
+ vv->ov_data = &fh->ov;
DEB_D(("%dx%d+%d+%d %s field=%s\n",
fh->ov.win.w.width,fh->ov.win.w.height,
fh->ov.win.w.left,fh->ov.win.w.top,
- dev->ov_fmt->name,v4l2_field_names[fh->ov.win.field]));
+ vv->ov_fmt->name,v4l2_field_names[fh->ov.win.field]));
saa7146_set_overlay(dev, fh, 1);
@@ -243,21 +247,23 @@ static
int stop_preview(struct saa7146_fh *fh)
{
struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+
DEB_EE(("saa7146.o: stop_preview()\n"));
/* check if overlay is running */
- if( 0 == dev->ov_data ) {
+ if( 0 == vv->ov_data ) {
DEB_D(("overlay is not active.\n"));
return 0;
}
- if( fh != dev->ov_data->fh ) {
+ if( fh != vv->ov_data->fh ) {
DEB_D(("overlay is active, but for another open.\n"));
return -EBUSY;
}
saa7146_set_overlay(dev, fh, 0);
- dev->ov_data = NULL;
+ vv->ov_data = NULL;
return 0;
}
@@ -266,6 +272,7 @@ static
int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
{
struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
unsigned long flags;
int err;
@@ -273,7 +280,7 @@ int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh));
- if( fh == dev->streaming ) {
+ if( fh == vv->streaming ) {
DEB_EE(("streaming capture is active"));
return -EAGAIN;
}
@@ -302,8 +309,8 @@ int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
fh->ov.fh = fh;
/* check if we have an active overlay */
- if( dev->ov_data != NULL ) {
- if( fh == dev->ov_data->fh) {
+ if( vv->ov_data != NULL ) {
+ if( fh == vv->ov_data->fh) {
spin_lock_irqsave(&dev->slock,flags);
stop_preview(fh);
start_preview(fh);
@@ -381,6 +388,8 @@ static
int get_control(struct saa7146_fh *fh, struct v4l2_control *c)
{
struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+
const struct v4l2_queryctrl* ctrl;
u32 value = 0;
@@ -401,10 +410,10 @@ int get_control(struct saa7146_fh *fh, struct v4l2_control *c)
c->value = 0x7f & (value >> 0);
break;
case V4L2_CID_VFLIP:
- c->value = dev->vflip;
+ c->value = vv->vflip;
break;
case V4L2_CID_HFLIP:
- c->value = dev->hflip;
+ c->value = vv->hflip;
break;
default:
return -EINVAL;
@@ -417,6 +426,8 @@ static
int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
{
struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+
const struct v4l2_queryctrl* ctrl;
unsigned long flags;
int restart_overlay = 0;
@@ -467,19 +478,19 @@ int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
}
case V4L2_CID_HFLIP:
/* fixme: we can supfhrt changing VFLIP and HFLIP here... */
- if( 0 != dev->streaming ) {
+ if( 0 != vv->streaming ) {
DEB_D(("V4L2_CID_HFLIP while active capture.\n"));
return -EINVAL;
}
- dev->hflip = c->value;
+ vv->hflip = c->value;
restart_overlay = 1;
break;
case V4L2_CID_VFLIP:
- if( 0 != dev->streaming ) {
+ if( 0 != vv->streaming ) {
DEB_D(("V4L2_CID_VFLIP while active capture.\n"));
return -EINVAL;
}
- dev->vflip = c->value;
+ vv->vflip = c->value;
restart_overlay = 1;
break;
default: {
@@ -487,8 +498,8 @@ int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
}
}
if( 0 != restart_overlay ) {
- if( 0 != dev->ov_data ) {
- if( fh == dev->ov_data->fh ) {
+ if( 0 != vv->ov_data ) {
+ if( fh == vv->ov_data->fh ) {
spin_lock_irqsave(&dev->slock,flags);
stop_preview(fh);
start_preview(fh);
@@ -606,15 +617,16 @@ static
int video_begin(struct saa7146_fh *fh)
{
struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
unsigned long flags;
DEB_EE(("dev:%p, fh:%p\n",dev,fh));
- if( fh == dev->streaming ) {
+ if( fh == vv->streaming ) {
DEB_S(("already capturing.\n"));
return 0;
}
- if( dev->streaming != 0 ) {
+ if( vv->streaming != 0 ) {
DEB_S(("already capturing, but in another open.\n"));
return -EBUSY;
}
@@ -630,7 +642,7 @@ int video_begin(struct saa7146_fh *fh)
/* enable rps0 irqs */
IER_ENABLE(dev, MASK_27);
- dev->streaming = fh;
+ vv->streaming = fh;
spin_unlock_irqrestore(&dev->slock,flags);
return 0;
}
@@ -639,11 +651,12 @@ static
int video_end(struct saa7146_fh *fh)
{
struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
unsigned long flags;
DEB_EE(("dev:%p, fh:%p\n",dev,fh));
- if( dev->streaming != fh ) {
+ if( vv->streaming != fh ) {
DEB_S(("not capturing.\n"));
return -EINVAL;
}
@@ -665,7 +678,7 @@ int video_end(struct saa7146_fh *fh)
video-dma3, but video_end should not get called anyway ...*/
saa7146_write(dev, MC1, 0x00700000);
- dev->streaming = NULL;
+ vv->streaming = NULL;
spin_unlock_irqrestore(&dev->slock, flags);
return 0;
@@ -681,6 +694,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
{
struct saa7146_fh *fh = file->private_data;
struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
unsigned long flags;
int err = 0, result = 0, ee = 0;
@@ -689,19 +703,19 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
struct videobuf_queue *q;
/* check if extension handles the command */
- for(ee = 0; dev->ext->ioctls[ee].flags != 0; ee++) {
- if( cmd == dev->ext->ioctls[ee].cmd )
+ for(ee = 0; dev->ext->ext_vv_data->ioctls[ee].flags != 0; ee++) {
+ if( cmd == dev->ext->ext_vv_data->ioctls[ee].cmd )
break;
}
- if( 0 != (dev->ext->ioctls[ee].flags & SAA7146_EXCLUSIVE) ) {
+ if( 0 != (dev->ext->ext_vv_data->ioctls[ee].flags & SAA7146_EXCLUSIVE) ) {
DEB_D(("extension handles ioctl exclusive.\n"));
- result = dev->ext->ioctl(dev, cmd, arg);
+ result = dev->ext->ext_vv_data->ioctl(dev, cmd, arg);
return result;
}
- if( 0 != (dev->ext->ioctls[ee].flags & SAA7146_BEFORE) ) {
+ if( 0 != (dev->ext->ext_vv_data->ioctls[ee].flags & SAA7146_BEFORE) ) {
DEB_D(("extension handles ioctl before.\n"));
- result = dev->ext->ioctl(dev, cmd, arg);
+ result = dev->ext->ext_vv_data->ioctl(dev, cmd, arg);
if( -EAGAIN != result ) {
return result;
}
@@ -742,7 +756,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
V4L2_CAP_VIDEO_OVERLAY |
V4L2_CAP_READWRITE |
V4L2_CAP_STREAMING;
- cap->capabilities |= dev->ext->capabilities;
+ cap->capabilities |= dev->ext->ext_vv_data->capabilities;
return 0;
}
case VIDIOC_G_FBUF:
@@ -751,7 +765,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
DEB_EE(("VIDIOC_G_FBUF\n"));
- *fb = dev->ov_fb;
+ *fb = vv->ov_fb;
fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
return 0;
}
@@ -768,7 +782,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
return -EPERM;
}
*/
- if( 0 != dev->ov_data ) {
+ if( 0 != vv->ov_data ) {
DEB_D(("VIDIOC_S_FBUF: overlay is active.\n"));
return -EPERM;
}
@@ -780,11 +794,11 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
}
/* ok, accept it */
- dev->ov_fb = *fb;
- dev->ov_fmt = fmt;
- if (0 == dev->ov_fb.fmt.bytesperline)
- dev->ov_fb.fmt.bytesperline =
- dev->ov_fb.fmt.width*fmt->depth/8;
+ vv->ov_fb = *fb;
+ vv->ov_fmt = fmt;
+ if (0 == vv->ov_fb.fmt.bytesperline)
+ vv->ov_fb.fmt.bytesperline =
+ vv->ov_fb.fmt.width*fmt->depth/8;
return 0;
}
case VIDIOC_ENUM_FMT:
@@ -879,7 +893,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
{
v4l2_std_id *id = arg;
DEB_EE(("VIDIOC_G_STD\n"));
- *id = dev->standard->id;
+ *id = vv->standard->id;
return 0;
}
/* the saa7146 supfhrts (used in conjunction with the saa7111a for example)
@@ -890,9 +904,9 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
struct v4l2_standard *e = arg;
if (e->index < 0 )
return -EINVAL;
- if( e->index < dev->ext->num_stds ) {
+ if( e->index < dev->ext->ext_vv_data->num_stds ) {
DEB_EE(("VIDIOC_ENUMSTD: index:%d\n",e->index));
- return v4l2_video_std_construct(e, dev->ext->stds[e->index].id, dev->ext->stds[e->index].name);
+ return v4l2_video_std_construct(e, dev->ext->ext_vv_data->stds[e->index].id, dev->ext->ext_vv_data->stds[e->index].name);
}
return -EINVAL;
}
@@ -906,25 +920,25 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
struct saa7146_fh *ov_fh = NULL;
- if( 0 != dev->streaming ) {
+ if( 0 != vv->streaming ) {
return -EBUSY;
}
down(&dev->lock);
- if( dev->ov_data != NULL ) {
- ov_fh = dev->ov_data->fh;
+ if( vv->ov_data != NULL ) {
+ ov_fh = vv->ov_data->fh;
stop_preview(ov_fh);
restart_overlay = 1;
}
- for(i = 0; i < dev->ext->num_stds; i++)
- if (*id & dev->ext->stds[i].id)
+ for(i = 0; i < dev->ext->ext_vv_data->num_stds; i++)
+ if (*id & dev->ext->ext_vv_data->stds[i].id)
break;
- if (i != dev->ext->num_stds) {
- dev->standard = &dev->ext->stds[i];
- if( NULL != dev->ext->std_callback )
- dev->ext->std_callback(dev, dev->standard);
+ if (i != dev->ext->ext_vv_data->num_stds) {
+ vv->standard = &dev->ext->ext_vv_data->stds[i];
+ if( NULL != dev->ext->ext_vv_data->std_callback )
+ dev->ext->ext_vv_data->std_callback(dev, vv->standard);
found = 1;
}
@@ -938,7 +952,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
return -EINVAL;
}
- DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n",dev->standard->name));
+ DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n",vv->standard->name));
return 0;
}
case VIDIOC_OVERLAY:
@@ -946,15 +960,15 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
int on = *(int *)arg;
int err = 0;
- if( NULL == dev->ov_fmt ) {
+ if( NULL == vv->ov_fmt ) {
DEB_D(("VIDIOC_OVERLAY: no framebuffer informations. call S_FBUF first!\n"));
return -EAGAIN;
}
DEB_D(("VIDIOC_OVERLAY on:%d\n",on));
if( 0 != on ) {
- if( dev->ov_data != NULL ) {
- if( fh != dev->ov_data->fh) {
+ if( vv->ov_data != NULL ) {
+ if( fh != vv->ov_data->fh) {
return -EAGAIN;
}
}
@@ -962,8 +976,8 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
err = start_preview(fh);
spin_unlock_irqrestore(&dev->slock,flags);
} else {
- if( dev->ov_data != NULL ) {
- if( fh != dev->ov_data->fh) {
+ if( vv->ov_data != NULL ) {
+ if( fh != vv->ov_data->fh) {
return -EAGAIN;
}
}
@@ -1049,10 +1063,12 @@ int buffer_activate (struct saa7146_dev *dev,
struct saa7146_buf *buf,
struct saa7146_buf *next)
{
+ struct saa7146_vv *vv = dev->vv_data;
+
buf->vb.state = STATE_ACTIVE;
saa7146_set_capture(dev,buf,next);
- mod_timer(&dev->video_q.timeout, jiffies+BUFFER_TIMEOUT);
+ mod_timer(&vv->video_q.timeout, jiffies+BUFFER_TIMEOUT);
return 0;
}
@@ -1061,14 +1077,15 @@ int buffer_prepare(struct file *file, struct videobuf_buffer *vb)
{
struct saa7146_fh *fh = file->private_data;
struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
struct saa7146_buf *buf = (struct saa7146_buf *)vb;
int size,err = 0;
/* sanity checks */
if (fh->video_fmt.width < 64 ||
fh->video_fmt.height < 64 ||
- fh->video_fmt.width > dev->standard->h_max_out ||
- fh->video_fmt.height > dev->standard->v_max_out) {
+ fh->video_fmt.width > vv->standard->h_max_out ||
+ fh->video_fmt.height > vv->standard->v_max_out) {
DEB_D(("w (%d) / h (%d) out of bounds.\n",fh->video_fmt.width,fh->video_fmt.height));
return -EINVAL;
}
@@ -1159,12 +1176,13 @@ void buffer_queue(struct file *file, struct videobuf_buffer *vb)
{
struct saa7146_fh *fh = file->private_data;
struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
/*
*/
struct saa7146_buf *buf = (struct saa7146_buf *)vb;
DEB_CAP(("vbuf:%p\n",vb));
- saa7146_buffer_queue(fh->dev,&fh->dev->video_q,buf);
+ saa7146_buffer_queue(fh->dev,&vv->video_q,buf);
}
@@ -1173,6 +1191,7 @@ void buffer_release(struct file *file, struct videobuf_buffer *vb)
{
struct saa7146_fh *fh = file->private_data;
struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
struct saa7146_buf *buf = (struct saa7146_buf *)vb;
DEB_CAP(("vbuf:%p\n",vb));
@@ -1197,17 +1216,21 @@ struct saa7146_standard standard[] = {
static
-void video_init(struct saa7146_dev *dev)
+void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
{
- INIT_LIST_HEAD(&dev->video_q.queue);
+ INIT_LIST_HEAD(&vv->video_q.queue);
- init_timer(&dev->video_q.timeout);
- dev->video_q.timeout.function = saa7146_buffer_timeout;
- dev->video_q.timeout.data = (unsigned long)(&dev->video_q);
- dev->video_q.dev = dev;
+ init_timer(&vv->video_q.timeout);
+ vv->video_q.timeout.function = saa7146_buffer_timeout;
+ vv->video_q.timeout.data = (unsigned long)(&vv->video_q);
+ vv->video_q.dev = dev;
/* set some default values */
- dev->standard = &standard[0];
+ vv->standard = &standard[0];
+
+ /* FIXME: what's this? */
+ vv->current_hps_source = SAA7146_HPS_SOURCE_PORT_A;
+ vv->current_hps_sync = SAA7146_HPS_SYNC_PORT_A;
}
@@ -1235,17 +1258,18 @@ void video_open(struct saa7146_dev *dev, struct saa7146_fh *fh)
static
void video_close(struct saa7146_dev *dev, struct saa7146_fh *fh, struct file *file)
{
+ struct saa7146_vv *vv = dev->vv_data;
unsigned long flags;
- if( 0 != dev->ov_data ) {
- if( fh == dev->ov_data->fh ) {
+ if( 0 != vv->ov_data ) {
+ if( fh == vv->ov_data->fh ) {
spin_lock_irqsave(&dev->slock,flags);
stop_preview(fh);
spin_unlock_irqrestore(&dev->slock,flags);
}
}
- if( fh == dev->streaming ) {
+ if( fh == vv->streaming ) {
video_end(fh);
}
@@ -1256,7 +1280,8 @@ void video_close(struct saa7146_dev *dev, struct saa7146_fh *fh, struct file *fi
static
void video_irq_done(struct saa7146_dev *dev, unsigned long st)
{
- struct saa7146_dmaqueue *q = &dev->video_q;
+ struct saa7146_vv *vv = dev->vv_data;
+ struct saa7146_dmaqueue *q = &vv->video_q;
spin_lock(&dev->slock);
DEB_CAP(("called.\n"));
@@ -1275,6 +1300,7 @@ ssize_t video_read(struct file *file, char *data, size_t count, loff_t *ppos)
{
struct saa7146_fh *fh = file->private_data;
struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
ssize_t ret = 0;
DEB_EE(("called.\n"));
@@ -1286,8 +1312,8 @@ ssize_t video_read(struct file *file, char *data, size_t count, loff_t *ppos)
video_end(fh);
/* restart overlay if it was active before */
- if( 0 != dev->ov_data) {
- start_preview(dev->ov_data->fh);
+ if( 0 != vv->ov_data) {
+ start_preview(vv->ov_data->fh);
}
return ret;
diff --git a/linux/drivers/media/common/saa7146_vv.h b/linux/drivers/media/common/saa7146_vv.h
new file mode 100644
index 000000000..5a924bfd5
--- /dev/null
+++ b/linux/drivers/media/common/saa7146_vv.h
@@ -0,0 +1,269 @@
+#ifndef __SAA7146_VV__
+#define __SAA7146_VV__
+
+#include "saa7146.h"
+
+#include <linux/videodev2.h>
+#include "video-buf.h"
+
+#define MAX_SAA7146_CAPTURE_BUFFERS 32 /* arbitrary */
+#define BUFFER_TIMEOUT (HZ/2) /* 0.5 seconds */
+
+struct saa7146_video_dma {
+ u32 base_odd;
+ u32 base_even;
+ u32 prot_addr;
+ u32 pitch;
+ u32 base_page;
+ u32 num_line_byte;
+};
+
+struct saa7146_format {
+ char *name;
+ int pixelformat;
+ u32 trans;
+ u8 depth;
+ unsigned long flags;
+};
+
+struct saa7146_standard
+{
+ char *name;
+ v4l2_std_id id;
+
+ int v_offset;
+ int v_field;
+ int v_calc;
+
+ int h_offset;
+ int h_pixels;
+ int h_calc;
+
+ int v_max_out;
+ int h_max_out;
+};
+
+/* buffer for one video/vbi frame */
+struct saa7146_buf {
+ /* common v4l buffer stuff -- must be first */
+ struct videobuf_buffer vb;
+
+ /* saa7146 specific */
+ struct v4l2_pix_format *fmt;
+ int (*activate)(struct saa7146_dev *dev,
+ struct saa7146_buf *buf,
+ struct saa7146_buf *next);
+
+ /* page tables */
+ struct saa7146_pgtable pt[3];
+};
+
+struct saa7146_dmaqueue {
+ struct saa7146_dev *dev;
+ struct saa7146_buf *curr;
+ struct list_head queue;
+ struct timer_list timeout;
+};
+
+struct saa7146_overlay {
+ struct saa7146_fh *fh;
+ struct v4l2_window win;
+ struct v4l2_clip clips[16];
+ int nclips;
+};
+
+/* per open data */
+struct saa7146_fh {
+ struct saa7146_dev *dev;
+ /* if this is a vbi or capture open */
+ enum v4l2_buf_type type;
+
+ /* video overlay */
+ struct saa7146_overlay ov;
+
+ /* video capture */
+ struct videobuf_queue video_q;
+ struct v4l2_pix_format video_fmt;
+
+ /* vbi capture */
+ struct videobuf_queue vbi_q;
+ struct v4l2_vbi_format vbi_fmt;
+ struct timer_list vbi_read_timeout;
+};
+
+struct saa7146_vv
+{
+ int vbi_minor;
+
+ /* vbi capture */
+ struct saa7146_dmaqueue vbi_q;
+ /* vbi workaround interrupt queue */
+ wait_queue_head_t vbi_wq;
+ int vbi_fieldcount;
+ struct saa7146_fh *vbi_streaming;
+
+ int video_minor;
+
+ /* video overlay */
+ struct v4l2_framebuffer ov_fb;
+ struct saa7146_format *ov_fmt;
+ struct saa7146_overlay *ov_data;
+
+ /* video capture */
+ struct saa7146_dmaqueue video_q;
+ struct saa7146_fh *streaming;
+
+ /* common: fixme? shouldn't this be in saa7146_fh?
+ (this leads to a more complicated question: shall the driver
+ store the different settings (for example S_INPUT) for every open
+ and restore it appropriately, or should all settings be common for
+ all opens? currently, we do the latter, like all other
+ drivers do... */
+ struct saa7146_standard *standard;
+
+ int vflip;
+ int hflip;
+ int current_hps_source;
+ int current_hps_sync;
+
+ u32 *clipping; /* pointer to clipping memory */
+};
+
+#define SAA7146_EXCLUSIVE 0x1
+#define SAA7146_BEFORE 0x2
+#define SAA7146_AFTER 0x4
+
+struct saa7146_extension_ioctls
+{
+ unsigned int cmd;
+ int flags;
+};
+
+/* flags */
+#define SAA7146_EXT_SWAP_ODD_EVEN 0x1 /* needs odd/even fields swapped */
+
+struct saa7146_ext_vv
+{
+ /* informations about the video capabilities of the device */
+ int inputs;
+ int audios;
+ u32 capabilities;
+ int flags;
+
+ /* additionally supported transmission standards */
+ struct saa7146_standard *stds;
+ int num_stds;
+ int (*std_callback)(struct saa7146_dev*, struct saa7146_standard *);
+
+ struct saa7146_extension_ioctls *ioctls;
+ int (*ioctl)(struct saa7146_dev*, unsigned int cmd, void *arg);
+};
+
+struct saa7146_use_ops {
+ void (*init)(struct saa7146_dev *, struct saa7146_vv *);
+ void(*open)(struct saa7146_dev *, struct saa7146_fh *);
+ void (*release)(struct saa7146_dev *, struct saa7146_fh *,struct file *);
+ void (*irq_done)(struct saa7146_dev *, unsigned long status);
+ ssize_t (*read)(struct file *, char *, size_t, loff_t *);
+ int (*capture_begin)(struct saa7146_fh *);
+ int (*capture_end)(struct saa7146_fh *);
+};
+
+/* from saa7146_fops.c */
+int saa7146_register_device(struct video_device *vid, struct saa7146_dev* dev, char *name, int type);
+int saa7146_unregister_device(struct video_device *vid, struct saa7146_dev* dev);
+void saa7146_buffer_finish(struct saa7146_dev *dev, struct saa7146_dmaqueue *q, int state);
+void saa7146_buffer_next(struct saa7146_dev *dev, struct saa7146_dmaqueue *q,int vbi);
+int saa7146_buffer_queue(struct saa7146_dev *dev, struct saa7146_dmaqueue *q, struct saa7146_buf *buf);
+void saa7146_buffer_timeout(unsigned long data);
+void saa7146_dma_free(struct saa7146_dev *dev,struct saa7146_buf *buf);
+
+int saa7146_vv_init(struct saa7146_dev* dev);
+int saa7146_vv_release(struct saa7146_dev* dev);
+
+
+/* from saa7146_hlp.c */
+void saa7146_set_overlay(struct saa7146_dev *dev, struct saa7146_fh *fh, int v);
+void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next);
+void saa7146_write_out_dma(struct saa7146_dev* dev, int which, struct saa7146_video_dma* vdma) ;
+void saa7146_set_hps_source_and_sync(struct saa7146_dev *saa, int source, int sync);
+void saa7146_set_gpio(struct saa7146_dev *saa, u8 pin, u8 data);
+
+/* from saa7146_video.c */
+extern struct saa7146_use_ops saa7146_video_uops;
+
+/* from saa7146_vbi.c */
+extern struct saa7146_use_ops saa7146_vbi_uops;
+
+/* saa7146 source inputs */
+#define SAA7146_HPS_SOURCE_PORT_A 0x00
+#define SAA7146_HPS_SOURCE_PORT_B 0x01
+#define SAA7146_HPS_SOURCE_YPB_CPA 0x02
+#define SAA7146_HPS_SOURCE_YPA_CPB 0x03
+
+/* sync inputs */
+#define SAA7146_HPS_SYNC_PORT_A 0x00
+#define SAA7146_HPS_SYNC_PORT_B 0x01
+
+/* number of vertical active lines */
+#define V_ACTIVE_LINES_PAL 576
+#define V_ACTIVE_LINES_NTSC 480
+#define V_ACTIVE_LINES_SECAM 576
+
+/* number of lines in a field for HPS to process */
+#define V_FIELD_PAL 288
+#define V_FIELD_NTSC 240
+#define V_FIELD_SECAM 288
+
+/* number of lines of vertical offset before processing */
+#define V_OFFSET_PAL 0x17
+#define V_OFFSET_NTSC 0x16
+#define V_OFFSET_SECAM 0x14
+
+/* number of horizontal pixels to process */
+#define H_PIXELS_PAL 680
+#define H_PIXELS_NTSC 708
+#define H_PIXELS_SECAM 720
+
+/* horizontal offset of processing window */
+#define H_OFFSET_PAL 0x14
+#define H_OFFSET_NTSC 0x06
+#define H_OFFSET_SECAM 0x14
+
+#define SAA7146_PAL_VALUES V_OFFSET_PAL, V_FIELD_PAL, V_ACTIVE_LINES_PAL, H_OFFSET_PAL, H_PIXELS_PAL, H_PIXELS_PAL+1, V_ACTIVE_LINES_PAL, 768
+#define SAA7146_NTSC_VALUES V_OFFSET_NTSC, V_FIELD_NTSC, V_ACTIVE_LINES_NTSC, H_OFFSET_NTSC, H_PIXELS_NTSC, H_PIXELS_NTSC+1, V_ACTIVE_LINES_NTSC, 640
+#define SAA7146_SECAM_VALUES V_OFFSET_SECAM, V_FIELD_SECAM, V_ACTIVE_LINES_SECAM, H_OFFSET_SECAM, H_PIXELS_SECAM, H_PIXELS_SECAM+1, V_ACTIVE_LINES_SECAM, 768
+
+/* some memory sizes */
+#define SAA7146_CLIPPING_MEM (14*PAGE_SIZE)
+
+/* some defines for the various clipping-modes */
+#define SAA7146_CLIPPING_RECT 0x4
+#define SAA7146_CLIPPING_RECT_INVERTED 0x5
+#define SAA7146_CLIPPING_MASK 0x6
+#define SAA7146_CLIPPING_MASK_INVERTED 0x7
+
+/* output formats: each entry holds four informations */
+#define RGB08_COMPOSED 0x0217 /* composed is used in the sense of "not-planar" */
+/* this means: planar?=0, yuv2rgb-conversation-mode=2, dither=yes(=1), format-mode = 7 */
+#define RGB15_COMPOSED 0x0213
+#define RGB16_COMPOSED 0x0210
+#define RGB24_COMPOSED 0x0201
+#define RGB32_COMPOSED 0x0202
+
+#define Y8 0x0006
+#define YUV411_COMPOSED 0x0003
+#define YUV422_COMPOSED 0x0000
+/* this means: planar?=1, yuv2rgb-conversion-mode=0, dither=no(=0), format-mode = b */
+#define YUV411_DECOMPOSED 0x100b
+#define YUV422_DECOMPOSED 0x1009
+#define YUV420_DECOMPOSED 0x100a
+
+#define IS_PLANAR(x) (x & 0xf000)
+
+/* misc defines */
+#define SAA7146_NO_SWAP (0x0)
+#define SAA7146_TWO_BYTE_SWAP (0x1)
+#define SAA7146_FOUR_BYTE_SWAP (0x2)
+
+#endif