summaryrefslogtreecommitdiff
path: root/linux/drivers/media
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
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')
-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
-rw-r--r--linux/drivers/media/dvb/Kconfig3
-rw-r--r--linux/drivers/media/dvb/Makefile2
-rw-r--r--linux/drivers/media/dvb/ttpci-budget/Kconfig (renamed from linux/drivers/media/dvb/av7110/Kconfig)7
-rw-r--r--linux/drivers/media/dvb/ttpci-budget/Makefile9
-rw-r--r--linux/drivers/media/dvb/ttpci-budget/budget.c739
-rw-r--r--linux/drivers/media/dvb/ttpci/Kconfig9
-rw-r--r--linux/drivers/media/dvb/ttpci/Makefile (renamed from linux/drivers/media/dvb/av7110/Makefile)0
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110.c (renamed from linux/drivers/media/dvb/av7110/av7110.c)478
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110.h (renamed from linux/drivers/media/dvb/av7110/av7110.h)46
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110_firm.h (renamed from linux/drivers/media/dvb/av7110/av7110_firm.h)0
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110_ipack.c (renamed from linux/drivers/media/dvb/av7110/av7110_ipack.c)0
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110_ipack.h (renamed from linux/drivers/media/dvb/av7110/av7110_ipack.h)0
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110_ir.c (renamed from linux/drivers/media/dvb/av7110/av7110_ir.c)0
-rw-r--r--linux/drivers/media/video/mxb.c87
21 files changed, 1520 insertions, 958 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
diff --git a/linux/drivers/media/dvb/Kconfig b/linux/drivers/media/dvb/Kconfig
index 5aba59f9e..edbec1c88 100644
--- a/linux/drivers/media/dvb/Kconfig
+++ b/linux/drivers/media/dvb/Kconfig
@@ -35,7 +35,8 @@ source "drivers/media/dvb/frontends/Kconfig"
comment "Supported DVB Adapters"
depends on DVB
-source "drivers/media/dvb/av7110/Kconfig"
+source "drivers/media/dvb/ttpci/Kconfig"
+source "drivers/media/dvb/ttpci-budget/Kconfig"
endmenu
diff --git a/linux/drivers/media/dvb/Makefile b/linux/drivers/media/dvb/Makefile
index 3290afb80..d23a404bf 100644
--- a/linux/drivers/media/dvb/Makefile
+++ b/linux/drivers/media/dvb/Makefile
@@ -2,4 +2,4 @@
# Makefile for the kernel multimedia device drivers.
#
-obj-y := dvb-core/ frontends/ av7110/
+obj-y := dvb-core/ frontends/ ttpci/ ttpci-budget/
diff --git a/linux/drivers/media/dvb/av7110/Kconfig b/linux/drivers/media/dvb/ttpci-budget/Kconfig
index 93270f079..3c4d43d41 100644
--- a/linux/drivers/media/dvb/av7110/Kconfig
+++ b/linux/drivers/media/dvb/ttpci-budget/Kconfig
@@ -1,13 +1,12 @@
config DVB_AV7110
- tristate "SAA7146 based AV7110 and Nova/Budget PCI cards"
+ tristate "SAA7146 based AV7110 PCI cards"
depends on VIDEO_DEV && DVB_CORE
help
Support for SAA7146 and AV7110 based DVB cards as produced
by Fujitsu-Siemens, Technotrend, Hauppauge and others.
- Simple cards like so called Budget- or Nova-PCI cards are
- supported as well as fullfeatured cards with onboard MPEG2
- decoder.
+ This driver only supports the fullfeatured cards with
+ onboard MPEG2 decoder.
Say Y if you own such a card and want to use it.
diff --git a/linux/drivers/media/dvb/ttpci-budget/Makefile b/linux/drivers/media/dvb/ttpci-budget/Makefile
new file mode 100644
index 000000000..11c671d1b
--- /dev/null
+++ b/linux/drivers/media/dvb/ttpci-budget/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the kernel AV7110 DVB device driver
+#
+
+dvb-ttpci-budget-objs := budget.o
+
+obj-$(CONFIG_DVB_BUDGET) += dvb-ttpci-budget.o
+
+EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -I$(src)/../../common/ -I$(src)/../../common/saa7146
diff --git a/linux/drivers/media/dvb/ttpci-budget/budget.c b/linux/drivers/media/dvb/ttpci-budget/budget.c
new file mode 100644
index 000000000..b50b1d4ad
--- /dev/null
+++ b/linux/drivers/media/dvb/ttpci-budget/budget.c
@@ -0,0 +1,739 @@
+/*
+ * budget.c: driver for the SAA7146 based Nova/Budget DVB cards
+ *
+ * Copyright (C) 1999-2002 Ralph Metzler
+ * & Marcus Metzler for convergence integrated media GmbH
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org/dvb/
+ */
+
+#include "dvb_i2c.h"
+#include "dvb_frontend.h"
+#include "dvbdev.h"
+#include "demux.h"
+#include "dvb_demux.h"
+#include "dmxdev.h"
+#include "dvb_filter.h"
+#include "dvb_net.h"
+
+#include "saa7146.h"
+
+static int budget_debug = 0;
+#if 1
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
+ #define KBUILD_MODNAME budget
+#endif
+#define DEBUG_PROLOG printk("%s: %s(): ",__stringify(KBUILD_MODNAME),__FUNCTION__)
+#define DEB_S(x) if (0!=(budget_debug&0x01)) { DEBUG_PROLOG; printk x; } /* simple debug messages */
+#define DEB_D(x) if (0!=(budget_debug&0x02)) { DEBUG_PROLOG; printk x; } /* more detailed debug messages */
+#define DEB_EE(x) if (0!=(budget_debug&0x04)) { DEBUG_PROLOG; printk x; } /* print enter and exit of functions */
+#else
+#define DEB_S(x)
+#define DEB_D(x)
+#define DEB_EE(x)
+#endif
+
+int budget_num = 0;
+
+/* place to store all the necessary device information */
+typedef struct budget_s {
+
+ /* devices */
+ struct dvb_device dvb_dev;
+ dvb_net_t dvb_net;
+
+ struct saa7146_dev *dev;
+
+ struct dvb_i2c_bus *i2c_bus;
+ struct card_info *card_type;
+
+ unsigned char *grabbing;
+ struct saa7146_pgtable pt;
+
+ struct tasklet_struct fidb_tasklet;
+
+ dmxdev_t dmxdev;
+ struct dvb_demux demux;
+ char demux_id[16];
+
+ dmx_frontend_t hw_frontend;
+ dmx_frontend_t mem_frontend;
+
+ int fe_synced;
+ struct semaphore pid_mutex;
+
+ int tsf;
+ u32 ttbp;
+ int feeding;
+
+ int registered;
+
+ struct dvb_adapter *dvb_adapter;
+} budget_t;
+
+/****************************************************************************
+ * General helper functions
+ ****************************************************************************/
+
+/* this is videobuf_vmalloc_to_sg() from video-buf.c */
+struct scatterlist*
+vmalloc_to_sg(unsigned char *virt, int nr_pages)
+{
+ struct scatterlist *sglist;
+ struct page *pg;
+ int i;
+
+ sglist = kmalloc(sizeof(struct scatterlist)*nr_pages, GFP_KERNEL);
+ if (NULL == sglist)
+ return NULL;
+ memset(sglist,0,sizeof(struct scatterlist)*nr_pages);
+ for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
+ pg = vmalloc_to_page(virt);
+ if (NULL == pg)
+ goto err;
+ if (PageHighMem(pg))
+ BUG();
+ sglist[i].page = pg;
+ sglist[i].length = PAGE_SIZE;
+ }
+ return sglist;
+
+ err:
+ kfree(sglist);
+ return NULL;
+}
+
+
+static inline void ddelay(int i)
+{
+ current->state=TASK_INTERRUPTIBLE;
+ schedule_timeout((HZ*i)/100);
+}
+
+/****************************************************************************
+ * TT budget / WinTV Nova
+ ****************************************************************************/
+
+static int
+TTBStop(budget_t *budget)
+{
+ DEB_EE(("budget: %p\n",budget));
+
+ if (--budget->feeding)
+ return budget->feeding;
+
+ saa7146_write(budget->dev, MC1, MASK_20); // DMA3 off
+ IER_DISABLE(budget->dev, MASK_07);
+ return 0;
+}
+
+#define TS_WIDTH (4*188)
+#define TS_HEIGHT (1024/4)
+#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
+
+static int
+TTBStart(budget_t *budget)
+{
+ struct saa7146_dev *dev=budget->dev;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ if (budget->feeding)
+ return ++budget->feeding;
+
+ saa7146_write(dev, MC1, MASK_20); // DMA3 off
+
+ memset(budget->grabbing, 0x00, TS_HEIGHT*TS_WIDTH);
+
+ saa7146_write(dev, PCI_BT_V1, 0x001c0000);
+
+ budget->tsf=0;
+ budget->ttbp=0;
+ saa7146_write(dev, DD1_INIT, 0x02000680);
+ saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+
+ saa7146_write(dev, BRS_CTRL, 0x60000000);
+ saa7146_write(dev, MC2, (MASK_08 | MASK_24));
+ mdelay(10);
+
+ saa7146_write(dev, BASE_ODD3, 0);
+ saa7146_write(dev, BASE_EVEN3, TS_WIDTH*TS_HEIGHT/2);
+ saa7146_write(dev, PROT_ADDR3, TS_WIDTH*TS_HEIGHT);
+ saa7146_write(dev, BASE_PAGE3, budget->pt.dma |ME1|0xb0);
+ saa7146_write(dev, PITCH3, TS_WIDTH);
+
+ saa7146_write(dev, NUM_LINE_BYTE3, ((TS_HEIGHT/2)<<16)|TS_WIDTH);
+ saa7146_write(dev, MC2, (MASK_04 | MASK_20));
+
+ saa7146_write(dev, MC1, (MASK_04 | MASK_20)); // DMA3 on
+
+ // FIDB
+ IER_ENABLE(budget->dev, MASK_07);
+
+ return ++budget->feeding;
+}
+
+static
+void fidbirq (unsigned long data)
+{
+ struct budget_s *budget = (struct budget_s*) data;
+ u8 *mem=(u8 *)(budget->grabbing);
+ int num;
+ u32 dmapos;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ dmapos=saa7146_read(budget->dev, PCI_VDP3);
+ dmapos-=(dmapos%188);
+
+ if (dmapos>=TS_BUFLEN) {
+ DEB_S(("bogus dmapos value ignored, budget: %p\n",budget));
+ return;
+ }
+
+ if (budget->tsf) {
+ mem+=budget->ttbp;
+ if (dmapos<0x20000) {
+ num=1024-budget->ttbp/188;
+ budget->ttbp=0;
+ } else {
+ num=(dmapos - budget->ttbp)/188;
+ budget->ttbp=dmapos;
+ }
+ } else {
+ if (budget->ttbp>1000*188 && budget->ttbp<1024*188) {
+ if (budget->feeding)
+ dvb_dmx_swfilter_packets(&budget->demux,
+ mem+budget->ttbp,
+ 1024- budget->ttbp / 188);
+ }
+ num=dmapos/188;
+ budget->ttbp=dmapos;
+ }
+
+ budget->tsf^=1;
+ saa7146_write(budget->dev, DD1_INIT, 0x02000600|(budget->tsf ? 0x40:0x80));
+ saa7146_write(budget->dev, MC2,
+ (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+
+ // FIXME: use bottom half or tasklet
+ if (budget->feeding && mem[0]==0x47)
+ dvb_dmx_swfilter_packets(&budget->demux, mem, num);
+}
+
+inline static void
+Set22K(budget_t *budget, int state)
+{
+ struct saa7146_dev *dev=budget->dev;
+ DEB_EE(("budget: %p\n",budget));
+ saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
+}
+
+
+/* Diseqc functions only for TT Budget card */
+/* taken from the Skyvision DVB driver by
+ Ralph Metzler <rjkm@metzlerbros.de> */
+
+inline static void
+DiseqcSendBit(budget_t *budget, int data)
+{
+ struct saa7146_dev *dev=budget->dev;
+ DEB_EE(("budget: %p\n",budget));
+
+ saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
+ udelay(data ? 500 : 1000);
+ saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+ udelay(data ? 1000 : 500);
+}
+
+static void
+DiseqcSendByte(budget_t *budget, int data)
+{
+ struct saa7146_dev *dev=budget->dev;
+ int i, par=1, d;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ for (i=7; i>=0; i--)
+ {
+ d=(data>>i)&1;
+ par^=d;
+ DiseqcSendBit(budget, d);
+ }
+ DiseqcSendBit(budget, par);
+}
+
+inline static int
+SendDiSEqCMsg(budget_t *budget, int len, u8 *msg, int burst)
+{
+ struct saa7146_dev *dev=budget->dev;
+ int i;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+ mdelay(16);
+
+ for (i=0; i<len; i++)
+ DiseqcSendByte(budget, msg[i]);
+
+ mdelay(16);
+
+ if (burst!=-1) {
+ if (burst)
+ DiseqcSendByte(budget, 0xff);
+ else {
+ saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
+ udelay(12500);
+ saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+ }
+ ddelay(2);
+ }
+
+ return 0;
+}
+
+/****************************************************************************
+ * DVB API SECTION
+ ****************************************************************************/
+
+static int
+budget_start_feed(struct dvb_demux_feed *feed)
+{
+ struct dvb_demux *demux = feed->demux;
+ budget_t *budget = (budget_t *) demux->priv;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ if (!demux->dmx.frontend)
+ return -EINVAL;
+
+ return TTBStart(budget);
+}
+
+static int
+budget_stop_feed(struct dvb_demux_feed *feed)
+{
+ struct dvb_demux *demux = feed->demux;
+ budget_t *budget = (budget_t *) demux->priv;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ return TTBStop(budget);
+}
+
+/******************************************************************************
+ * SEC device file operations
+ ******************************************************************************/
+
+static
+int budget_diseqc_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
+{
+ budget_t *budget = fe->before_after_data;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ switch (cmd) {
+ case FE_SET_TONE:
+ switch ((fe_sec_tone_mode_t) arg) {
+ case SEC_TONE_ON:
+ Set22K (budget, 1);
+ break;
+ case SEC_TONE_OFF:
+ Set22K (budget, 0);
+ break;
+ default:
+ return -EINVAL;
+ };
+ break;
+
+ case FE_DISEQC_SEND_MASTER_CMD:
+ {
+ struct dvb_diseqc_master_cmd *cmd = arg;
+
+ SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
+ break;
+ }
+
+ case FE_DISEQC_SEND_BURST:
+ SendDiSEqCMsg (budget, 0, NULL, (int) arg);
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ };
+
+ return 0;
+}
+
+static
+int budget_register(budget_t *budget)
+{
+ int ret;
+ dmx_frontend_t *dvbfront=&budget->hw_frontend;
+ struct dvb_demux *dvbdemux=&budget->demux;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ if (budget->registered)
+ return -1;
+
+ budget->registered=1;
+
+ /* init DiSEqC stuff */
+ dvb_add_frontend_ioctls (budget->dvb_adapter, budget_diseqc_ioctl, NULL, budget);
+
+ memcpy(budget->demux_id, "demux0_0", 9);
+ budget->demux_id[7]=budget->dvb_adapter->num+0x30;
+ dvbdemux->priv=(void *) budget;
+
+ dvbdemux->filternum=256;
+ dvbdemux->feednum=256;
+ dvbdemux->start_feed=budget_start_feed;
+ dvbdemux->stop_feed=budget_stop_feed;
+ dvbdemux->write_to_decoder=NULL;
+
+ dvbdemux->dmx.vendor="CIM";
+ dvbdemux->dmx.model="sw";
+ dvbdemux->dmx.id=budget->demux_id;
+ dvbdemux->dmx.capabilities=(DMX_TS_FILTERING|
+ DMX_SECTION_FILTERING|
+ DMX_MEMORY_BASED_FILTERING);
+
+ dvb_dmx_init(&budget->demux);
+
+ dvbfront->id="hw_frontend";
+ dvbfront->vendor="VLSI";
+ dvbfront->model="DVB Frontend";
+ dvbfront->source=DMX_FRONTEND_0;
+
+ budget->dmxdev.filternum=256;
+ budget->dmxdev.demux=&dvbdemux->dmx;
+ budget->dmxdev.capabilities=0;
+
+ dvb_dmxdev_init(&budget->dmxdev, budget->dvb_adapter);
+
+ ret=dvbdemux->dmx.add_frontend(&dvbdemux->dmx,
+ &budget->hw_frontend);
+ if (ret<0)
+ return ret;
+
+ budget->mem_frontend.id="mem_frontend";
+ budget->mem_frontend.vendor="memory";
+ budget->mem_frontend.model="sw";
+ budget->mem_frontend.source=DMX_MEMORY_FE;
+ ret=dvbdemux->dmx.add_frontend(&dvbdemux->dmx,
+ &budget->mem_frontend);
+ if (ret<0)
+ return ret;
+
+ ret=dvbdemux->dmx.connect_frontend(&dvbdemux->dmx,
+ &budget->hw_frontend);
+ if (ret<0)
+ return ret;
+
+ budget->dvb_net.card_num=budget->dvb_adapter->num;
+ dvb_net_init(budget->dvb_adapter, &budget->dvb_net, &dvbdemux->dmx);
+
+ return 0;
+}
+
+
+static void
+dvb_unregister(budget_t *budget)
+{
+ struct dvb_demux *dvbdemux=&budget->demux;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ if (!budget->registered)
+ return;
+
+ dvb_net_release(&budget->dvb_net);
+
+ dvbdemux->dmx.close(&dvbdemux->dmx);
+ dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &budget->hw_frontend);
+ dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &budget->mem_frontend);
+
+ dvb_dmxdev_release(&budget->dmxdev);
+ dvb_dmx_release(&budget->demux);
+ dvb_remove_frontend_ioctls (budget->dvb_adapter, budget_diseqc_ioctl, NULL);
+}
+
+static
+int master_xfer (struct dvb_i2c_bus *i2c, const struct i2c_msg msgs[], int num)
+{
+ struct saa7146_dev *dev = i2c->data;
+ return saa7146_i2c_transfer(dev, msgs, num, 6);
+}
+
+/****************************************************************************
+ * INITIALIZATION
+ ****************************************************************************/
+
+int budget_preinit(struct saa7146_dev* dev)
+{
+ DEB_EE(("dev: %p\n",dev));
+ return 0;
+}
+
+struct card_info {
+ int type;
+ char *name;
+};
+
+#define DVB_CARD_TT_BUDGET 0
+#define DVB_CARD_TT_BUDGET_CI 1
+#define DVB_CARD_KNC1 2
+
+static struct card_info ttbs = { DVB_CARD_TT_BUDGET, "TT-Budget/WinTV-NOVA-S PCI" };
+static struct card_info ttbc = { DVB_CARD_TT_BUDGET, "TT-Budget/WinTV-NOVA-C PCI" };
+static struct card_info ttbt = { DVB_CARD_TT_BUDGET, "TT-Budget/WinTV-NOVA-T PCI" };
+static struct card_info ttbci = { DVB_CARD_TT_BUDGET_CI, "TT-Budget/WinTV-NOVA-CI PCI" };
+static struct card_info satel = { DVB_CARD_TT_BUDGET, "SATELCO Multimedia PCI"};
+static struct card_info knc1 = { DVB_CARD_KNC1, "KNC1 DVB-S" };
+
+static struct saa7146_sub_info sub_data[] = {
+ { 0x1131, 0x4f56 },
+ { 0x13c2, 0x1003 },
+ { 0x13c2, 0x1004 },
+ { 0x13c2, 0x1005 },
+ { 0x13c2, 0x100c },
+ { 0x13c2, 0x1013 },
+ { 0xffff, 0xffff },
+};
+
+struct card_match {
+ struct saa7146_sub_info *sub; /* Subsystem IDs or PCI_ANY_ID */
+ struct card_info *card;
+};
+
+static struct card_match match_data[] = {
+ { &sub_data[ 0], &knc1 },
+ { &sub_data[ 1], &ttbs },
+ { &sub_data[ 2], &ttbc },
+ { &sub_data[ 3], &ttbt },
+ { &sub_data[ 4], &ttbci },
+ { &sub_data[ 5], &satel },
+ { &sub_data[ 6], NULL },
+};
+
+
+int budget_probe(struct saa7146_dev* dev, unsigned int subvendor, unsigned int subdevice)
+{
+ budget_t *budget;
+ int i = 0;
+
+ DEB_EE(("dev: %p\n",dev));
+
+ for(i = 0;;i++) {
+ if( 0xffff == match_data[i].sub->subvendor ) {
+ printk(KERN_ERR "dvb: device subvendor:0x%04x, subdevice:0x%04x is not a known dvb card.\n",subvendor,subdevice);
+ return -ENODEV;
+ }
+ if( subvendor == match_data[i].sub->subvendor && subdevice == match_data[i].sub->subdevice ) {
+ break;
+ }
+ }
+
+ if (!(budget = kmalloc (sizeof (struct budget_s), GFP_KERNEL))) {
+ printk ("%s: out of memory!\n", __FUNCTION__);
+ return -ENOMEM;
+ }
+ memset(budget, 0, sizeof(budget_t));
+ budget->card_type = match_data[i].card;
+
+ (budget_t*)dev->ext_priv = budget;
+
+ return 0;
+}
+
+static
+int budget_attach (struct saa7146_dev* dev)
+{
+ budget_t *budget = (budget_t*)dev->ext_priv;
+ struct scatterlist *slist = NULL;
+ int slen = 0;
+ int length = TS_WIDTH*TS_HEIGHT;
+ int pages = (length+PAGE_SIZE-1)/PAGE_SIZE;
+ int ret = 0;
+
+ DEB_EE(("dev: %p, budget: %p\n",dev,budget));
+
+ budget->dev=(struct saa7146_dev *)dev;
+ dvb_register_adapter(&budget->dvb_adapter, budget->card_type->name);
+
+ saa7146_i2c_adapter_prepare(dev, NULL, SAA7146_I2C_BUS_BIT_RATE_3200);
+ budget->i2c_bus = dvb_register_i2c_bus (master_xfer, dev, budget->dvb_adapter, 0);
+
+ if (!budget->i2c_bus) {
+ dvb_unregister_adapter (budget->dvb_adapter);
+ return -ENOMEM;
+ }
+
+ budget->grabbing = vmalloc(length);
+ if (!budget->grabbing) {
+ printk(KERN_ERR "dvb: vmalloc() failed.\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ if (!(slist = vmalloc_to_sg(budget->grabbing, pages))) {
+ printk(KERN_ERR "dvb: vmalloc_to_sg() failed.\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ if (saa7146_pgtable_alloc(dev->pci, &budget->pt)) {
+ printk(KERN_ERR "dvb: saa7146_pgtable_alloc() failed.\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ slen = pci_map_sg(dev->pci,slist,pages,PCI_DMA_FROMDEVICE);
+ saa7146_pgtable_build_single(dev->pci, &budget->pt, slist, slen);
+
+ saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
+ /* set dd1 stream a & b */
+ saa7146_write(dev, DD1_STREAM_B, 0x00000000);
+ saa7146_write(dev, DD1_INIT, 0x02000000);
+ saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+ /* upload all */
+ saa7146_write(dev, MC2, 0x077c077c);
+ saa7146_write(dev, GPIO_CTRL, 0x000000);
+
+ tasklet_init (&budget->fidb_tasklet, fidbirq, (unsigned long) budget);
+
+ saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); /* frontend power on */
+
+ budget_register(budget);
+
+ printk(KERN_INFO "budget: found budget-%d.\n",budget_num);
+ budget_num++;
+ return 0;
+
+err:
+ if( NULL != budget->grabbing ) {
+ vfree(budget->grabbing);
+ }
+ if( NULL != slist ) {
+ kfree(slist);
+ }
+ dvb_unregister_i2c_bus (master_xfer,budget->i2c_bus->adapter, budget->i2c_bus->id);
+ dvb_unregister_adapter (budget->dvb_adapter);
+ return ret;
+}
+
+static
+int budget_detach (struct saa7146_dev* saa)
+{
+ budget_t *budget = (budget_t*)saa->ext_priv;
+ DEB_EE(("budget: %p\n",budget));
+
+ dvb_unregister(budget);
+ dvb_unregister_i2c_bus (master_xfer,budget->i2c_bus->adapter, budget->i2c_bus->id);
+ dvb_unregister_adapter (budget->dvb_adapter);
+
+ saa7146_pgtable_free(saa->pci, &budget->pt);
+ vfree(budget->grabbing);
+ kfree (budget);
+
+ saa->ext_priv = NULL;
+ budget_num--;
+
+ return 0;
+}
+
+
+static
+void budget_irq(struct saa7146_dev* dev, u32 *isr)
+{
+ budget_t *budget = (budget_t*)dev->ext_priv;
+
+ DEB_EE(("dev: %p, budget: %p\n",dev,budget));
+
+ if (*isr & MASK_07)
+ tasklet_schedule (&budget->fidb_tasklet);
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
+static
+void budget_inc_use(struct saa7146_dev* adap)
+{
+ MOD_INC_USE_COUNT;
+}
+
+static
+void budget_dec_use(struct saa7146_dev* adap)
+{
+ MOD_DEC_USE_COUNT;
+}
+#endif
+
+static
+struct saa7146_extension budget_extension = {
+ .name = "budget dvb\0",
+ .devices = &sub_data[0],
+ .module = THIS_MODULE,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
+ .inc_use = budget_inc_use,
+ .dec_use = budget_dec_use,
+#endif
+ .preinit = budget_preinit,
+ .probe = budget_probe,
+ .attach = budget_attach,
+ .detach = budget_detach,
+
+ .irq_mask = MASK_07,
+ .irq_func = budget_irq,
+};
+
+
+static
+int __init budget_init(void)
+{
+ DEB_EE((".\n"));
+
+ if (saa7146_register_extension(&budget_extension))
+ return -ENODEV;
+
+ return 0;
+}
+
+
+static
+void __exit budget_exit(void)
+{
+ DEB_EE((".\n"));
+
+ if (saa7146_unregister_extension(&budget_extension))
+ printk(KERN_ERR "dvb: extension deregistration failed.\n");
+}
+
+module_init(budget_init);
+module_exit(budget_exit);
+
+MODULE_DESCRIPTION("driver for the SAA7146 based so-called budget PCI DVB cards by "
+ "Siemens, Technotrend, Hauppauge");
+MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(budget_debug,"i");
diff --git a/linux/drivers/media/dvb/ttpci/Kconfig b/linux/drivers/media/dvb/ttpci/Kconfig
new file mode 100644
index 000000000..cf8fe5251
--- /dev/null
+++ b/linux/drivers/media/dvb/ttpci/Kconfig
@@ -0,0 +1,9 @@
+config DVB_BUDGET
+ tristate "SAA7146 based Nova/Budget PCI cards"
+ depends on VIDEO_DEV && DVB_CORE
+ help
+ Support for simple SAA7146 based DVB cards
+ (so called Budget- or Nova-PCI cards) without onboard
+ MPEG2 decoder.
+
+ Say Y if you own such a card and want to use it.
diff --git a/linux/drivers/media/dvb/av7110/Makefile b/linux/drivers/media/dvb/ttpci/Makefile
index 5a9fd0c0c..5a9fd0c0c 100644
--- a/linux/drivers/media/dvb/av7110/Makefile
+++ b/linux/drivers/media/dvb/ttpci/Makefile
diff --git a/linux/drivers/media/dvb/av7110/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c
index 77ccc15db..f196ec210 100644
--- a/linux/drivers/media/dvb/av7110/av7110.c
+++ b/linux/drivers/media/dvb/ttpci/av7110.c
@@ -1,6 +1,5 @@
/*
* av7110.c: driver for the SAA7146 based AV110 cards (like the Fujitsu-Siemens DVB)
- * and Nova/Budget DVB cards
*
* Copyright (C) 1999-2002 Ralph Metzler
* & Marcus Metzler for convergence integrated media GmbH
@@ -121,21 +120,9 @@ static inline void ddelay(int i)
/****************************************************************************
- * GPIO and DEBI functions
+ * DEBI functions
****************************************************************************/
-inline static void
-setgpio(av7110_t *av7110, int port, u32 data)
-{
- struct saa7146_dev *dev = av7110->dev;
- u32 val = 0;
-
- val=saa7146_read(dev,GPIO_CTRL);
- val&=~(0xff << (8*(port)));
- val|=(data)<<(8*(port));
- saa7146_write(dev, GPIO_CTRL, val);
-}
-
/* This DEBI code is based on the Stradis driver
by Nathan Laredo <laredo@gnu.org> */
@@ -311,7 +298,7 @@ reset_arm(av7110_t *av7110)
{
DEB_EE(("av7110: %p\n",av7110));
- setgpio(av7110, RESET_LINE, GPIO_OUTLO);
+ saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO);
/* Disable DEBI and GPIO irq */
IER_DISABLE(av7110->dev, (MASK_19 | MASK_03));
@@ -320,7 +307,7 @@ reset_arm(av7110_t *av7110)
saa7146_write(av7110->dev, ISR, (MASK_19 | MASK_03));
mdelay(800);
- setgpio(av7110, RESET_LINE, GPIO_OUTHI);
+ saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTHI);
mdelay(800);
ARM_ResetMailBox(av7110);
@@ -703,84 +690,6 @@ ring_buffer_put(ring_buffer_t *db, u8 *buf, int len)
}
#endif
-
-/****************************************************************************
- * TT budget / WinTV Nova
- ****************************************************************************/
-
-static int
-TTBStop(av7110_t *av7110)
-{
- DEB_EE(("av7110: %p\n",av7110));
-
- if (--av7110->feeding)
- return av7110->feeding;
- saa7146_write(av7110->dev, MC1, MASK_20); // DMA3 off
-
-// saa7146_write(av7110->dev, MC1, MASK_28); // RPS0 off
-
- IER_DISABLE(av7110->dev, (MASK_07 | MASK_10));
-/*
- saa7146_write(av7110->dev, IER,
- saa7146_read(av7110->dev, IER) & ~MASK_10 );
- saa7146_write(av7110->dev, IER,
- saa7146_read(av7110->dev, IER)& ~MASK_07);
-*/
- return 0;
-}
-
-#define TS_WIDTH (4*188)
-#define TS_HEIGHT (1024/4)
-#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
-
-static int
-TTBStart(av7110_t *av7110)
-{
- struct saa7146_dev *dev=av7110->dev;
-
- DEB_EE(("av7110: %p\n",av7110));
-
- //printk ("function : %s\n", __FUNCTION__);
- if (av7110->feeding)
- return ++av7110->feeding;
-
- saa7146_write(dev, MC1, MASK_20); // DMA3 off
-
- memset(av7110->grabbing, 0x00, TS_HEIGHT*TS_WIDTH);
-
- saa7146_write(dev, PCI_BT_V1, 0x001c0000);
-
- av7110->tsf=0;
- av7110->ttbp=0;
- saa7146_write(dev, DD1_INIT, 0x02000680);
- saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-
- saa7146_write(dev, BRS_CTRL, 0x60000000);
- saa7146_write(dev, MC2, (MASK_08 | MASK_24));
- mdelay(10);
-
- saa7146_write(dev, BASE_ODD3, 0);
- saa7146_write(dev, BASE_EVEN3, TS_WIDTH*TS_HEIGHT/2);
- saa7146_write(dev, PROT_ADDR3, TS_WIDTH*TS_HEIGHT);
- saa7146_write(dev, BASE_PAGE3, av7110->pt.dma |ME1|0xb0);
- saa7146_write(dev, PITCH3, TS_WIDTH);
-
- saa7146_write(dev, NUM_LINE_BYTE3, ((TS_HEIGHT/2)<<16)|TS_WIDTH);
- saa7146_write(dev, MC2, (MASK_04 | MASK_20));
-
- // VPE
- IER_ENABLE(av7110->dev, MASK_10);
-// saa7146_write(dev, IER, saa7146_read(saa->mem, IER)|MASK_10);
-
- saa7146_write(dev, MC1, (MASK_04 | MASK_20)); // DMA3 on
-
- // FIDB
- IER_ENABLE(av7110->dev, MASK_07);
-// saa7146_write(dev, IER, saa7146_read(saa->mem, IER)|MASK_07);
-
- return ++av7110->feeding;
-}
-
/**
* Hack! we save the last av7110 ptr. This should be ok, since
* you rarely will use more then one IR control.
@@ -928,86 +837,6 @@ u8 pshead[0x26] = {
};
-static void vpeirq (unsigned long data)
-{
- //printk("vpeirq %08x\n", saa7146_read(av7110->dev, PCI_VDP3));
-}
-
-#if 0
-static void fidbirq(struct saa7146_dev* saa, void *data)
-{
- av7110_t *av7110=(av7110_t *) data;
- u8 *mem;
-
- DEB_EE(("av7110: %p\n",av7110));
-
- mem=(av7110->tsf ? TS_HEIGHT*TS_WIDTH/2 :0)+(u8 *)av7110->grabbing;
-
- // FIXME: think of something better without busy waiting
- if (av7110->tsf)
- while (saa7146_read(av7110->dev, PCI_VDP3)>0x20000);
- else
- while (saa7146_read(av7110->dev, PCI_VDP3)<0x17800);
-
- av7110->tsf^=1;
- saa7146_write(av7110->dev, DD1_INIT, 0x02000600|(av7110->tsf ? 0x40:0x80));
- saa7146_write(av7110->dev, MC2,
- (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-
- // FIXME: use bottom half or tasklet
- if (av7110->feeding && mem[0]==0x47)
- dvb_dmx_swfilter_packets(&av7110->demux, mem, 512);
-}
-#else
-static
-void fidbirq (unsigned long data)
-{
- struct av7110_s *av7110 = (struct av7110_s*) data;
- u8 *mem=(u8 *)(av7110->grabbing);
- int num;
- u32 dmapos;
-
- DEB_EE(("av7110: %p\n",av7110));
-
- dmapos=saa7146_read(av7110->dev, PCI_VDP3);
- dmapos-=(dmapos%188);
-
- if (dmapos>=TS_BUFLEN) {
- DEB_S(("bogus dmapos value ignored, av7110: %p\n",av7110));
- return;
- }
-
- if (av7110->tsf) {
- mem+=av7110->ttbp;
- if (dmapos<0x20000) {
- num=1024-av7110->ttbp/188;
- av7110->ttbp=0;
- } else {
- num=(dmapos - av7110->ttbp)/188;
- av7110->ttbp=dmapos;
- }
- } else {
- if (av7110->ttbp>1000*188 && av7110->ttbp<1024*188) {
- if (av7110->feeding)
- dvb_dmx_swfilter_packets(&av7110->demux,
- mem+av7110->ttbp,
- 1024- av7110->ttbp / 188);
- }
- num=dmapos/188;
- av7110->ttbp=dmapos;
- }
-
- av7110->tsf^=1;
- saa7146_write(av7110->dev, DD1_INIT, 0x02000600|(av7110->tsf ? 0x40:0x80));
- saa7146_write(av7110->dev, MC2,
- (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-
- // FIXME: use bottom half or tasklet
- if (av7110->feeding && mem[0]==0x47)
- dvb_dmx_swfilter_packets(&av7110->demux, mem, num);
-}
-#endif
-
//#define DEBUG_TIMING
inline static void
print_time(char *s)
@@ -2247,12 +2076,13 @@ bootcode[] = {
static int
bootarm(av7110_t *av7110)
{
+ struct saa7146_dev *dev= av7110->dev;
u32 ret;
int i;
DEB_EE(("av7110: %p\n",av7110));
- setgpio(av7110, RESET_LINE, GPIO_OUTLO);
+ saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
/* Disable DEBI and GPIO irq */
IER_DISABLE(av7110->dev, MASK_03|MASK_19);
@@ -2282,15 +2112,15 @@ bootarm(av7110_t *av7110)
/* boot */
DEB_D(("bootarm: load boot code\n"));
- setgpio(av7110, ARM_IRQ_LINE, GPIO_IRQLO);
- //setgpio(av7110, DEBI_DONE_LINE, GPIO_INPUT);
- //setgpio(av7110, 3, GPIO_INPUT);
+ saa7146_setgpio(dev, ARM_IRQ_LINE, SAA7146_GPIO_IRQLO);
+ //saa7146_setgpio(dev, DEBI_DONE_LINE, SAA7146_GPIO_INPUT);
+ //saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT);
iwdebi(av7110, DEBISWAB, DPRAM_BASE, (u32) bootcode, sizeof(bootcode));
iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
wait_for_debi_done(av7110);
- setgpio(av7110, RESET_LINE, GPIO_OUTHI);
+ saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
current->state=TASK_INTERRUPTIBLE;
schedule_timeout(HZ);
@@ -2299,7 +2129,7 @@ bootarm(av7110_t *av7110)
if (load_dram(av7110, (u32 *)Root, sizeof(Root))<0)
return -1;
- setgpio(av7110, RESET_LINE, GPIO_OUTLO);
+ saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
mdelay(1);
DEB_D(("bootarm: load dpram code\n"));
@@ -2308,7 +2138,7 @@ bootarm(av7110_t *av7110)
wait_for_debi_done(av7110);
- setgpio(av7110, RESET_LINE, GPIO_OUTHI);
+ saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
mdelay(800);
//ARM_ClearIrq(av7110);
@@ -2412,43 +2242,8 @@ inline static void
Set22K(av7110_t *av7110, int state)
{
DEB_EE(("av7110: %p\n",av7110));
- if (av7110->card_type->type==DVB_CARD_TT_SIEMENS)
+// if (av7110->card_type->type==DVB_CARD_TT_SIEMENS)
outcom(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0);
- if (av7110->card_type->type==DVB_CARD_TT_BUDGET)
- setgpio(av7110, 3, (state ? GPIO_OUTHI : GPIO_OUTLO));
-}
-
-
-/* Diseqc functions only for TT Budget card */
-/* taken from the Skyvision DVB driver by
- Ralph Metzler <rjkm@metzlerbros.de> */
-
-
-inline static void
-DiseqcSendBit(av7110_t *av7110, int data)
-{
- DEB_EE(("av7110: %p\n",av7110));
-
- setgpio(av7110, 3, GPIO_OUTHI);
- udelay(data ? 500 : 1000);
- setgpio(av7110, 3, GPIO_OUTLO);
- udelay(data ? 1000 : 500);
-}
-
-static void
-DiseqcSendByte(av7110_t *av7110, int data)
-{
- int i, par=1, d;
-
- DEB_EE(("av7110: %p\n",av7110));
-
- for (i=7; i>=0; i--)
- {
- d=(data>>i)&1;
- par^=d;
- DiseqcSendBit(av7110, d);
- }
- DiseqcSendBit(av7110, par);
}
inline static int
@@ -2458,8 +2253,10 @@ SendDiSEqCMsg(av7110_t *av7110, int len, u8 *msg, int burst)
DEB_EE(("av7110: %p\n",av7110));
+/*
switch (av7110->card_type->type) {
case DVB_CARD_TT_SIEMENS:
+*/
{
u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) + SendDiSEqC),
16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
@@ -2479,35 +2276,12 @@ SendDiSEqCMsg(av7110_t *av7110, int len, u8 *msg, int burst)
buf[i+4]=msg[i];
SOutCommand(av7110, buf, 18);
+/*
break;
}
-
- case DVB_CARD_TT_BUDGET:
- setgpio(av7110, 3, GPIO_OUTLO);
-
- mdelay(16);
-
- for (i=0; i<len; i++)
- DiseqcSendByte(av7110, msg[i]);
-
- mdelay(16);
-
- if (burst!=-1) {
- if (burst)
- DiseqcSendByte(av7110, 0xff);
- else {
- setgpio(av7110, 3, GPIO_OUTHI);
- udelay(12500);
- setgpio(av7110, 3, GPIO_OUTLO);
- }
-
- ddelay(2);
- }
-
- break;
-
default:
return -1;
+*/
}
return 0;
}
@@ -3223,9 +2997,6 @@ av7110_start_feed(struct dvb_demux_feed *feed)
if (!demux->dmx.frontend)
return -EINVAL;
- if (av7110->card_type->type >= DVB_CARD_TT_BUDGET)
- return TTBStart(av7110);
-
if (feed->pid > 0x1fff)
return -EINVAL;
@@ -3282,9 +3053,6 @@ av7110_stop_feed(struct dvb_demux_feed *feed)
DEB_EE(("av7110: %p\n",av7110));
- if (av7110->card_type->type >= DVB_CARD_TT_BUDGET)
- return TTBStop(av7110);
-
if (feed->type == DMX_TYPE_TS) {
if (feed->ts_type & TS_DECODER) {
if (feed->pes_type >= DMX_TS_PES_OTHER ||
@@ -4221,14 +3989,13 @@ int av7110_register(av7110_t *av7110)
av7110->registered=1;
- if (av7110->card_type->type==DVB_CARD_TT_SIEMENS)
+// if (av7110->card_type->type==DVB_CARD_TT_SIEMENS)
dvb_add_frontend_notifier (av7110->dvb_adapter,
av7110_before_after_tune, av7110);
/**
* init DiSEqC stuff
*/
- if (av7110->card_type->type==DVB_CARD_TT_BUDGET ||
- av7110->card_type->type==DVB_CARD_TT_SIEMENS)
+// if (av7110->card_type->type==DVB_CARD_TT_SIEMENS)
dvb_add_frontend_ioctls (av7110->dvb_adapter,
av7110_diseqc_ioctl, NULL, av7110);
@@ -4250,7 +4017,7 @@ int av7110_register(av7110_t *av7110)
av7110->demux_id[7]=av7110->dvb_adapter->num+0x30;
dvbdemux->priv=(void *) av7110;
- if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) {
+// if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) {
for (i=0; i<32; i++)
av7110->handle2filter[i]=NULL;
@@ -4280,35 +4047,7 @@ int av7110_register(av7110_t *av7110)
av7110->dmxdev.capabilities=0;
dvb_dmxdev_init(&av7110->dmxdev, av7110->dvb_adapter);
- }
-
- if (av7110->card_type->type>=DVB_CARD_TT_BUDGET) {
- dvbdemux->filternum=256;
- dvbdemux->feednum=256;
- dvbdemux->start_feed=av7110_start_feed;
- dvbdemux->stop_feed=av7110_stop_feed;
- dvbdemux->write_to_decoder=NULL;
-
- dvbdemux->dmx.vendor="CIM";
- dvbdemux->dmx.model="sw";
- dvbdemux->dmx.id=av7110->demux_id;
- dvbdemux->dmx.capabilities=(DMX_TS_FILTERING|
- DMX_SECTION_FILTERING|
- DMX_MEMORY_BASED_FILTERING);
-
- dvb_dmx_init(&av7110->demux);
-
- dvbfront->id="hw_frontend";
- dvbfront->vendor="VLSI";
- dvbfront->model="DVB Frontend";
- dvbfront->source=DMX_FRONTEND_0;
-
- av7110->dmxdev.filternum=256;
- av7110->dmxdev.demux=&dvbdemux->dmx;
- av7110->dmxdev.capabilities=0;
-
- dvb_dmxdev_init(&av7110->dmxdev, av7110->dvb_adapter);
- }
+// }
ret=dvbdemux->dmx.add_frontend(&dvbdemux->dmx,
&av7110->hw_frontend);
@@ -4329,7 +4068,7 @@ int av7110_register(av7110_t *av7110)
if (ret<0)
return ret;
- if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) {
+// if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) {
dvb_register_device(av7110->dvb_adapter, &av7110->video_dev,
&dvbdev_video, av7110, DVB_DEVICE_VIDEO);
dvb_register_device(av7110->dvb_adapter, &av7110->audio_dev,
@@ -4347,7 +4086,7 @@ int av7110_register(av7110_t *av7110)
dvb_audio_write,
av7110->audio_dev);
#endif
- }
+// }
av7110->dvb_net.card_num=av7110->dvb_adapter->num;
dvb_net_init(av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);
@@ -4375,14 +4114,14 @@ dvb_unregister(av7110_t *av7110)
dvb_dmxdev_release(&av7110->dmxdev);
dvb_dmx_release(&av7110->demux);
- if (av7110->card_type->type==DVB_CARD_TT_SIEMENS)
+// if (av7110->card_type->type==DVB_CARD_TT_SIEMENS)
dvb_remove_frontend_notifier (av7110->dvb_adapter,
av7110_before_after_tune);
dvb_remove_frontend_ioctls (av7110->dvb_adapter,
av7110_diseqc_ioctl, NULL);
- if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) {
+// if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) {
dvb_unregister_device(av7110->audio_dev);
dvb_unregister_device(av7110->video_dev);
dvb_unregister_device(av7110->osd_dev);
@@ -4390,7 +4129,7 @@ dvb_unregister(av7110_t *av7110)
#ifdef USE_DVB_DSP
dvb_unregister_dsp(av7110->dsp_dev);
#endif
- }
+// }
}
static
@@ -4423,32 +4162,25 @@ int av7110_preinit(struct saa7146_dev* dev)
return 0;
}
-static struct card_info fs_1_5 = { DVB_CARD_TT_SIEMENS, "Siemens cable card PCI rev1.5" };
-static struct card_info fs_1_3 = { DVB_CARD_TT_SIEMENS, "Siemens/Technotrend/Hauppauge PCI rev1.3" };
-static struct card_info ttbs = { DVB_CARD_TT_BUDGET, "TT-Budget/WinTV-NOVA-S PCI" };
-static struct card_info ttbc = { DVB_CARD_TT_BUDGET, "TT-Budget/WinTV-NOVA-C PCI" };
-static struct card_info ttbt = { DVB_CARD_TT_BUDGET, "TT-Budget/WinTV-NOVA-T PCI" };
-static struct card_info ttbci = { DVB_CARD_TT_BUDGET_CI, "TT-Budget/WinTV-NOVA-CI PCI" };
-static struct card_info satel = { DVB_CARD_TT_BUDGET, "SATELCO Multimedia PCI"};
-static struct card_info unkwn = { DVB_CARD_TT_SIEMENS, "Technotrend/Hauppauge PCI rev?(unknown0)?"};
-static struct card_info tt_1_6 = { DVB_CARD_TT_SIEMENS, "Technotrend/Hauppauge PCI rev1.3 or 1.6" };
-static struct card_info tt_2_1 = { DVB_CARD_TT_SIEMENS, "Technotrend/Hauppauge PCI rev2.1" };
-static struct card_info tt_t = { DVB_CARD_TT_SIEMENS, "Technotrend/Hauppauge PCI DVB-T" };
-static struct card_info knc1 = { DVB_CARD_KNC1, "KNC1 DVB-S" };
+struct card_info {
+ char *name;
+};
+
+static char *fs_1_5 = { "Siemens cable card PCI rev1.5" };
+static char *fs_1_3 = { "Siemens/Technotrend/Hauppauge PCI rev1.3" };
+static char *unkwn = { "Technotrend/Hauppauge PCI rev?(unknown0)?"};
+static char *tt_1_6 = { "Technotrend/Hauppauge PCI rev1.3 or 1.6" };
+static char *tt_2_1 = { "Technotrend/Hauppauge PCI rev2.1" };
+static char *tt_t = { "Technotrend/Hauppauge PCI DVB-T" };
struct card_match {
- struct saa7146_sub_info *sub; /* Subsystem ID's or PCI_ANY_ID */
- struct card_info *card;
+ struct saa7146_sub_info *sub; /* Subsystem IDs or PCI_ANY_ID */
+ char **card;
};
static struct saa7146_sub_info sub_data[] = {
{ 0x110a, 0xffff },
{ 0x110a, 0x0000 },
- { 0x13c2, 0x1003 },
- { 0x13c2, 0x1004 },
- { 0x13c2, 0x1005 },
- { 0x13c2, 0x100c },
- { 0x13c2, 0x1013 },
{ 0x13c2, 0x0000 },
{ 0x13c2, 0x1002 },
{ 0x13c2, 0x0001 },
@@ -4458,29 +4190,22 @@ static struct saa7146_sub_info sub_data[] = {
{ 0x13c2, 0x0006 },
{ 0x13c2, 0x0008 },
{ 0xffc2, 0x0000 },
- { 0x1131, 0x4f56 },
{ 0xffff, 0xffff },
};
static struct card_match match_data[] = {
{ &sub_data[ 0], &fs_1_5 },
{ &sub_data[ 1], &fs_1_5 },
- { &sub_data[ 2], &ttbs },
- { &sub_data[ 3], &ttbc },
- { &sub_data[ 4], &ttbt },
- { &sub_data[ 5], &ttbci },
- { &sub_data[ 6], &satel },
- { &sub_data[ 7], &fs_1_3 },
- { &sub_data[ 8], &unkwn },
- { &sub_data[ 9], &tt_1_6 },
- { &sub_data[10], &tt_2_1 },
- { &sub_data[11], &tt_2_1 },
- { &sub_data[12], &tt_2_1 },
- { &sub_data[13], &tt_1_6 },
- { &sub_data[14], &tt_t },
- { &sub_data[15], &unkwn },
- { &sub_data[16], &knc1 },
- { &sub_data[17], NULL },
+ { &sub_data[ 2], &fs_1_3 },
+ { &sub_data[ 3], &unkwn },
+ { &sub_data[ 4], &tt_1_6 },
+ { &sub_data[ 5], &tt_2_1 },
+ { &sub_data[ 6], &tt_2_1 },
+ { &sub_data[ 7], &tt_2_1 },
+ { &sub_data[ 8], &tt_1_6 },
+ { &sub_data[ 9], &tt_t },
+ { &sub_data[10], &unkwn },
+ { &sub_data[11], NULL },
};
@@ -4506,7 +4231,7 @@ int av7110_probe(struct saa7146_dev* dev, unsigned int subvendor, unsigned int s
return -ENOMEM;
}
memset(av7110, 0, sizeof(av7110_t));
- av7110->card_type = match_data[i].card;
+ av7110->card_name = *match_data[i].card;
(av7110_t*)dev->ext_priv = av7110;
@@ -4517,56 +4242,33 @@ static
int av7110_attach (struct saa7146_dev* dev)
{
av7110_t *av7110 = (av7110_t*)dev->ext_priv;
- struct scatterlist *slist = NULL;
- int slen = 0;
- int length = TS_WIDTH*TS_HEIGHT;
- int pages = (length+PAGE_SIZE-1)/PAGE_SIZE;
int ret = 0;
DEB_EE(("dev: %p, av7110: %p\n",dev,av7110));
- saa7146_video_uops.init(dev);
+ if( 0 != saa7146_vv_init(dev)) {
+ ERR(("cannot init capture device. skipping.\n"));
+ return -1;
+ }
+
if( 0 != saa7146_register_device(&av7110->vd, dev, "av7710", VFL_TYPE_GRABBER)) {
ERR(("cannot register capture device. skipping.\n"));
+ saa7146_vv_release(dev);
return -1;
}
av7110->dev=(struct saa7146_dev *)dev;
- dvb_register_adapter(&av7110->dvb_adapter, av7110->card_type->name);
+ dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name);
saa7146_i2c_adapter_prepare(dev, NULL, SAA7146_I2C_BUS_BIT_RATE_3200);
av7110->i2c_bus = dvb_register_i2c_bus (master_xfer, dev, av7110->dvb_adapter, 0);
if (!av7110->i2c_bus) {
+ saa7146_unregister_device(&av7110->vd, dev);
+ saa7146_vv_release(dev);
dvb_unregister_adapter (av7110->dvb_adapter);
return -ENOMEM;
}
-
-// fixme if (av7110->card_type->type >= DVB_CARD_TT_BUDGET)
- av7110->grabbing = vmalloc(length);
- if (!av7110->grabbing) {
- printk(KERN_ERR "dvb: vmalloc() failed.\n");
- ret = -ENOMEM;
- goto err;
- }
-
- if (!(slist = videobuf_vmalloc_to_sg(av7110->grabbing, pages))) {
- printk(KERN_ERR "dvb: videobuf_vmalloc_to_sg() failed.\n");
- ret = -ENOMEM;
- goto err;
- }
-
- if (saa7146_pgtable_alloc(dev->pci, &av7110->pt)) {
- printk(KERN_ERR "dvb: saa7146_pgtable_alloc() failed.\n");
- ret = -ENOMEM;
- goto err;
- }
-
- slen = pci_map_sg(dev->pci,slist,pages,PCI_DMA_FROMDEVICE);
- saa7146_pgtable_build_single(dev->pci, &av7110->pt, slist, slen);
-
-// }
-
saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
saa7146_write(dev, BCS_CTRL, 0x80400040);
@@ -4581,8 +4283,6 @@ int av7110_attach (struct saa7146_dev* dev)
tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110);
tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110);
- tasklet_init (&av7110->vpe_tasklet, vpeirq, (unsigned long) av7110);
- tasklet_init (&av7110->fidb_tasklet, fidbirq, (unsigned long) av7110);
sema_init(&av7110->pid_mutex, 1);
@@ -4640,23 +4340,18 @@ int av7110_attach (struct saa7146_dev* dev)
/* handle different card types */
/* load firmware into AV7110 cards */
- if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) {
+// if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) {
bootarm(av7110);
firmversion(av7110);
if ((av7110->arm_app&0xffff)<0x2502) {
printk("av7110: Warning, firmware version is too old. System might be unstable!!!\n");
}
kernel_thread(arm_thread, (void *) av7110, 0);
- } else {
- saa7146_write(av7110->dev, DD1_INIT, 0x02000600);
- saa7146_write(av7110->dev, MC2,
- (MASK_09 | MASK_25 | MASK_10 | MASK_26));
- setgpio(av7110, 2, GPIO_OUTHI); /* frontend power on */
- }
+// }
SetVolume(av7110, 0xff, 0xff);
- if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) {
+// if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) {
VidMode(av7110, vidmode);
/* remaining inits according to card and frontend type */
@@ -4693,11 +4388,11 @@ int av7110_attach (struct saa7146_dev* dev)
outcom(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
outcom(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
- //setgpio(av7110, 1, GPIO_OUTHI); // RGB on, SCART pin 16
- //setgpio(av7110, 3, GPIO_OUTLO); // SCARTpin 8
+ //saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
+ //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
av7110->adac_type = DVB_ADAC_NONE;
}
- }
+// }
av7110_setup_irc_config (av7110, 0);
av7110_register(av7110);
@@ -4707,12 +4402,9 @@ int av7110_attach (struct saa7146_dev* dev)
return 0;
err:
- if( NULL != av7110->grabbing ) {
- vfree(av7110->grabbing);
- }
- if( NULL != slist ) {
- kfree(slist);
- }
+ /* FIXME: error handling is totally bogus: memory does not get freed ... */
+ saa7146_unregister_device(&av7110->vd, dev);
+ saa7146_vv_release(dev);
dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, av7110->i2c_bus->id);
dvb_unregister_adapter (av7110->dvb_adapter);
return ret;
@@ -4747,11 +4439,6 @@ int av7110_detach (struct saa7146_dev* saa)
pci_free_consistent(saa->pci, 8192, av7110->debi_virt,
av7110->debi_bus);
-// fixme if (av7110->card_type->type >= DVB_CARD_TT_BUDGET)
- saa7146_pgtable_free(saa->pci, &av7110->pt);
- vfree(av7110->grabbing);
-// }
-
dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, av7110->i2c_bus->id);
dvb_unregister_adapter (av7110->dvb_adapter);
@@ -4776,12 +4463,6 @@ void av7110_irq(struct saa7146_dev* dev, u32 *isr)
if (*isr & MASK_03)
tasklet_schedule (&av7110->gpio_tasklet);
-
- if (*isr & MASK_10)
- tasklet_schedule (&av7110->vpe_tasklet);
-
- if (*isr & MASK_07)
- tasklet_schedule (&av7110->fidb_tasklet);
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
@@ -4809,35 +4490,38 @@ struct saa7146_standard standard[] = {
};
static
-struct saa7146_extension av7110_extension = {
- .name = "dvb\0",
+struct saa7146_ext_vv av7110_vv_data = {
.inputs = 1,
.audios = 1,
.capabilities = 0,
-
.flags = SAA7146_EXT_SWAP_ODD_EVEN,
+ .stds = &standard[0],
+ .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
+ .std_callback = NULL,
+
+ .ioctls = &ioctls[0],
+ .ioctl = av7110_ioctl,
+};
+
+static
+struct saa7146_extension av7110_extension = {
+ .name = "dvb\0",
+
.devices = &sub_data[0],
.module = THIS_MODULE,
-
+ .ext_vv_data = &av7110_vv_data,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
.inc_use = av7110_inc_use,
.dec_use = av7110_dec_use,
#endif
- .stds = &standard[0],
- .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
- .std_callback = NULL,
-
- .ioctls = &ioctls[0],
-
.preinit = av7110_preinit,
.probe = av7110_probe,
.attach = av7110_attach,
.detach = av7110_detach,
- .ioctl = av7110_ioctl,
- .irq_mask = MASK_07|MASK_10|MASK_19|MASK_03, // |MASK_27,
+ .irq_mask = MASK_19|MASK_03,
.irq_func = av7110_irq,
};
diff --git a/linux/drivers/media/dvb/av7110/av7110.h b/linux/drivers/media/dvb/ttpci/av7110.h
index a379a3fcd..d1eabe3ab 100644
--- a/linux/drivers/media/dvb/av7110/av7110.h
+++ b/linux/drivers/media/dvb/ttpci/av7110.h
@@ -11,7 +11,7 @@
#include <linux/devfs_fs_kernel.h>
#endif
-#include "saa7146.h"
+#include "saa7146_vv.h"
/* DEBI transfer mode defs */
@@ -39,11 +39,6 @@
#include "dvb_filter.h"
#include "dvb_net.h"
-#define DVB_CARD_TT_SIEMENS 0
-#define DVB_CARD_TT_BUDGET 1
-#define DVB_CARD_TT_BUDGET_CI 2
-#define DVB_CARD_KNC1 3
-
typedef enum BOOTSTATES
{
BOOTSTATE_BUFFER_EMPTY = 0,
@@ -51,16 +46,6 @@ typedef enum BOOTSTATES
BOOTSTATE_BOOT_COMPLETE = 2
} BOOTSTATES;
-typedef enum GPIO_MODE
-{
- GPIO_INPUT = 0x00,
- GPIO_IRQHI = 0x10,
- GPIO_IRQLO = 0x20,
- GPIO_IRQHL = 0x30,
- GPIO_OUTLO = 0x40,
- GPIO_OUTHI = 0x50
-} GPIO_MODE;
-
typedef enum
{ RP_None,
AudioPES,
@@ -111,14 +96,14 @@ typedef enum {
// switch defines
#define SB_GPIO 3
-#define SB_OFF GPIO_OUTLO //SlowBlank aus (TV-Mode)
-#define SB_ON GPIO_INPUT //SlowBlank an (AV-Mode)
-#define SB_WIDE GPIO_OUTHI //SlowBlank 6V (16/9-Mode) nicht realisiert
+#define SB_OFF SAA7146_GPIO_OUTLO //SlowBlank aus (TV-Mode)
+#define SB_ON SAA7146_GPIO_INPUT //SlowBlank an (AV-Mode)
+#define SB_WIDE SAA7146_GPIO_OUTHI //SlowBlank 6V (16/9-Mode) nicht realisiert
#define FB_GPIO 1
-#define FB_OFF GPIO_LO //FastBlank aus (CVBS-Mode)
-#define FB_ON GPIO_OUTHI //FastBlank an (RGB-Mode)
-#define FB_LOOP GPIO_INPUT //FastBlank der PC-Grafik durchschleifen
+#define FB_OFF SAA7146_GPIO_LO //FastBlank aus (CVBS-Mode)
+#define FB_ON SAA7146_GPIO_OUTHI //FastBlank an (RGB-Mode)
+#define FB_LOOP SAA7146_GPIO_INPUT //FastBlank der PC-Grafik durchschleifen
typedef enum VIDEOOUTPUTMODE
{
@@ -471,11 +456,6 @@ typedef struct p2t_s {
struct dvb_demux_feed *feed;
} p2t_t;
-struct card_info {
- int type;
- char *name;
-};
-
/* place to store all the necessary device information */
typedef struct av7110_s {
@@ -488,15 +468,10 @@ typedef struct av7110_s {
struct saa7146_dev *dev;
struct dvb_i2c_bus *i2c_bus;
- struct card_info *card_type;
-
- unsigned char *grabbing;
- struct saa7146_pgtable pt;
+ char *card_name;
struct tasklet_struct debi_tasklet;
struct tasklet_struct gpio_tasklet;
- struct tasklet_struct vpe_tasklet;
- struct tasklet_struct fidb_tasklet;
int adac_type; /* audio DAC type */
#define DVB_ADAC_TI 0
@@ -586,11 +561,6 @@ typedef struct av7110_s {
u8 *kbuf[2];
int sinfo;
- int shsize;
- int swsize;
-
- int tsf;
- u32 ttbp;
int feeding;
int arm_errors;
diff --git a/linux/drivers/media/dvb/av7110/av7110_firm.h b/linux/drivers/media/dvb/ttpci/av7110_firm.h
index 5c93deb3d..5c93deb3d 100644
--- a/linux/drivers/media/dvb/av7110/av7110_firm.h
+++ b/linux/drivers/media/dvb/ttpci/av7110_firm.h
diff --git a/linux/drivers/media/dvb/av7110/av7110_ipack.c b/linux/drivers/media/dvb/ttpci/av7110_ipack.c
index 3d16442e6..3d16442e6 100644
--- a/linux/drivers/media/dvb/av7110/av7110_ipack.c
+++ b/linux/drivers/media/dvb/ttpci/av7110_ipack.c
diff --git a/linux/drivers/media/dvb/av7110/av7110_ipack.h b/linux/drivers/media/dvb/ttpci/av7110_ipack.h
index d1c995aff..d1c995aff 100644
--- a/linux/drivers/media/dvb/av7110/av7110_ipack.h
+++ b/linux/drivers/media/dvb/ttpci/av7110_ipack.h
diff --git a/linux/drivers/media/dvb/av7110/av7110_ir.c b/linux/drivers/media/dvb/ttpci/av7110_ir.c
index 4e89ed71f..4e89ed71f 100644
--- a/linux/drivers/media/dvb/av7110/av7110_ir.c
+++ b/linux/drivers/media/dvb/ttpci/av7110_ir.c
diff --git a/linux/drivers/media/video/mxb.c b/linux/drivers/media/video/mxb.c
index ce8a4d9b4..2c25aa644 100644
--- a/linux/drivers/media/video/mxb.c
+++ b/linux/drivers/media/video/mxb.c
@@ -18,7 +18,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <saa7146.h>
+#include <saa7146_vv.h>
#include "mxb.h"
#include "tea6415c.h"
@@ -176,6 +176,31 @@ struct mxb
int cur_mute; /* current mute status */
};
+static int mxb_vbi_bypass(struct saa7146_dev* dev)
+{
+ struct mxb* mxb = (struct mxb*)dev->ext_priv;
+ s32 byte = 0x0;
+ int result = 0;
+
+ DEB_EE(("dev:%p\n",dev));
+
+ /* switch bypass in saa7111a, this should be done in the
+ saa7111a driver of course... */
+ if ( -1 == (result = i2c_smbus_read_byte_data(mxb->saa7111a, SAA711X_OUTPUT_CONTROL_3))) {
+ DEB_D(("could not read from saa7111a.\n"));
+ return -EFAULT;
+ }
+ byte = result;
+ byte &= 0xf0;
+ byte |= 0x0a;
+
+ if ( 0 != (result = i2c_smbus_write_byte_data(mxb->saa7111a, SAA711X_OUTPUT_CONTROL_3, byte))) {
+ DEB_D(("could not write to saa7111a.\n"));
+ return -EFAULT;
+ }
+ return 0;
+}
+
/* this function gets called very early in the registration process of
the extension. it has been reported that some devices need to enable
the i2c-bus explicitly for example -- this can be done here. please
@@ -357,6 +382,8 @@ static int mxb_init_done(struct saa7146_dev* dev)
// i = VIDEO_MODE_PAL;
// mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_NORM, &i);
+ mxb_vbi_bypass(dev);
+
/* select a tuner type */
i = 5;
mxb->tuner->driver->command(mxb->tuner,TUNER_SET_TYPE, &i);
@@ -451,7 +478,7 @@ static int mxb_attach(struct saa7146_dev* dev)
/* checking for i2c-devices can be omitted here, because we
already did this in "mxb_vl42_probe" */
- saa7146_video_uops.init(dev);
+ saa7146_vv_init(dev);
if( 0 != saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
ERR(("cannot register capture v4l2 device. skipping.\n"));
return -1;
@@ -459,10 +486,8 @@ static int mxb_attach(struct saa7146_dev* dev)
/* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
- saa7146_vbi_uops.init(dev);
if( 0 != saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
ERR(("cannot register vbi v4l2 device. skipping.\n"));
- return -1;
}
}
@@ -494,6 +519,7 @@ static int mxb_detach(struct saa7146_dev* dev)
if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
saa7146_unregister_device(&mxb->vbi_dev,dev);
}
+ saa7146_vv_release(dev);
mxb_num--;
@@ -503,31 +529,6 @@ static int mxb_detach(struct saa7146_dev* dev)
return 0;
}
-static int mxb_vbi_bypass(struct saa7146_dev* dev)
-{
- struct mxb* mxb = (struct mxb*)dev->ext_priv;
- s32 byte = 0x0;
- int result = 0;
-
- DEB_EE(("dev:%p\n",dev));
-
- /* switch bypass in saa7111a, this should be done in the
- saa7111a driver of course... */
- if ( -1 == (result = i2c_smbus_read_byte_data(mxb->saa7111a, SAA711X_OUTPUT_CONTROL_3))) {
- DEB_D(("could not read from saa7111a.\n"));
- return -EFAULT;
- }
- byte = result;
- byte &= 0xf0;
- byte |= 0x0a;
-
- if ( 0 != (result = i2c_smbus_write_byte_data(mxb->saa7111a, SAA711X_OUTPUT_CONTROL_3, byte))) {
- DEB_D(("could not write to saa7111a.\n"));
- return -EFAULT;
- }
- return 0;
-}
-
/* hack: this should go into saa711x */
static int saa7111_set_gpio(struct saa7146_dev *dev, int bl)
{
@@ -561,7 +562,8 @@ static int saa7111_set_gpio(struct saa7146_dev *dev, int bl)
static int mxb_ioctl(struct saa7146_dev *dev, unsigned int cmd, void *arg)
{
struct mxb* mxb = (struct mxb*)dev->ext_priv;
-
+ struct saa7146_vv *vv = dev->vv_data;
+
switch(cmd) {
case VIDIOC_ENUMINPUT:
{
@@ -909,7 +911,7 @@ static int mxb_ioctl(struct saa7146_dev *dev, unsigned int cmd, void *arg)
/* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
spin_lock(&dev->slock);
- dev->vbi_fieldcount = 0;
+ vv->vbi_fieldcount = 0;
spin_unlock(&dev->slock);
return 0;
@@ -1017,33 +1019,34 @@ static struct saa7146_sub_info sub_data[] = {
};
static
-struct saa7146_extension extension = {
- .name = MXB_IDENTIFIER,
+struct saa7146_ext_vv vv_data = {
.inputs = MXB_INPUTS,
.audios = MXB_AUDIOS,
.capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
-
.flags = 0,
-
+ .stds = &standard[0],
+ .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
+ .std_callback = &std_callback,
+ .ioctls = &ioctls[0],
+ .ioctl = mxb_ioctl,
+};
+
+static
+struct saa7146_extension extension = {
+ .name = MXB_IDENTIFIER,
.devices = &sub_data[0],
.module = THIS_MODULE,
+ .ext_vv_data = &vv_data,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
.inc_use = mxb_inc_use,
.dec_use = mxb_dec_use,
#endif
- .stds = &standard[0],
- .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
- .std_callback = &std_callback,
-
- .ioctls = &ioctls[0],
-
.preinit = mxb_preinit,
.probe = mxb_probe,
.attach = mxb_attach,
.detach = mxb_detach,
- .ioctl = mxb_ioctl,
.irq_mask = 0,
.irq_func = NULL,