#include <linux/unistd.h>
#include <linux/byteorder/swab.h>
#include <linux/pagemap.h>
+#include <linux/scatterlist.h>
#include <linux/workqueue.h>
#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <linux/dvb/video.h>
#include <linux/dvb/audio.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <media/tuner.h>
#include <media/cx2341x.h>
-#include <media/ivtv.h>
-
+#include <linux/ivtv.h>
/* Memory layout */
#define IVTV_ENCODER_OFFSET 0x00000000
#define IVTV_MAX_PGM_INDEX (400)
struct ivtv_options {
- 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 */
- int newi2c; /* New I2C algorithm */
+ 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 */
+ int newi2c; /* new I2C algorithm */
};
/* ivtv-specific mailbox template */
#define IVTV_F_I_DMA 0 /* DMA in progress */
#define IVTV_F_I_UDMA 1 /* UDMA in progress */
#define IVTV_F_I_UDMA_PENDING 2 /* UDMA pending */
-#define IVTV_F_I_SPEED_CHANGE 3 /* A speed change is in progress */
-#define IVTV_F_I_EOS 4 /* End of encoder stream reached */
-#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_SPEED_CHANGE 3 /* a speed change is in progress */
+#define IVTV_F_I_EOS 4 /* end of encoder stream reached */
+#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_UPDATE_CC 9 /* CC should be updated */
#define IVTV_F_I_UPDATE_WSS 10 /* WSS should be updated */
#define IVTV_F_I_DECODING_YUV 12 /* this stream is YUV frame decoding */
#define IVTV_F_I_ENC_PAUSED 13 /* the encoder is paused */
#define IVTV_F_I_VALID_DEC_TIMINGS 14 /* last_dec_timing is valid */
-#define IVTV_F_I_HAVE_WORK 15 /* Used in the interrupt handler: there is work to be done */
+#define IVTV_F_I_HAVE_WORK 15 /* used in the interrupt handler: there is work to be done */
#define IVTV_F_I_WORK_HANDLER_VBI 16 /* there is work to be done for VBI */
#define IVTV_F_I_WORK_HANDLER_YUV 17 /* there is work to be done for YUV */
#define IVTV_F_I_WORK_HANDLER_PIO 18 /* there is work to be done for PIO */
#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 */
+#define IVTV_F_I_WORK_INITED 23 /* worker thread was initialized */
/* Event notifications */
#define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */
/* Scatter-Gather array element, used in DMA transfers */
struct ivtv_sg_element {
+ __le32 src;
+ __le32 dst;
+ __le32 size;
+};
+
+struct ivtv_sg_host_element {
u32 src;
u32 dst;
u32 size;
unsigned short b_flags;
unsigned short dma_xfer_cnt;
char *buf;
-
u32 bytesused;
u32 readpos;
};
struct ivtv_queue {
- struct list_head list;
- u32 buffers;
- u32 length;
- u32 bytesused;
+ struct list_head list; /* the list of buffers in this queue */
+ u32 buffers; /* number of buffers in this queue */
+ u32 length; /* total number of bytes of available buffer space */
+ u32 bytesused; /* total number of bytes used in this queue */
};
-struct ivtv; /* forward reference */
+struct ivtv; /* forward reference */
struct ivtv_stream {
/* These first four fields are always set, even if the stream
int type; /* stream type */
u32 id;
- spinlock_t qlock; /* locks access to the queues */
- unsigned long s_flags; /* status flags, see above */
- int dma; /* can be PCI_DMA_TODEVICE,
- PCI_DMA_FROMDEVICE or
- PCI_DMA_NONE */
+ spinlock_t qlock; /* locks access to the queues */
+ unsigned long s_flags; /* status flags, see above */
+ int dma; /* can be PCI_DMA_TODEVICE, PCI_DMA_FROMDEVICE or PCI_DMA_NONE */
u32 pending_offset;
u32 pending_backup;
u64 pending_pts;
u16 dma_xfer_cnt;
/* Base Dev SG Array for cx23415/6 */
- struct ivtv_sg_element *sg_pending;
- struct ivtv_sg_element *sg_processing;
+ struct ivtv_sg_host_element *sg_pending;
+ struct ivtv_sg_host_element *sg_processing;
struct ivtv_sg_element *sg_dma;
dma_addr_t sg_handle;
int sg_pending_size;
};
struct ivtv_open_id {
- u32 open_id;
- int type;
- int yuv_frames;
- enum v4l2_priority prio;
+ u32 open_id; /* unique ID for this file descriptor */
+ int type; /* stream type */
+ int yuv_frames; /* 1: started OUT_UDMA_YUV output mode */
+ enum v4l2_priority prio; /* priority */
struct ivtv *itv;
};
u32 tru_h;
u32 offset_y;
s32 lace_mode;
+ u32 sync_field;
+ u32 delay;
+ u32 interlaced;
};
#define IVTV_YUV_MODE_INTERLACED 0x00
#define IVTV_YUV_SYNC_ODD 0x04
#define IVTV_YUV_SYNC_MASK 0x04
+#define IVTV_YUV_BUFFERS 8
+
struct yuv_playback_info
{
u32 reg_2834;
int v_filter_2;
int h_filter;
+ u8 track_osd; /* Should yuv output track the OSD size & position */
+
u32 osd_x_offset;
u32 osd_y_offset;
u32 osd_vis_w;
u32 osd_vis_h;
- int decode_height;
+ u32 osd_full_w;
+ u32 osd_full_h;
- int frame_interlaced;
+ int decode_height;
int lace_mode;
int lace_threshold;
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 new_frame_info[IVTV_YUV_BUFFERS];
struct yuv_frame_info old_frame_info;
struct yuv_frame_info old_frame_info_args;
void *blanking_ptr;
dma_addr_t blanking_dmaptr;
+
+ int stream_size;
+
+ u8 draw_frame; /* PVR350 buffer to draw into */
+ u8 max_frames_buffered; /* Maximum number of frames to buffer */
+
+ struct v4l2_rect main_rect;
+ u32 v4l2_src_w;
+ u32 v4l2_src_h;
};
#define IVTV_VBI_FRAMES 32
/* VBI data */
+struct vbi_cc {
+ u8 odd[2]; /* two-byte payload of odd field */
+ u8 even[2]; /* two-byte payload of even field */;
+};
+
+struct vbi_vps {
+ u8 data[5]; /* five-byte VPS payload */
+};
+
struct vbi_info {
- u32 dec_start;
- u32 enc_start, enc_size;
- int fpi;
- u32 frame;
- u8 cc_data_odd[256];
- u8 cc_data_even[256];
- int cc_pos;
- u8 cc_no_update;
- u8 vps[5];
- u8 vps_found;
- int wss;
- u8 wss_found;
- u8 wss_no_update;
- u32 raw_decoder_line_size;
- u8 raw_decoder_sav_odd_field;
- u8 raw_decoder_sav_even_field;
- u32 sliced_decoder_line_size;
- u8 sliced_decoder_sav_odd_field;
- u8 sliced_decoder_sav_even_field;
- struct v4l2_format in;
- /* convenience pointer to sliced struct in vbi_in union */
- struct v4l2_sliced_vbi_format *sliced_in;
- int insert_mpeg;
-
- /* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
- One for /dev/vbi0 and one for /dev/vbi8 */
- struct v4l2_sliced_vbi_data sliced_data[36];
- struct v4l2_sliced_vbi_data sliced_dec_data[36];
+ /* VBI general data, does not change during streaming */
+
+ u32 raw_decoder_line_size; /* raw VBI line size from digitizer */
+ u8 raw_decoder_sav_odd_field; /* raw VBI Start Active Video digitizer code of odd field */
+ u8 raw_decoder_sav_even_field; /* raw VBI Start Active Video digitizer code of even field */
+ u32 sliced_decoder_line_size; /* sliced VBI line size from digitizer */
+ u8 sliced_decoder_sav_odd_field; /* sliced VBI Start Active Video digitizer code of odd field */
+ u8 sliced_decoder_sav_even_field; /* sliced VBI Start Active Video digitizer code of even field */
+
+ u32 start[2]; /* start of first VBI line in the odd/even fields */
+ u32 count; /* number of VBI lines per field */
+ u32 raw_size; /* size of raw VBI line from the digitizer */
+ u32 sliced_size; /* size of sliced VBI line from the digitizer */
+
+ u32 dec_start; /* start in decoder memory of VBI re-insertion buffers */
+ u32 enc_start; /* start in encoder memory of VBI capture buffers */
+ u32 enc_size; /* size of VBI capture area */
+ int fpi; /* number of VBI frames per interrupt */
+
+ struct v4l2_format in; /* current VBI capture format */
+ struct v4l2_sliced_vbi_format *sliced_in; /* convenience pointer to sliced struct in vbi.in union */
+ int insert_mpeg; /* if non-zero, then embed VBI data in MPEG stream */
+
+ /* Raw VBI compatibility hack */
+
+ u32 frame; /* frame counter hack needed for backwards compatibility
+ of old VBI software */
+
+ /* Sliced VBI output data */
+
+ struct vbi_cc cc_payload[256]; /* sliced VBI CC payload array: it is an array to
+ prevent dropping CC data if they couldn't be
+ processed fast enough */
+ int cc_payload_idx; /* index in cc_payload */
+ u8 cc_missing_cnt; /* counts number of frames without CC for passthrough mode */
+ int wss_payload; /* sliced VBI WSS payload */
+ u8 wss_missing_cnt; /* counts number of frames without WSS for passthrough mode */
+ struct vbi_vps vps_payload; /* sliced VBI VPS payload */
+
+ /* Sliced VBI capture data */
+
+ struct v4l2_sliced_vbi_data sliced_data[36]; /* sliced VBI storage for VBI encoder stream */
+ struct v4l2_sliced_vbi_data sliced_dec_data[36];/* sliced VBI storage for VBI decoder stream */
+
+ /* VBI Embedding data */
/* Buffer for VBI data inserted into MPEG stream.
The first byte is a dummy byte that's never used.
This pointer array will allocate 2049 bytes to store each VBI frame. */
u8 *sliced_mpeg_data[IVTV_VBI_FRAMES];
u32 sliced_mpeg_size[IVTV_VBI_FRAMES];
- struct ivtv_buffer sliced_mpeg_buf;
- u32 inserted_frame;
-
- u32 start[2], count;
- u32 raw_size;
- u32 sliced_size;
+ struct ivtv_buffer sliced_mpeg_buf; /* temporary buffer holding data from sliced_mpeg_data */
+ u32 inserted_frame; /* index in sliced_mpeg_size of next sliced data
+ to be inserted in the MPEG stream */
};
/* forward declaration of struct defined in ivtv-cards.h */
/* Struct to hold info about ivtv cards */
struct ivtv {
- int num; /* board number, -1 during init! */
- char name[8]; /* board name for printk and interrupts (e.g. 'ivtv0') */
- struct pci_dev *dev; /* PCI device */
+ /* General fixed card data */
+ int num; /* board number, -1 during init! */
+ char name[8]; /* board name for printk and interrupts (e.g. 'ivtv0') */
+ struct pci_dev *dev; /* PCI device */
const struct ivtv_card *card; /* card information */
- const char *card_name; /* full name of the card */
- u8 has_cx23415; /* 1 if it is a cx23415 based card, 0 for cx23416 */
- u8 is_50hz;
- u8 is_60hz;
- u8 is_out_50hz;
- u8 is_out_60hz;
- u8 pvr150_workaround; /* 1 if the cx25840 needs to workaround a PVR150 bug */
- u8 nof_inputs; /* number of video inputs */
- 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 */
+ const char *card_name; /* full name of the card */
+ const struct ivtv_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
+ u8 has_cx23415; /* 1 if it is a cx23415 based card, 0 for cx23416 */
+ u8 pvr150_workaround; /* 1 if the cx25840 needs to workaround a PVR150 bug */
+ u8 nof_inputs; /* number of video inputs */
+ u8 nof_audio_inputs; /* number of audio inputs */
+ u32 v4l2_cap; /* V4L2 capabilities of card */
+ u32 hw_flags; /* hardware description of the board */
+ v4l2_std_id tuner_std; /* the norm of the card's tuner (fixed) */
+ /* controlling video decoder function */
int (*video_dec_func)(struct ivtv *, unsigned int, void *);
+ u32 base_addr; /* PCI resource base address */
+ volatile void __iomem *enc_mem; /* pointer to mapped encoder memory */
+ volatile void __iomem *dec_mem; /* pointer to mapped decoder memory */
+ volatile void __iomem *reg_mem; /* pointer to mapped registers */
+ struct ivtv_options options; /* user options */
+
+
+ /* High-level state info */
+ unsigned long i_flags; /* global ivtv flags */
+ u8 is_50hz; /* 1 if the current capture standard is 50 Hz */
+ u8 is_60hz /* 1 if the current capture standard is 60 Hz */;
+ u8 is_out_50hz /* 1 if the current TV output standard is 50 Hz */;
+ u8 is_out_60hz /* 1 if the current TV output standard is 60 Hz */;
+ int output_mode; /* decoder output mode: NONE, MPG, YUV, UDMA YUV, passthrough */
+ u32 audio_input; /* current audio input */
+ u32 active_input; /* current video input */
+ u32 active_output; /* current video output */
+ v4l2_std_id std; /* current capture TV standard */
+ v4l2_std_id std_out; /* current TV output standard */
+ u8 audio_stereo_mode; /* decoder setting how to handle stereo MPEG audio */
+ u8 audio_bilingual_mode; /* decoder setting how to handle bilingual MPEG audio */
+ struct cx2341x_mpeg_params params; /* current encoder parameters */
+
+
+ /* Locking */
+ spinlock_t lock; /* lock access to this struct */
+ struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */
+
+ /* Streams */
+ int stream_buf_size[IVTV_MAX_STREAMS]; /* stream buffer size */
+ struct ivtv_stream streams[IVTV_MAX_STREAMS]; /* stream data */
+ atomic_t capturing; /* count number of active capture streams */
+ atomic_t decoding; /* count number of active decoding streams */
+
+
+ /* Interrupts & DMA */
+ u32 irqmask; /* active interrupts */
+ u32 irq_rr_idx; /* round-robin stream index */
+ struct workqueue_struct *irq_work_queues; /* workqueue for PIO/YUV/VBI actions */
+ struct work_struct irq_work_queue; /* work entry */
+ spinlock_t dma_reg_lock; /* lock access to DMA engine registers */
+ int cur_dma_stream; /* index of current stream doing DMA (-1 if none) */
+ int cur_pio_stream; /* index of current stream doing PIO (-1 if none) */
+ u32 dma_data_req_offset; /* store offset in decoder memory of current DMA request */
+ u32 dma_data_req_size; /* store size of current DMA request */
+ int dma_retries; /* current DMA retry attempt */
+ struct ivtv_user_dma udma; /* user based DMA for OSD */
+ struct timer_list dma_timer; /* timer used to catch unfinished DMAs */
+ u32 last_vsync_field; /* last seen vsync field */
+ wait_queue_head_t dma_waitq; /* wake up when the current DMA is finished */
+ wait_queue_head_t eos_waitq; /* wake up when EOS arrives */
+ wait_queue_head_t event_waitq; /* wake up when the next decoder event arrives */
+ wait_queue_head_t vsync_waitq; /* wake up when the next decoder vsync arrives */
+
+
+ /* Mailbox */
+ struct ivtv_mailbox_data enc_mbox; /* encoder mailboxes */
+ struct ivtv_mailbox_data dec_mbox; /* decoder mailboxes */
+ struct ivtv_api_cache api_cache[256]; /* cached API commands */
+
+
+ /* I2C */
+ struct i2c_adapter i2c_adap;
+ struct i2c_algo_bit_data i2c_algo;
+ struct i2c_client i2c_client;
+ struct i2c_client *i2c_clients[I2C_CLIENTS_MAX];/* pointers to all I2C clients */
+ int i2c_state; /* i2c bit state */
+ struct mutex i2c_bus_lock; /* lock i2c bus */
+
+
+ /* Program Index information */
+ u32 pgm_info_offset; /* start of pgm info in encoder memory */
+ u32 pgm_info_num; /* number of elements in the pgm cyclic buffer in encoder memory */
+ u32 pgm_info_write_idx; /* last index written by the card that was transferred to pgm_info[] */
+ u32 pgm_info_read_idx; /* last index in pgm_info read by the application */
+ struct v4l2_enc_idx_entry pgm_info[IVTV_MAX_PGM_INDEX]; /* filled from the pgm cyclic buffer on the card */
+
+
+ /* Miscellaneous */
+ u32 open_id; /* incremented each time an open occurs, is >= 1 */
+ struct v4l2_prio_state prio; /* priority state */
+ int search_pack_header; /* 1 if ivtv_copy_buf_to_user() is scanning for a pack header (0xba) */
+ int speed; /* current playback speed setting */
+ u8 speed_mute_audio; /* 1 if audio should be muted when fast forward */
+ u64 mpg_data_received; /* number of bytes received from the MPEG stream */
+ u64 vbi_data_inserted; /* number of VBI bytes inserted into the MPEG stream */
+ u32 last_dec_timing[3]; /* cache last retrieved pts/scr/frame values */
+ unsigned long dualwatch_jiffies;/* jiffies value of the previous dualwatch check */
+ u16 dualwatch_stereo_mode; /* current detected dualwatch stereo mode */
+
+
+ /* VBI state info */
+ struct vbi_info vbi; /* VBI-specific data */
+
+
+ /* YUV playback */
+ struct yuv_playback_info yuv_info; /* YUV playback data */
- struct ivtv_options options; /* User options */
- int stream_buf_size[IVTV_MAX_STREAMS]; /* Stream buffer size */
- struct ivtv_stream streams[IVTV_MAX_STREAMS]; /* Stream data */
- int speed;
- u8 speed_mute_audio;
- unsigned long i_flags; /* global ivtv flags */
- atomic_t capturing; /* count number of active capture streams */
- atomic_t decoding; /* count number of active decoding streams */
- u32 irq_rr_idx; /* Round-robin stream index */
- int cur_dma_stream; /* index of stream doing DMA */
- 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;
-
- spinlock_t dma_reg_lock; /* lock access to DMA engine registers */
- struct mutex serialize_lock; /* lock used to serialize starting streams */
-
- /* User based DMA for OSD */
- struct ivtv_user_dma udma;
-
- int open_id; /* incremented each time an open occurs, used as unique ID.
- starts at 1, so 0 can be used as uninitialized value
- in the stream->id. */
-
- u32 base_addr;
- u32 irqmask;
-
- struct v4l2_prio_state prio;
- struct workqueue_struct *irq_work_queues;
- struct work_struct irq_work_queue;
- struct timer_list dma_timer; /* Timer used to catch unfinished DMAs */
-
- struct vbi_info vbi;
-
- struct ivtv_mailbox_data enc_mbox;
- struct ivtv_mailbox_data dec_mbox;
- struct ivtv_api_cache api_cache[256]; /* Cached API Commands */
-
- u8 card_rev;
- volatile void __iomem *enc_mem, *dec_mem, *reg_mem;
-
- u32 pgm_info_offset;
- u32 pgm_info_num;
- u32 pgm_info_write_idx;
- u32 pgm_info_read_idx;
- struct v4l2_enc_idx_entry pgm_info[IVTV_MAX_PGM_INDEX];
-
- u64 mpg_data_received;
- u64 vbi_data_inserted;
-
- wait_queue_head_t cap_w;
- /* when the next decoder event arrives this queue is woken up */
- wait_queue_head_t event_waitq;
- /* when the next decoder vsync arrives this queue is woken up */
- wait_queue_head_t vsync_waitq;
- /* when the current DMA is finished this queue is woken up */
- wait_queue_head_t dma_waitq;
/* OSD support */
unsigned long osd_video_pbase;
- int osd_global_alpha_state; /* 0=off : 1=on */
- int osd_local_alpha_state; /* 0=off : 1=on */
- int osd_color_key_state; /* 0=off : 1=on */
- u8 osd_global_alpha; /* Current global alpha */
- u32 osd_color_key; /* Current color key */
- u32 osd_pixelformat; /* Current pixel format */
- struct v4l2_rect osd_rect; /* Current OSD position and size */
- struct v4l2_rect main_rect; /* Current Main window position and size */
-
- u32 last_dec_timing[3]; /* Store last retrieved pts/scr/frame values */
-
- /* i2c */
- struct i2c_adapter i2c_adap;
- struct i2c_algo_bit_data i2c_algo;
- struct i2c_client i2c_client;
- struct mutex i2c_bus_lock;
- int i2c_state;
- struct i2c_client *i2c_clients[I2C_CLIENTS_MAX];
-
- /* v4l2 and User settings */
-
- /* codec settings */
- struct cx2341x_mpeg_params params;
- u32 audio_input;
- u32 active_input;
- u32 active_output;
- v4l2_std_id std;
- v4l2_std_id std_out;
- v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */
- u8 audio_stereo_mode;
- u8 audio_bilingual_mode;
-
- /* dualwatch */
- unsigned long dualwatch_jiffies;
- u16 dualwatch_stereo_mode;
-
- /* Digitizer type */
- int digitizer; /* 0x00EF = saa7114 0x00FO = saa7115 0x0106 = mic */
-
- u32 lastVsyncFrame;
-
- struct yuv_playback_info yuv_info;
- struct osd_info *osd_info;
+ int osd_global_alpha_state; /* 1 = global alpha is on */
+ int osd_local_alpha_state; /* 1 = local alpha is on */
+ int osd_chroma_key_state; /* 1 = chroma-keying is on */
+ u8 osd_global_alpha; /* current global alpha */
+ u32 osd_chroma_key; /* current chroma key */
+ struct v4l2_rect osd_rect; /* current OSD position and size */
+ struct v4l2_rect main_rect; /* current Main window position and size */
+ struct osd_info *osd_info; /* ivtvfb private OSD info */
};
/* Globals */