]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/media/video/ivtv/ivtv-driver.h
V4L/DVB (6086): ivtv: fix output mode processing: UDMA_YUV wasn't cleared
[linux-2.6-omap-h63xx.git] / drivers / media / video / ivtv / ivtv-driver.h
index 8abb34a35816917c5af6392beb873020e387dafe..3ed4703956d3657f90247ec7e757a052e44b6f49 100644 (file)
@@ -38,7 +38,6 @@
 
 #include <linux/version.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <media/tuner.h>
 #include <media/cx2341x.h>
 
-/* #define HAVE_XC3028 1 */
-
 #include <media/ivtv.h>
 
+
 #define IVTV_ENCODER_OFFSET    0x00000000
 #define IVTV_ENCODER_SIZE      0x00800000      /* Last half isn't needed 0x01000000 */
 
 
 extern const u32 yuv_offset[4];
 
-/* Maximum ivtv driver instances.
-   Based on 6 PVR500s each with two PVR15s...
-   TODO: make this dynamic. I believe it is only a global in order to support
-    ivtv-fb. There must be a better way to do that. */
-#define IVTV_MAX_CARDS 12
+/* Maximum ivtv driver instances. Some people have a huge number of
+   capture cards, so set this to a high value. */
+#define IVTV_MAX_CARDS 32
 
 /* Supported cards */
 #define IVTV_CARD_PVR_250            0 /* WinTV PVR 250 */
@@ -116,12 +112,10 @@ extern const u32 yuv_offset[4];
 #define IVTV_CARD_GOTVIEW_PCI_DVD2   15        /* GotView PCI DVD2 */
 #define IVTV_CARD_YUAN_MPC622        16        /* Yuan MPC622 miniPCI */
 #define IVTV_CARD_DCTMTVP1          17 /* DIGITAL COWBOY DCT-MTVP1 */
-#ifdef HAVE_XC3028
-#define IVTV_CARD_PG600V2           18 /* Yuan PG600V2/GotView PCI DVD Lite/Club3D ZAP-TV1x01 */
-#define IVTV_CARD_LAST                      18
-#else
-#define IVTV_CARD_LAST                      17
-#endif
+#define IVTV_CARD_PG600V2           18 /* Yuan PG600V2/GotView PCI DVD Lite */
+#define IVTV_CARD_CLUB3D            19 /* Club3D ZAP-TV1x01 */
+#define IVTV_CARD_AVERTV_MCE116             20 /* AVerTV MCE 116 Plus */
+#define IVTV_CARD_LAST                      20
 
 /* Variants of existing cards but with the same PCI IDs. The driver
    detects these based on other device information.
@@ -191,10 +185,12 @@ extern const u32 yuv_offset[4];
 #define IVTV_DEFAULT_ENC_MPG_BUFFERS 4
 #define IVTV_DEFAULT_ENC_YUV_BUFFERS 2
 #define IVTV_DEFAULT_ENC_VBI_BUFFERS 1
-#define IVTV_DEFAULT_ENC_PCM_BUFFERS 1
+/* Exception: size in kB for this stream (MB is overkill) */
+#define IVTV_DEFAULT_ENC_PCM_BUFFERS 320
 #define IVTV_DEFAULT_DEC_MPG_BUFFERS 1
 #define IVTV_DEFAULT_DEC_YUV_BUFFERS 1
-#define IVTV_DEFAULT_DEC_VBI_BUFFERS 1
+/* Exception: size in kB for this stream (MB is way overkill) */
+#define IVTV_DEFAULT_DEC_VBI_BUFFERS 64
 
 /* ======================================================================== */
 /* ========================== END USER SETTABLE DMA VARIABLES ============= */
@@ -259,17 +255,18 @@ extern const u32 yuv_offset[4];
 
 /* debugging */
 
-#define IVTV_DBGFLG_WARN  (1 << 0)
-#define IVTV_DBGFLG_INFO  (1 << 1)
-#define IVTV_DBGFLG_API   (1 << 2)
-#define IVTV_DBGFLG_DMA   (1 << 3)
-#define IVTV_DBGFLG_IOCTL (1 << 4)
-#define IVTV_DBGFLG_I2C   (1 << 5)
-#define IVTV_DBGFLG_IRQ   (1 << 6)
-#define IVTV_DBGFLG_DEC   (1 << 7)
-#define IVTV_DBGFLG_YUV   (1 << 8)
+#define IVTV_DBGFLG_WARN    (1 << 0)
+#define IVTV_DBGFLG_INFO    (1 << 1)
+#define IVTV_DBGFLG_MB      (1 << 2)
+#define IVTV_DBGFLG_IOCTL   (1 << 3)
+#define IVTV_DBGFLG_FILE    (1 << 4)
+#define IVTV_DBGFLG_DMA     (1 << 5)
+#define IVTV_DBGFLG_IRQ     (1 << 6)
+#define IVTV_DBGFLG_DEC     (1 << 7)
+#define IVTV_DBGFLG_YUV     (1 << 8)
+#define IVTV_DBGFLG_I2C     (1 << 9)
 /* Flag to turn on high volume debugging */
-#define IVTV_DBGFLG_HIGHVOL (1 << 9)
+#define IVTV_DBGFLG_HIGHVOL (1 << 10)
 
 /* NOTE: extra space before comma in 'itv->num , ## args' is required for
    gcc-2.95, otherwise it won't compile. */
@@ -278,53 +275,37 @@ extern const u32 yuv_offset[4];
                if ((x) & ivtv_debug) \
                        printk(KERN_INFO "ivtv%d " type ": " fmt, itv->num , ## args); \
        } while (0)
-#define IVTV_DEBUG_WARN(fmt, args...)  IVTV_DEBUG(IVTV_DBGFLG_WARN, "warning", fmt , ## args)
-#define IVTV_DEBUG_INFO(fmt, args...)  IVTV_DEBUG(IVTV_DBGFLG_INFO, "info",fmt , ## args)
-#define IVTV_DEBUG_API(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_API, "api", fmt , ## args)
-#define IVTV_DEBUG_DMA(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_DMA, "dma", fmt , ## args)
+#define IVTV_DEBUG_WARN(fmt, args...)  IVTV_DEBUG(IVTV_DBGFLG_WARN,  "warn",  fmt , ## args)
+#define IVTV_DEBUG_INFO(fmt, args...)  IVTV_DEBUG(IVTV_DBGFLG_INFO,  "info",  fmt , ## args)
+#define IVTV_DEBUG_MB(fmt, args...)    IVTV_DEBUG(IVTV_DBGFLG_MB,    "mb",    fmt , ## args)
+#define IVTV_DEBUG_DMA(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_DMA,   "dma",   fmt , ## args)
 #define IVTV_DEBUG_IOCTL(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_IOCTL, "ioctl", fmt , ## args)
-#define IVTV_DEBUG_I2C(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_I2C, "i2c", fmt , ## args)
-#define IVTV_DEBUG_IRQ(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_IRQ, "irq", fmt , ## args)
-#define IVTV_DEBUG_DEC(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_DEC, "dec", fmt , ## args)
-#define IVTV_DEBUG_YUV(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_YUV, "yuv", fmt , ## args)
+#define IVTV_DEBUG_FILE(fmt, args...)  IVTV_DEBUG(IVTV_DBGFLG_FILE,  "file",  fmt , ## args)
+#define IVTV_DEBUG_I2C(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_I2C,   "i2c",   fmt , ## args)
+#define IVTV_DEBUG_IRQ(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_IRQ,   "irq",   fmt , ## args)
+#define IVTV_DEBUG_DEC(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_DEC,   "dec",   fmt , ## args)
+#define IVTV_DEBUG_YUV(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_YUV,   "yuv",   fmt , ## args)
 
 #define IVTV_DEBUG_HIGH_VOL(x, type, fmt, args...) \
        do { \
                if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) \
                        printk(KERN_INFO "ivtv%d " type ": " fmt, itv->num , ## args); \
        } while (0)
-#define IVTV_DEBUG_HI_WARN(fmt, args...)  IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN, "warning", fmt , ## args)
-#define IVTV_DEBUG_HI_INFO(fmt, args...)  IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_INFO, "info",fmt , ## args)
-#define IVTV_DEBUG_HI_API(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_API, "api", fmt , ## args)
-#define IVTV_DEBUG_HI_DMA(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DMA, "dma", fmt , ## args)
+#define IVTV_DEBUG_HI_WARN(fmt, args...)  IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN,  "warn",  fmt , ## args)
+#define IVTV_DEBUG_HI_INFO(fmt, args...)  IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_INFO,  "info",  fmt , ## args)
+#define IVTV_DEBUG_HI_MB(fmt, args...)    IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_MB,    "mb",    fmt , ## args)
+#define IVTV_DEBUG_HI_DMA(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DMA,   "dma",   fmt , ## args)
 #define IVTV_DEBUG_HI_IOCTL(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_IOCTL, "ioctl", fmt , ## args)
-#define IVTV_DEBUG_HI_I2C(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_I2C, "i2c", fmt , ## args)
-#define IVTV_DEBUG_HI_IRQ(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_IRQ, "irq", fmt , ## args)
-#define IVTV_DEBUG_HI_DEC(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DEC, "dec", fmt , ## args)
-#define IVTV_DEBUG_HI_YUV(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_YUV, "yuv", fmt , ## args)
-
-#define IVTV_FB_DEBUG(x, type, fmt, args...) \
-       do { \
-               if ((x) & ivtv_debug) \
-                       printk(KERN_INFO "ivtv%d-fb " type ": " fmt, itv->num , ## args); \
-       } while (0)
-#define IVTV_FB_DEBUG_WARN(fmt, args...)  IVTV_FB_DEBUG(IVTV_DBGFLG_WARN, "warning", fmt , ## args)
-#define IVTV_FB_DEBUG_INFO(fmt, args...)  IVTV_FB_DEBUG(IVTV_DBGFLG_INFO, "info", fmt , ## args)
-#define IVTV_FB_DEBUG_API(fmt, args...)   IVTV_FB_DEBUG(IVTV_DBGFLG_API, "api", fmt , ## args)
-#define IVTV_FB_DEBUG_DMA(fmt, args...)   IVTV_FB_DEBUG(IVTV_DBGFLG_DMA, "dma", fmt , ## args)
-#define IVTV_FB_DEBUG_IOCTL(fmt, args...) IVTV_FB_DEBUG(IVTV_DBGFLG_IOCTL, "ioctl", fmt , ## args)
-#define IVTV_FB_DEBUG_I2C(fmt, args...)   IVTV_FB_DEBUG(IVTV_DBGFLG_I2C, "i2c", fmt , ## args)
-#define IVTV_FB_DEBUG_IRQ(fmt, args...)   IVTV_FB_DEBUG(IVTV_DBGFLG_IRQ, "irq", fmt , ## args)
-#define IVTV_FB_DEBUG_DEC(fmt, args...)   IVTV_FB_DEBUG(IVTV_DBGFLG_DEC, "dec", fmt , ## args)
-#define IVTV_FB_DEBUG_YUV(fmt, args...)   IVTV_FB_DEBUG(IVTV_DBGFLG_YUV, "yuv", fmt , ## args)
+#define IVTV_DEBUG_HI_FILE(fmt, args...)  IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_FILE,  "file",  fmt , ## args)
+#define IVTV_DEBUG_HI_I2C(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_I2C,   "i2c",   fmt , ## args)
+#define IVTV_DEBUG_HI_IRQ(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_IRQ,   "irq",   fmt , ## args)
+#define IVTV_DEBUG_HI_DEC(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DEC,   "dec",   fmt , ## args)
+#define IVTV_DEBUG_HI_YUV(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_YUV,   "yuv",   fmt , ## args)
 
 /* Standard kernel messages */
 #define IVTV_ERR(fmt, args...)      printk(KERN_ERR  "ivtv%d: " fmt, itv->num , ## args)
 #define IVTV_WARN(fmt, args...)     printk(KERN_WARNING "ivtv%d: " fmt, itv->num , ## args)
 #define IVTV_INFO(fmt, args...)     printk(KERN_INFO "ivtv%d: " fmt, itv->num , ## args)
-#define IVTV_FB_ERR(fmt, args...)   printk(KERN_ERR  "ivtv%d-fb: " fmt, itv->num , ## args)
-#define IVTV_FB_WARN(fmt, args...)  printk(KERN_WARNING  "ivtv%d-fb: " fmt, itv->num , ## args)
-#define IVTV_FB_INFO(fmt, args...)  printk(KERN_INFO "ivtv%d-fb: " fmt, itv->num , ## args)
 
 /* Values for IVTV_API_DEC_PLAYBACK_SPEED mpeg_frame_type_mask parameter: */
 #define MPEG_FRAME_TYPE_IFRAME 1
@@ -344,7 +325,7 @@ extern int ivtv_debug;
 
 
 struct ivtv_options {
-       int megabytes[IVTV_MAX_STREAMS]; /* Size in megabytes of each stream */
+       int kilobytes[IVTV_MAX_STREAMS]; /* Size in kilobytes of each stream */
        int cardtype;           /* force card type on load */
        int tuner;              /* set tuner on load */
        int radio;              /* enable/disable radio */
@@ -379,7 +360,7 @@ struct ivtv_mailbox_data {
 };
 
 /* per-buffer bit flags */
-#define IVTV_F_B_NEED_BUF_SWAP  0      /* this buffer should be byte swapped */
+#define IVTV_F_B_NEED_BUF_SWAP  (1 << 0)       /* this buffer should be byte swapped */
 
 /* per-stream, s_flags */
 #define IVTV_F_S_DMA_PENDING   0       /* this stream has pending DMA */
@@ -405,7 +386,6 @@ struct ivtv_mailbox_data {
 #define IVTV_F_I_RADIO_USER       5    /* The radio tuner is selected */
 #define IVTV_F_I_DIG_RST          6    /* Reset digitizer */
 #define IVTV_F_I_DEC_YUV          7    /* YUV instead of MPG is being decoded */
-#define IVTV_F_I_ENC_VBI          8    /* VBI DMA */
 #define IVTV_F_I_UPDATE_CC        9    /* CC should be updated */
 #define IVTV_F_I_UPDATE_WSS       10   /* WSS should be updated */
 #define IVTV_F_I_UPDATE_VPS       11   /* VPS should be updated */
@@ -418,6 +398,8 @@ struct ivtv_mailbox_data {
 #define IVTV_F_I_WORK_HANDLER_PIO  18  /* there is work to be done for PIO */
 #define IVTV_F_I_PIO              19   /* PIO in progress */
 #define IVTV_F_I_DEC_PAUSED       20   /* the decoder is paused */
+#define IVTV_F_I_INITED                   21   /* set after first open */
+#define IVTV_F_I_FAILED                   22   /* set if first open failed */
 
 /* Event notifications */
 #define IVTV_F_I_EV_DEC_STOPPED           28   /* decoder stopped event */
@@ -426,7 +408,7 @@ struct ivtv_mailbox_data {
 #define IVTV_F_I_EV_VSYNC_ENABLED  31  /* VSYNC event enabled */
 
 /* Scatter-Gather array element, used in DMA transfers */
-struct ivtv_SG_element {
+struct ivtv_sg_element {
        u32 src;
        u32 dst;
        u32 size;
@@ -436,9 +418,11 @@ struct ivtv_user_dma {
        struct mutex lock;
        int page_count;
        struct page *map[IVTV_DMA_SG_OSD_ENT];
+       /* Needed when dealing with highmem userspace buffers */
+       struct page *bouncemap[IVTV_DMA_SG_OSD_ENT];
 
        /* Base Dev SG Array for cx23415/6 */
-       struct ivtv_SG_element SGarray[IVTV_DMA_SG_OSD_ENT];
+       struct ivtv_sg_element SGarray[IVTV_DMA_SG_OSD_ENT];
        dma_addr_t SG_handle;
        int SG_length;
 
@@ -458,7 +442,8 @@ struct ivtv_dma_page_info {
 struct ivtv_buffer {
        struct list_head list;
        dma_addr_t dma_handle;
-       unsigned long b_flags;
+       unsigned short b_flags;
+       unsigned short dma_xfer_cnt;
        char *buf;
 
        u32 bytesused;
@@ -488,6 +473,10 @@ struct ivtv_stream {
        int dma;                /* can be PCI_DMA_TODEVICE,
                                   PCI_DMA_FROMDEVICE or
                                   PCI_DMA_NONE */
+       u32 pending_offset;
+       u32 pending_backup;
+       u64 pending_pts;
+
        u32 dma_offset;
        u32 dma_backup;
        u64 dma_pts;
@@ -508,11 +497,18 @@ struct ivtv_stream {
        struct ivtv_queue q_dma;        /* waiting for DMA */
        struct ivtv_queue q_predma;     /* waiting for DMA */
 
+       /* DMA xfer counter, buffers belonging to the same DMA
+          xfer will have the same dma_xfer_cnt. */
+       u16 dma_xfer_cnt;
+
        /* Base Dev SG Array for cx23415/6 */
-       struct ivtv_SG_element *SGarray;
-       struct ivtv_SG_element *PIOarray;
-       dma_addr_t SG_handle;
-       int SG_length;
+       struct ivtv_sg_element *sg_pending;
+       struct ivtv_sg_element *sg_processing;
+       struct ivtv_sg_element *sg_dma;
+       dma_addr_t sg_handle;
+       int sg_pending_size;
+       int sg_processing_size;
+       int sg_processed;
 
        /* SG List of Buffers */
        struct scatterlist *SGlist;
@@ -521,6 +517,7 @@ struct ivtv_stream {
 struct ivtv_open_id {
        u32 open_id;
        int type;
+       int yuv_frames;
        enum v4l2_priority prio;
        struct ivtv *itv;
 };
@@ -549,6 +546,7 @@ struct yuv_frame_info
        u32 tru_w;
        u32 tru_h;
        u32 offset_y;
+       int lace_mode;
 };
 
 #define IVTV_YUV_MODE_INTERLACED       0x00
@@ -621,7 +619,6 @@ struct yuv_playback_info
        int decode_height;
 
        int frame_interlaced;
-       int frame_interlaced_last;
 
        int lace_mode;
        int lace_threshold;
@@ -632,6 +629,11 @@ struct yuv_playback_info
 
        u32 yuv_forced_update;
        int update_frame;
+
+       int sync_field[4];  /* Field to sync on */
+       int field_delay[4]; /* Flag to extend duration of previous frame */
+       u8 fields_lapsed;   /* Counter used when delaying a frame */
+
        struct yuv_frame_info new_frame_info[4];
        struct yuv_frame_info old_frame_info;
        struct yuv_frame_info old_frame_info_args;
@@ -648,7 +650,6 @@ struct vbi_info {
        u32 enc_start, enc_size;
        int fpi;
        u32 frame;
-       u32 dma_offset;
        u8 cc_data_odd[256];
        u8 cc_data_even[256];
        int cc_pos;
@@ -667,7 +668,6 @@ struct vbi_info {
        struct v4l2_format in;
        /* convenience pointer to sliced struct in vbi_in union */
        struct v4l2_sliced_vbi_format *sliced_in;
-       u32 service_set_in;
        int insert_mpeg;
 
        /* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
@@ -718,6 +718,7 @@ struct ivtv {
        u8 nof_audio_inputs;    /* number of audio inputs */
        u32 v4l2_cap;           /* V4L2 capabilities of card */
        u32 hw_flags;           /* Hardware description of the board */
+       int tunerid;            /* Userspace tuner ID for experimental Xceive tuner support */
 
        /* controlling Video decoder function */
        int (*video_dec_func)(struct ivtv *, unsigned int, void *);
@@ -735,6 +736,7 @@ struct ivtv {
        int cur_pio_stream;     /* index of stream doing PIO */
        u32 dma_data_req_offset;
        u32 dma_data_req_size;
+       int dma_retries;
        int output_mode;        /* NONE, MPG, YUV, UDMA YUV, passthrough */
        spinlock_t lock;        /* lock access to this struct */
        int search_pack_header;
@@ -858,6 +860,9 @@ int ivtv_waitq(wait_queue_head_t *waitq);
 struct tveeprom; /* forward reference */
 void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv);
 
+/* First-open initialization: load firmware, init cx25840, etc. */
+int ivtv_init_on_first_open(struct ivtv *itv);
+
 /* This is a PCI post thing, where if the pci register is not read, then
    the write doesn't always take effect right away. By reading back the
    register any pending PCI writes will be performed (in order), and so