162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci ivtv driver internal defines and structures 362306a36Sopenharmony_ci Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> 462306a36Sopenharmony_ci Copyright (C) 2004 Chris Kennedy <c@groovy.org> 562306a36Sopenharmony_ci Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci This program is free software; you can redistribute it and/or modify 862306a36Sopenharmony_ci it under the terms of the GNU General Public License as published by 962306a36Sopenharmony_ci the Free Software Foundation; either version 2 of the License, or 1062306a36Sopenharmony_ci (at your option) any later version. 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci This program is distributed in the hope that it will be useful, 1362306a36Sopenharmony_ci but WITHOUT ANY WARRANTY; without even the implied warranty of 1462306a36Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1562306a36Sopenharmony_ci GNU General Public License for more details. 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci You should have received a copy of the GNU General Public License 1862306a36Sopenharmony_ci along with this program; if not, write to the Free Software 1962306a36Sopenharmony_ci Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 2062306a36Sopenharmony_ci */ 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#ifndef IVTV_DRIVER_H 2362306a36Sopenharmony_ci#define IVTV_DRIVER_H 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci/* Internal header for ivtv project: 2862306a36Sopenharmony_ci * Driver for the cx23415/6 chip. 2962306a36Sopenharmony_ci * Author: Kevin Thayer (nufan_wfk at yahoo.com) 3062306a36Sopenharmony_ci * License: GPL 3162306a36Sopenharmony_ci * 3262306a36Sopenharmony_ci * ----- 3362306a36Sopenharmony_ci * MPG600/MPG160 support by T.Adachi <tadachi@tadachi-net.com> 3462306a36Sopenharmony_ci * and Takeru KOMORIYA<komoriya@paken.org> 3562306a36Sopenharmony_ci * 3662306a36Sopenharmony_ci * AVerMedia M179 GPIO info by Chris Pinkham <cpinkham@bc2va.org> 3762306a36Sopenharmony_ci * using information provided by Jiun-Kuei Jung @ AVerMedia. 3862306a36Sopenharmony_ci */ 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci#include <linux/module.h> 4162306a36Sopenharmony_ci#include <linux/init.h> 4262306a36Sopenharmony_ci#include <linux/delay.h> 4362306a36Sopenharmony_ci#include <linux/sched/signal.h> 4462306a36Sopenharmony_ci#include <linux/fs.h> 4562306a36Sopenharmony_ci#include <linux/pci.h> 4662306a36Sopenharmony_ci#include <linux/interrupt.h> 4762306a36Sopenharmony_ci#include <linux/spinlock.h> 4862306a36Sopenharmony_ci#include <linux/i2c.h> 4962306a36Sopenharmony_ci#include <linux/i2c-algo-bit.h> 5062306a36Sopenharmony_ci#include <linux/list.h> 5162306a36Sopenharmony_ci#include <linux/unistd.h> 5262306a36Sopenharmony_ci#include <linux/pagemap.h> 5362306a36Sopenharmony_ci#include <linux/scatterlist.h> 5462306a36Sopenharmony_ci#include <linux/kthread.h> 5562306a36Sopenharmony_ci#include <linux/mutex.h> 5662306a36Sopenharmony_ci#include <linux/slab.h> 5762306a36Sopenharmony_ci#include <linux/uaccess.h> 5862306a36Sopenharmony_ci#include <asm/byteorder.h> 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci#include <media/v4l2-common.h> 6162306a36Sopenharmony_ci#include <media/v4l2-ioctl.h> 6262306a36Sopenharmony_ci#include <media/v4l2-ctrls.h> 6362306a36Sopenharmony_ci#include <media/v4l2-device.h> 6462306a36Sopenharmony_ci#include <media/v4l2-fh.h> 6562306a36Sopenharmony_ci#include <media/tuner.h> 6662306a36Sopenharmony_ci#include <media/drv-intf/cx2341x.h> 6762306a36Sopenharmony_ci#include <media/i2c/ir-kbd-i2c.h> 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci#include <linux/ivtv.h> 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci/* Memory layout */ 7262306a36Sopenharmony_ci#define IVTV_ENCODER_OFFSET 0x00000000 7362306a36Sopenharmony_ci#define IVTV_ENCODER_SIZE 0x00800000 /* Total size is 0x01000000, but only first half is used */ 7462306a36Sopenharmony_ci#define IVTV_DECODER_OFFSET 0x01000000 7562306a36Sopenharmony_ci#define IVTV_DECODER_SIZE 0x00800000 /* Total size is 0x01000000, but only first half is used */ 7662306a36Sopenharmony_ci#define IVTV_REG_OFFSET 0x02000000 7762306a36Sopenharmony_ci#define IVTV_REG_SIZE 0x00010000 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci/* Maximum ivtv driver instances. Some people have a huge number of 8062306a36Sopenharmony_ci capture cards, so set this to a high value. */ 8162306a36Sopenharmony_ci#define IVTV_MAX_CARDS 32 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci#define IVTV_ENC_STREAM_TYPE_MPG 0 8462306a36Sopenharmony_ci#define IVTV_ENC_STREAM_TYPE_YUV 1 8562306a36Sopenharmony_ci#define IVTV_ENC_STREAM_TYPE_VBI 2 8662306a36Sopenharmony_ci#define IVTV_ENC_STREAM_TYPE_PCM 3 8762306a36Sopenharmony_ci#define IVTV_ENC_STREAM_TYPE_RAD 4 8862306a36Sopenharmony_ci#define IVTV_DEC_STREAM_TYPE_MPG 5 8962306a36Sopenharmony_ci#define IVTV_DEC_STREAM_TYPE_VBI 6 9062306a36Sopenharmony_ci#define IVTV_DEC_STREAM_TYPE_VOUT 7 9162306a36Sopenharmony_ci#define IVTV_DEC_STREAM_TYPE_YUV 8 9262306a36Sopenharmony_ci#define IVTV_MAX_STREAMS 9 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci#define IVTV_DMA_SG_OSD_ENT (2883584/PAGE_SIZE) /* sg entities */ 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci/* DMA Registers */ 9762306a36Sopenharmony_ci#define IVTV_REG_DMAXFER (0x0000) 9862306a36Sopenharmony_ci#define IVTV_REG_DMASTATUS (0x0004) 9962306a36Sopenharmony_ci#define IVTV_REG_DECDMAADDR (0x0008) 10062306a36Sopenharmony_ci#define IVTV_REG_ENCDMAADDR (0x000c) 10162306a36Sopenharmony_ci#define IVTV_REG_DMACONTROL (0x0010) 10262306a36Sopenharmony_ci#define IVTV_REG_IRQSTATUS (0x0040) 10362306a36Sopenharmony_ci#define IVTV_REG_IRQMASK (0x0048) 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci/* Setup Registers */ 10662306a36Sopenharmony_ci#define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8) 10762306a36Sopenharmony_ci#define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC) 10862306a36Sopenharmony_ci#define IVTV_REG_DEC_SDRAM_REFRESH (0x08F8) 10962306a36Sopenharmony_ci#define IVTV_REG_DEC_SDRAM_PRECHARGE (0x08FC) 11062306a36Sopenharmony_ci#define IVTV_REG_VDM (0x2800) 11162306a36Sopenharmony_ci#define IVTV_REG_AO (0x2D00) 11262306a36Sopenharmony_ci#define IVTV_REG_BYTEFLUSH (0x2D24) 11362306a36Sopenharmony_ci#define IVTV_REG_SPU (0x9050) 11462306a36Sopenharmony_ci#define IVTV_REG_HW_BLOCKS (0x9054) 11562306a36Sopenharmony_ci#define IVTV_REG_VPU (0x9058) 11662306a36Sopenharmony_ci#define IVTV_REG_APU (0xA064) 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci/* Other registers */ 11962306a36Sopenharmony_ci#define IVTV_REG_DEC_LINE_FIELD (0x28C0) 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci/* debugging */ 12262306a36Sopenharmony_ciextern int ivtv_debug; 12362306a36Sopenharmony_ci#ifdef CONFIG_VIDEO_ADV_DEBUG 12462306a36Sopenharmony_ciextern int ivtv_fw_debug; 12562306a36Sopenharmony_ci#endif 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci#define IVTV_DBGFLG_WARN (1 << 0) 12862306a36Sopenharmony_ci#define IVTV_DBGFLG_INFO (1 << 1) 12962306a36Sopenharmony_ci#define IVTV_DBGFLG_MB (1 << 2) 13062306a36Sopenharmony_ci#define IVTV_DBGFLG_IOCTL (1 << 3) 13162306a36Sopenharmony_ci#define IVTV_DBGFLG_FILE (1 << 4) 13262306a36Sopenharmony_ci#define IVTV_DBGFLG_DMA (1 << 5) 13362306a36Sopenharmony_ci#define IVTV_DBGFLG_IRQ (1 << 6) 13462306a36Sopenharmony_ci#define IVTV_DBGFLG_DEC (1 << 7) 13562306a36Sopenharmony_ci#define IVTV_DBGFLG_YUV (1 << 8) 13662306a36Sopenharmony_ci#define IVTV_DBGFLG_I2C (1 << 9) 13762306a36Sopenharmony_ci/* Flag to turn on high volume debugging */ 13862306a36Sopenharmony_ci#define IVTV_DBGFLG_HIGHVOL (1 << 10) 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci#define IVTV_DEBUG(x, type, fmt, args...) \ 14162306a36Sopenharmony_ci do { \ 14262306a36Sopenharmony_ci if ((x) & ivtv_debug) \ 14362306a36Sopenharmony_ci v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args); \ 14462306a36Sopenharmony_ci } while (0) 14562306a36Sopenharmony_ci#define IVTV_DEBUG_WARN(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_WARN, "warn", fmt , ## args) 14662306a36Sopenharmony_ci#define IVTV_DEBUG_INFO(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_INFO, "info", fmt , ## args) 14762306a36Sopenharmony_ci#define IVTV_DEBUG_MB(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_MB, "mb", fmt , ## args) 14862306a36Sopenharmony_ci#define IVTV_DEBUG_DMA(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_DMA, "dma", fmt , ## args) 14962306a36Sopenharmony_ci#define IVTV_DEBUG_IOCTL(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_IOCTL, "ioctl", fmt , ## args) 15062306a36Sopenharmony_ci#define IVTV_DEBUG_FILE(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_FILE, "file", fmt , ## args) 15162306a36Sopenharmony_ci#define IVTV_DEBUG_I2C(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_I2C, "i2c", fmt , ## args) 15262306a36Sopenharmony_ci#define IVTV_DEBUG_IRQ(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_IRQ, "irq", fmt , ## args) 15362306a36Sopenharmony_ci#define IVTV_DEBUG_DEC(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_DEC, "dec", fmt , ## args) 15462306a36Sopenharmony_ci#define IVTV_DEBUG_YUV(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_YUV, "yuv", fmt , ## args) 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci#define IVTV_DEBUG_HIGH_VOL(x, type, fmt, args...) \ 15762306a36Sopenharmony_ci do { \ 15862306a36Sopenharmony_ci if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) \ 15962306a36Sopenharmony_ci v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args); \ 16062306a36Sopenharmony_ci } while (0) 16162306a36Sopenharmony_ci#define IVTV_DEBUG_HI_WARN(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN, "warn", fmt , ## args) 16262306a36Sopenharmony_ci#define IVTV_DEBUG_HI_INFO(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_INFO, "info", fmt , ## args) 16362306a36Sopenharmony_ci#define IVTV_DEBUG_HI_MB(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_MB, "mb", fmt , ## args) 16462306a36Sopenharmony_ci#define IVTV_DEBUG_HI_DMA(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DMA, "dma", fmt , ## args) 16562306a36Sopenharmony_ci#define IVTV_DEBUG_HI_IOCTL(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_IOCTL, "ioctl", fmt , ## args) 16662306a36Sopenharmony_ci#define IVTV_DEBUG_HI_FILE(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_FILE, "file", fmt , ## args) 16762306a36Sopenharmony_ci#define IVTV_DEBUG_HI_I2C(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_I2C, "i2c", fmt , ## args) 16862306a36Sopenharmony_ci#define IVTV_DEBUG_HI_IRQ(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_IRQ, "irq", fmt , ## args) 16962306a36Sopenharmony_ci#define IVTV_DEBUG_HI_DEC(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DEC, "dec", fmt , ## args) 17062306a36Sopenharmony_ci#define IVTV_DEBUG_HI_YUV(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_YUV, "yuv", fmt , ## args) 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci/* Standard kernel messages */ 17362306a36Sopenharmony_ci#define IVTV_ERR(fmt, args...) v4l2_err(&itv->v4l2_dev, fmt , ## args) 17462306a36Sopenharmony_ci#define IVTV_WARN(fmt, args...) v4l2_warn(&itv->v4l2_dev, fmt , ## args) 17562306a36Sopenharmony_ci#define IVTV_INFO(fmt, args...) v4l2_info(&itv->v4l2_dev, fmt , ## args) 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci/* output modes (cx23415 only) */ 17862306a36Sopenharmony_ci#define OUT_NONE 0 17962306a36Sopenharmony_ci#define OUT_MPG 1 18062306a36Sopenharmony_ci#define OUT_YUV 2 18162306a36Sopenharmony_ci#define OUT_UDMA_YUV 3 18262306a36Sopenharmony_ci#define OUT_PASSTHROUGH 4 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci#define IVTV_MAX_PGM_INDEX (400) 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci/* Default I2C SCL period in microseconds */ 18762306a36Sopenharmony_ci#define IVTV_DEFAULT_I2C_CLOCK_PERIOD 20 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_cistruct ivtv_options { 19062306a36Sopenharmony_ci int kilobytes[IVTV_MAX_STREAMS]; /* size in kilobytes of each stream */ 19162306a36Sopenharmony_ci int cardtype; /* force card type on load */ 19262306a36Sopenharmony_ci int tuner; /* set tuner on load */ 19362306a36Sopenharmony_ci int radio; /* enable/disable radio */ 19462306a36Sopenharmony_ci int newi2c; /* new I2C algorithm */ 19562306a36Sopenharmony_ci int i2c_clock_period; /* period of SCL for I2C bus */ 19662306a36Sopenharmony_ci}; 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci/* ivtv-specific mailbox template */ 19962306a36Sopenharmony_cistruct ivtv_mailbox { 20062306a36Sopenharmony_ci u32 flags; 20162306a36Sopenharmony_ci u32 cmd; 20262306a36Sopenharmony_ci u32 retval; 20362306a36Sopenharmony_ci u32 timeout; 20462306a36Sopenharmony_ci u32 data[CX2341X_MBOX_MAX_DATA]; 20562306a36Sopenharmony_ci}; 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_cistruct ivtv_api_cache { 20862306a36Sopenharmony_ci unsigned long last_jiffies; /* when last command was issued */ 20962306a36Sopenharmony_ci u32 data[CX2341X_MBOX_MAX_DATA]; /* last sent api data */ 21062306a36Sopenharmony_ci}; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_cistruct ivtv_mailbox_data { 21362306a36Sopenharmony_ci volatile struct ivtv_mailbox __iomem *mbox; 21462306a36Sopenharmony_ci /* Bits 0-2 are for the encoder mailboxes, 0-1 are for the decoder mailboxes. 21562306a36Sopenharmony_ci If the bit is set, then the corresponding mailbox is in use by the driver. */ 21662306a36Sopenharmony_ci unsigned long busy; 21762306a36Sopenharmony_ci u8 max_mbox; 21862306a36Sopenharmony_ci}; 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci/* per-buffer bit flags */ 22162306a36Sopenharmony_ci#define IVTV_F_B_NEED_BUF_SWAP (1 << 0) /* this buffer should be byte swapped */ 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci/* per-stream, s_flags */ 22462306a36Sopenharmony_ci#define IVTV_F_S_DMA_PENDING 0 /* this stream has pending DMA */ 22562306a36Sopenharmony_ci#define IVTV_F_S_DMA_HAS_VBI 1 /* the current DMA request also requests VBI data */ 22662306a36Sopenharmony_ci#define IVTV_F_S_NEEDS_DATA 2 /* this decoding stream needs more data */ 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci#define IVTV_F_S_CLAIMED 3 /* this stream is claimed */ 22962306a36Sopenharmony_ci#define IVTV_F_S_STREAMING 4 /* the fw is decoding/encoding this stream */ 23062306a36Sopenharmony_ci#define IVTV_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */ 23162306a36Sopenharmony_ci#define IVTV_F_S_PASSTHROUGH 6 /* this stream is in passthrough mode */ 23262306a36Sopenharmony_ci#define IVTV_F_S_STREAMOFF 7 /* signal end of stream EOS */ 23362306a36Sopenharmony_ci#define IVTV_F_S_APPL_IO 8 /* this stream is used read/written by an application */ 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci#define IVTV_F_S_PIO_PENDING 9 /* this stream has pending PIO */ 23662306a36Sopenharmony_ci#define IVTV_F_S_PIO_HAS_VBI 1 /* the current PIO request also requests VBI data */ 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci/* per-ivtv, i_flags */ 23962306a36Sopenharmony_ci#define IVTV_F_I_DMA 0 /* DMA in progress */ 24062306a36Sopenharmony_ci#define IVTV_F_I_UDMA 1 /* UDMA in progress */ 24162306a36Sopenharmony_ci#define IVTV_F_I_UDMA_PENDING 2 /* UDMA pending */ 24262306a36Sopenharmony_ci#define IVTV_F_I_SPEED_CHANGE 3 /* a speed change is in progress */ 24362306a36Sopenharmony_ci#define IVTV_F_I_EOS 4 /* end of encoder stream reached */ 24462306a36Sopenharmony_ci#define IVTV_F_I_RADIO_USER 5 /* the radio tuner is selected */ 24562306a36Sopenharmony_ci#define IVTV_F_I_DIG_RST 6 /* reset digitizer */ 24662306a36Sopenharmony_ci#define IVTV_F_I_DEC_YUV 7 /* YUV instead of MPG is being decoded */ 24762306a36Sopenharmony_ci#define IVTV_F_I_UPDATE_CC 9 /* CC should be updated */ 24862306a36Sopenharmony_ci#define IVTV_F_I_UPDATE_WSS 10 /* WSS should be updated */ 24962306a36Sopenharmony_ci#define IVTV_F_I_UPDATE_VPS 11 /* VPS should be updated */ 25062306a36Sopenharmony_ci#define IVTV_F_I_DECODING_YUV 12 /* this stream is YUV frame decoding */ 25162306a36Sopenharmony_ci#define IVTV_F_I_ENC_PAUSED 13 /* the encoder is paused */ 25262306a36Sopenharmony_ci#define IVTV_F_I_VALID_DEC_TIMINGS 14 /* last_dec_timing is valid */ 25362306a36Sopenharmony_ci#define IVTV_F_I_HAVE_WORK 15 /* used in the interrupt handler: there is work to be done */ 25462306a36Sopenharmony_ci#define IVTV_F_I_WORK_HANDLER_VBI 16 /* there is work to be done for VBI */ 25562306a36Sopenharmony_ci#define IVTV_F_I_WORK_HANDLER_YUV 17 /* there is work to be done for YUV */ 25662306a36Sopenharmony_ci#define IVTV_F_I_WORK_HANDLER_PIO 18 /* there is work to be done for PIO */ 25762306a36Sopenharmony_ci#define IVTV_F_I_PIO 19 /* PIO in progress */ 25862306a36Sopenharmony_ci#define IVTV_F_I_DEC_PAUSED 20 /* the decoder is paused */ 25962306a36Sopenharmony_ci#define IVTV_F_I_INITED 21 /* set after first open */ 26062306a36Sopenharmony_ci#define IVTV_F_I_FAILED 22 /* set if first open failed */ 26162306a36Sopenharmony_ci#define IVTV_F_I_WORK_HANDLER_PCM 23 /* there is work to be done for PCM */ 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci/* Event notifications */ 26462306a36Sopenharmony_ci#define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */ 26562306a36Sopenharmony_ci#define IVTV_F_I_EV_VSYNC 29 /* VSYNC event */ 26662306a36Sopenharmony_ci#define IVTV_F_I_EV_VSYNC_FIELD 30 /* VSYNC event field (0 = first, 1 = second field) */ 26762306a36Sopenharmony_ci#define IVTV_F_I_EV_VSYNC_ENABLED 31 /* VSYNC event enabled */ 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci/* Scatter-Gather array element, used in DMA transfers */ 27062306a36Sopenharmony_cistruct ivtv_sg_element { 27162306a36Sopenharmony_ci __le32 src; 27262306a36Sopenharmony_ci __le32 dst; 27362306a36Sopenharmony_ci __le32 size; 27462306a36Sopenharmony_ci}; 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_cistruct ivtv_sg_host_element { 27762306a36Sopenharmony_ci u32 src; 27862306a36Sopenharmony_ci u32 dst; 27962306a36Sopenharmony_ci u32 size; 28062306a36Sopenharmony_ci}; 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_cistruct ivtv_user_dma { 28362306a36Sopenharmony_ci struct mutex lock; 28462306a36Sopenharmony_ci int page_count; 28562306a36Sopenharmony_ci struct page *map[IVTV_DMA_SG_OSD_ENT]; 28662306a36Sopenharmony_ci /* Needed when dealing with highmem userspace buffers */ 28762306a36Sopenharmony_ci struct page *bouncemap[IVTV_DMA_SG_OSD_ENT]; 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci /* Base Dev SG Array for cx23415/6 */ 29062306a36Sopenharmony_ci struct ivtv_sg_element SGarray[IVTV_DMA_SG_OSD_ENT]; 29162306a36Sopenharmony_ci dma_addr_t SG_handle; 29262306a36Sopenharmony_ci int SG_length; 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci /* SG List of Buffers */ 29562306a36Sopenharmony_ci struct scatterlist SGlist[IVTV_DMA_SG_OSD_ENT]; 29662306a36Sopenharmony_ci}; 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_cistruct ivtv_dma_page_info { 29962306a36Sopenharmony_ci unsigned long uaddr; 30062306a36Sopenharmony_ci unsigned long first; 30162306a36Sopenharmony_ci unsigned long last; 30262306a36Sopenharmony_ci unsigned int offset; 30362306a36Sopenharmony_ci unsigned int tail; 30462306a36Sopenharmony_ci int page_count; 30562306a36Sopenharmony_ci}; 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_cistruct ivtv_buffer { 30862306a36Sopenharmony_ci struct list_head list; 30962306a36Sopenharmony_ci dma_addr_t dma_handle; 31062306a36Sopenharmony_ci unsigned short b_flags; 31162306a36Sopenharmony_ci unsigned short dma_xfer_cnt; 31262306a36Sopenharmony_ci char *buf; 31362306a36Sopenharmony_ci u32 bytesused; 31462306a36Sopenharmony_ci u32 readpos; 31562306a36Sopenharmony_ci}; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_cistruct ivtv_queue { 31862306a36Sopenharmony_ci struct list_head list; /* the list of buffers in this queue */ 31962306a36Sopenharmony_ci u32 buffers; /* number of buffers in this queue */ 32062306a36Sopenharmony_ci u32 length; /* total number of bytes of available buffer space */ 32162306a36Sopenharmony_ci u32 bytesused; /* total number of bytes used in this queue */ 32262306a36Sopenharmony_ci}; 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_cistruct ivtv; /* forward reference */ 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_cistruct ivtv_stream { 32762306a36Sopenharmony_ci /* These first four fields are always set, even if the stream 32862306a36Sopenharmony_ci is not actually created. */ 32962306a36Sopenharmony_ci struct video_device vdev; /* vdev.v4l2_dev is NULL if there is no device */ 33062306a36Sopenharmony_ci struct ivtv *itv; /* for ease of use */ 33162306a36Sopenharmony_ci const char *name; /* name of the stream */ 33262306a36Sopenharmony_ci int type; /* stream type */ 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci struct v4l2_fh *fh; /* pointer to the streaming filehandle */ 33562306a36Sopenharmony_ci spinlock_t qlock; /* locks access to the queues */ 33662306a36Sopenharmony_ci unsigned long s_flags; /* status flags, see above */ 33762306a36Sopenharmony_ci int dma; /* can be PCI_DMA_TODEVICE, PCI_DMA_FROMDEVICE or PCI_DMA_NONE */ 33862306a36Sopenharmony_ci u32 pending_offset; 33962306a36Sopenharmony_ci u32 pending_backup; 34062306a36Sopenharmony_ci u64 pending_pts; 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci u32 dma_offset; 34362306a36Sopenharmony_ci u32 dma_backup; 34462306a36Sopenharmony_ci u64 dma_pts; 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci int subtype; 34762306a36Sopenharmony_ci wait_queue_head_t waitq; 34862306a36Sopenharmony_ci u32 dma_last_offset; 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci /* Buffer Stats */ 35162306a36Sopenharmony_ci u32 buffers; 35262306a36Sopenharmony_ci u32 buf_size; 35362306a36Sopenharmony_ci u32 buffers_stolen; 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci /* Buffer Queues */ 35662306a36Sopenharmony_ci struct ivtv_queue q_free; /* free buffers */ 35762306a36Sopenharmony_ci struct ivtv_queue q_full; /* full buffers */ 35862306a36Sopenharmony_ci struct ivtv_queue q_io; /* waiting for I/O */ 35962306a36Sopenharmony_ci struct ivtv_queue q_dma; /* waiting for DMA */ 36062306a36Sopenharmony_ci struct ivtv_queue q_predma; /* waiting for DMA */ 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci /* DMA xfer counter, buffers belonging to the same DMA 36362306a36Sopenharmony_ci xfer will have the same dma_xfer_cnt. */ 36462306a36Sopenharmony_ci u16 dma_xfer_cnt; 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci /* Base Dev SG Array for cx23415/6 */ 36762306a36Sopenharmony_ci struct ivtv_sg_host_element *sg_pending; 36862306a36Sopenharmony_ci struct ivtv_sg_host_element *sg_processing; 36962306a36Sopenharmony_ci struct ivtv_sg_element *sg_dma; 37062306a36Sopenharmony_ci dma_addr_t sg_handle; 37162306a36Sopenharmony_ci int sg_pending_size; 37262306a36Sopenharmony_ci int sg_processing_size; 37362306a36Sopenharmony_ci int sg_processed; 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci /* SG List of Buffers */ 37662306a36Sopenharmony_ci struct scatterlist *SGlist; 37762306a36Sopenharmony_ci}; 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_cistruct ivtv_open_id { 38062306a36Sopenharmony_ci struct v4l2_fh fh; 38162306a36Sopenharmony_ci int type; /* stream type */ 38262306a36Sopenharmony_ci int yuv_frames; /* 1: started OUT_UDMA_YUV output mode */ 38362306a36Sopenharmony_ci struct ivtv *itv; 38462306a36Sopenharmony_ci}; 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_cistatic inline struct ivtv_open_id *fh2id(struct v4l2_fh *fh) 38762306a36Sopenharmony_ci{ 38862306a36Sopenharmony_ci return container_of(fh, struct ivtv_open_id, fh); 38962306a36Sopenharmony_ci} 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_cistruct yuv_frame_info 39262306a36Sopenharmony_ci{ 39362306a36Sopenharmony_ci u32 update; 39462306a36Sopenharmony_ci s32 src_x; 39562306a36Sopenharmony_ci s32 src_y; 39662306a36Sopenharmony_ci u32 src_w; 39762306a36Sopenharmony_ci u32 src_h; 39862306a36Sopenharmony_ci s32 dst_x; 39962306a36Sopenharmony_ci s32 dst_y; 40062306a36Sopenharmony_ci u32 dst_w; 40162306a36Sopenharmony_ci u32 dst_h; 40262306a36Sopenharmony_ci s32 pan_x; 40362306a36Sopenharmony_ci s32 pan_y; 40462306a36Sopenharmony_ci u32 vis_w; 40562306a36Sopenharmony_ci u32 vis_h; 40662306a36Sopenharmony_ci u32 interlaced_y; 40762306a36Sopenharmony_ci u32 interlaced_uv; 40862306a36Sopenharmony_ci s32 tru_x; 40962306a36Sopenharmony_ci u32 tru_w; 41062306a36Sopenharmony_ci u32 tru_h; 41162306a36Sopenharmony_ci u32 offset_y; 41262306a36Sopenharmony_ci s32 lace_mode; 41362306a36Sopenharmony_ci u32 sync_field; 41462306a36Sopenharmony_ci u32 delay; 41562306a36Sopenharmony_ci u32 interlaced; 41662306a36Sopenharmony_ci}; 41762306a36Sopenharmony_ci 41862306a36Sopenharmony_ci#define IVTV_YUV_MODE_INTERLACED 0x00 41962306a36Sopenharmony_ci#define IVTV_YUV_MODE_PROGRESSIVE 0x01 42062306a36Sopenharmony_ci#define IVTV_YUV_MODE_AUTO 0x02 42162306a36Sopenharmony_ci#define IVTV_YUV_MODE_MASK 0x03 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_ci#define IVTV_YUV_SYNC_EVEN 0x00 42462306a36Sopenharmony_ci#define IVTV_YUV_SYNC_ODD 0x04 42562306a36Sopenharmony_ci#define IVTV_YUV_SYNC_MASK 0x04 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_ci#define IVTV_YUV_BUFFERS 8 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_cistruct yuv_playback_info 43062306a36Sopenharmony_ci{ 43162306a36Sopenharmony_ci u32 reg_2834; 43262306a36Sopenharmony_ci u32 reg_2838; 43362306a36Sopenharmony_ci u32 reg_283c; 43462306a36Sopenharmony_ci u32 reg_2840; 43562306a36Sopenharmony_ci u32 reg_2844; 43662306a36Sopenharmony_ci u32 reg_2848; 43762306a36Sopenharmony_ci u32 reg_2854; 43862306a36Sopenharmony_ci u32 reg_285c; 43962306a36Sopenharmony_ci u32 reg_2864; 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci u32 reg_2870; 44262306a36Sopenharmony_ci u32 reg_2874; 44362306a36Sopenharmony_ci u32 reg_2890; 44462306a36Sopenharmony_ci u32 reg_2898; 44562306a36Sopenharmony_ci u32 reg_289c; 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci u32 reg_2918; 44862306a36Sopenharmony_ci u32 reg_291c; 44962306a36Sopenharmony_ci u32 reg_2920; 45062306a36Sopenharmony_ci u32 reg_2924; 45162306a36Sopenharmony_ci u32 reg_2928; 45262306a36Sopenharmony_ci u32 reg_292c; 45362306a36Sopenharmony_ci u32 reg_2930; 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ci u32 reg_2934; 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci u32 reg_2938; 45862306a36Sopenharmony_ci u32 reg_293c; 45962306a36Sopenharmony_ci u32 reg_2940; 46062306a36Sopenharmony_ci u32 reg_2944; 46162306a36Sopenharmony_ci u32 reg_2948; 46262306a36Sopenharmony_ci u32 reg_294c; 46362306a36Sopenharmony_ci u32 reg_2950; 46462306a36Sopenharmony_ci u32 reg_2954; 46562306a36Sopenharmony_ci u32 reg_2958; 46662306a36Sopenharmony_ci u32 reg_295c; 46762306a36Sopenharmony_ci u32 reg_2960; 46862306a36Sopenharmony_ci u32 reg_2964; 46962306a36Sopenharmony_ci u32 reg_2968; 47062306a36Sopenharmony_ci u32 reg_296c; 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci u32 reg_2970; 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci int v_filter_1; 47562306a36Sopenharmony_ci int v_filter_2; 47662306a36Sopenharmony_ci int h_filter; 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ci u8 track_osd; /* Should yuv output track the OSD size & position */ 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci u32 osd_x_offset; 48162306a36Sopenharmony_ci u32 osd_y_offset; 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_ci u32 osd_x_pan; 48462306a36Sopenharmony_ci u32 osd_y_pan; 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci u32 osd_vis_w; 48762306a36Sopenharmony_ci u32 osd_vis_h; 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci u32 osd_full_w; 49062306a36Sopenharmony_ci u32 osd_full_h; 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci int decode_height; 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_ci int lace_mode; 49562306a36Sopenharmony_ci int lace_threshold; 49662306a36Sopenharmony_ci int lace_sync_field; 49762306a36Sopenharmony_ci 49862306a36Sopenharmony_ci atomic_t next_dma_frame; 49962306a36Sopenharmony_ci atomic_t next_fill_frame; 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_ci u32 yuv_forced_update; 50262306a36Sopenharmony_ci int update_frame; 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci u8 fields_lapsed; /* Counter used when delaying a frame */ 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_ci struct yuv_frame_info new_frame_info[IVTV_YUV_BUFFERS]; 50762306a36Sopenharmony_ci struct yuv_frame_info old_frame_info; 50862306a36Sopenharmony_ci struct yuv_frame_info old_frame_info_args; 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ci void *blanking_ptr; 51162306a36Sopenharmony_ci dma_addr_t blanking_dmaptr; 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci int stream_size; 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci u8 draw_frame; /* PVR350 buffer to draw into */ 51662306a36Sopenharmony_ci u8 max_frames_buffered; /* Maximum number of frames to buffer */ 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_ci struct v4l2_rect main_rect; 51962306a36Sopenharmony_ci u32 v4l2_src_w; 52062306a36Sopenharmony_ci u32 v4l2_src_h; 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_ci u8 running; /* Have any frames been displayed */ 52362306a36Sopenharmony_ci}; 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_ci#define IVTV_VBI_FRAMES 32 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ci/* VBI data */ 52862306a36Sopenharmony_cistruct vbi_cc { 52962306a36Sopenharmony_ci u8 odd[2]; /* two-byte payload of odd field */ 53062306a36Sopenharmony_ci u8 even[2]; /* two-byte payload of even field */; 53162306a36Sopenharmony_ci}; 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_cistruct vbi_vps { 53462306a36Sopenharmony_ci u8 data[5]; /* five-byte VPS payload */ 53562306a36Sopenharmony_ci}; 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_cistruct vbi_info { 53862306a36Sopenharmony_ci /* VBI general data, does not change during streaming */ 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci u32 raw_decoder_line_size; /* raw VBI line size from digitizer */ 54162306a36Sopenharmony_ci u8 raw_decoder_sav_odd_field; /* raw VBI Start Active Video digitizer code of odd field */ 54262306a36Sopenharmony_ci u8 raw_decoder_sav_even_field; /* raw VBI Start Active Video digitizer code of even field */ 54362306a36Sopenharmony_ci u32 sliced_decoder_line_size; /* sliced VBI line size from digitizer */ 54462306a36Sopenharmony_ci u8 sliced_decoder_sav_odd_field; /* sliced VBI Start Active Video digitizer code of odd field */ 54562306a36Sopenharmony_ci u8 sliced_decoder_sav_even_field; /* sliced VBI Start Active Video digitizer code of even field */ 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_ci u32 start[2]; /* start of first VBI line in the odd/even fields */ 54862306a36Sopenharmony_ci u32 count; /* number of VBI lines per field */ 54962306a36Sopenharmony_ci u32 raw_size; /* size of raw VBI line from the digitizer */ 55062306a36Sopenharmony_ci u32 sliced_size; /* size of sliced VBI line from the digitizer */ 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci u32 dec_start; /* start in decoder memory of VBI re-insertion buffers */ 55362306a36Sopenharmony_ci u32 enc_start; /* start in encoder memory of VBI capture buffers */ 55462306a36Sopenharmony_ci u32 enc_size; /* size of VBI capture area */ 55562306a36Sopenharmony_ci int fpi; /* number of VBI frames per interrupt */ 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci struct v4l2_format in; /* current VBI capture format */ 55862306a36Sopenharmony_ci struct v4l2_sliced_vbi_format *sliced_in; /* convenience pointer to sliced struct in vbi.in union */ 55962306a36Sopenharmony_ci int insert_mpeg; /* if non-zero, then embed VBI data in MPEG stream */ 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci /* Raw VBI compatibility hack */ 56262306a36Sopenharmony_ci 56362306a36Sopenharmony_ci u32 frame; /* frame counter hack needed for backwards compatibility 56462306a36Sopenharmony_ci of old VBI software */ 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_ci /* Sliced VBI output data */ 56762306a36Sopenharmony_ci 56862306a36Sopenharmony_ci struct vbi_cc cc_payload[256]; /* sliced VBI CC payload array: it is an array to 56962306a36Sopenharmony_ci prevent dropping CC data if they couldn't be 57062306a36Sopenharmony_ci processed fast enough */ 57162306a36Sopenharmony_ci int cc_payload_idx; /* index in cc_payload */ 57262306a36Sopenharmony_ci u8 cc_missing_cnt; /* counts number of frames without CC for passthrough mode */ 57362306a36Sopenharmony_ci int wss_payload; /* sliced VBI WSS payload */ 57462306a36Sopenharmony_ci u8 wss_missing_cnt; /* counts number of frames without WSS for passthrough mode */ 57562306a36Sopenharmony_ci struct vbi_vps vps_payload; /* sliced VBI VPS payload */ 57662306a36Sopenharmony_ci 57762306a36Sopenharmony_ci /* Sliced VBI capture data */ 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci struct v4l2_sliced_vbi_data sliced_data[36]; /* sliced VBI storage for VBI encoder stream */ 58062306a36Sopenharmony_ci struct v4l2_sliced_vbi_data sliced_dec_data[36];/* sliced VBI storage for VBI decoder stream */ 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_ci /* VBI Embedding data */ 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_ci /* Buffer for VBI data inserted into MPEG stream. 58562306a36Sopenharmony_ci The first byte is a dummy byte that's never used. 58662306a36Sopenharmony_ci The next 16 bytes contain the MPEG header for the VBI data, 58762306a36Sopenharmony_ci the remainder is the actual VBI data. 58862306a36Sopenharmony_ci The max size accepted by the MPEG VBI reinsertion turns out 58962306a36Sopenharmony_ci to be 1552 bytes, which happens to be 4 + (1 + 42) * (2 * 18) bytes, 59062306a36Sopenharmony_ci where 4 is a four byte header, 42 is the max sliced VBI payload, 1 is 59162306a36Sopenharmony_ci a single line header byte and 2 * 18 is the number of VBI lines per frame. 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ci However, it seems that the data must be 1K aligned, so we have to 59462306a36Sopenharmony_ci pad the data until the 1 or 2 K boundary. 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_ci This pointer array will allocate 2049 bytes to store each VBI frame. */ 59762306a36Sopenharmony_ci u8 *sliced_mpeg_data[IVTV_VBI_FRAMES]; 59862306a36Sopenharmony_ci u32 sliced_mpeg_size[IVTV_VBI_FRAMES]; 59962306a36Sopenharmony_ci struct ivtv_buffer sliced_mpeg_buf; /* temporary buffer holding data from sliced_mpeg_data */ 60062306a36Sopenharmony_ci u32 inserted_frame; /* index in sliced_mpeg_size of next sliced data 60162306a36Sopenharmony_ci to be inserted in the MPEG stream */ 60262306a36Sopenharmony_ci}; 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_ci/* forward declaration of struct defined in ivtv-cards.h */ 60562306a36Sopenharmony_cistruct ivtv_card; 60662306a36Sopenharmony_ci 60762306a36Sopenharmony_ci/* Struct to hold info about ivtv cards */ 60862306a36Sopenharmony_cistruct ivtv { 60962306a36Sopenharmony_ci /* General fixed card data */ 61062306a36Sopenharmony_ci struct pci_dev *pdev; /* PCI device */ 61162306a36Sopenharmony_ci const struct ivtv_card *card; /* card information */ 61262306a36Sopenharmony_ci const char *card_name; /* full name of the card */ 61362306a36Sopenharmony_ci const struct ivtv_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */ 61462306a36Sopenharmony_ci u8 has_cx23415; /* 1 if it is a cx23415 based card, 0 for cx23416 */ 61562306a36Sopenharmony_ci u8 pvr150_workaround; /* 1 if the cx25840 needs to workaround a PVR150 bug */ 61662306a36Sopenharmony_ci u8 nof_inputs; /* number of video inputs */ 61762306a36Sopenharmony_ci u8 nof_audio_inputs; /* number of audio inputs */ 61862306a36Sopenharmony_ci u32 v4l2_cap; /* V4L2 capabilities of card */ 61962306a36Sopenharmony_ci u32 hw_flags; /* hardware description of the board */ 62062306a36Sopenharmony_ci v4l2_std_id tuner_std; /* the norm of the card's tuner (fixed) */ 62162306a36Sopenharmony_ci struct v4l2_subdev *sd_video; /* controlling video decoder subdev */ 62262306a36Sopenharmony_ci struct v4l2_subdev *sd_audio; /* controlling audio subdev */ 62362306a36Sopenharmony_ci struct v4l2_subdev *sd_muxer; /* controlling audio muxer subdev */ 62462306a36Sopenharmony_ci resource_size_t base_addr; /* PCI resource base address */ 62562306a36Sopenharmony_ci volatile void __iomem *enc_mem; /* pointer to mapped encoder memory */ 62662306a36Sopenharmony_ci volatile void __iomem *dec_mem; /* pointer to mapped decoder memory */ 62762306a36Sopenharmony_ci volatile void __iomem *reg_mem; /* pointer to mapped registers */ 62862306a36Sopenharmony_ci struct ivtv_options options; /* user options */ 62962306a36Sopenharmony_ci 63062306a36Sopenharmony_ci struct v4l2_device v4l2_dev; 63162306a36Sopenharmony_ci struct cx2341x_handler cxhdl; 63262306a36Sopenharmony_ci struct { 63362306a36Sopenharmony_ci /* PTS/Frame count control cluster */ 63462306a36Sopenharmony_ci struct v4l2_ctrl *ctrl_pts; 63562306a36Sopenharmony_ci struct v4l2_ctrl *ctrl_frame; 63662306a36Sopenharmony_ci }; 63762306a36Sopenharmony_ci struct { 63862306a36Sopenharmony_ci /* Audio Playback control cluster */ 63962306a36Sopenharmony_ci struct v4l2_ctrl *ctrl_audio_playback; 64062306a36Sopenharmony_ci struct v4l2_ctrl *ctrl_audio_multilingual_playback; 64162306a36Sopenharmony_ci }; 64262306a36Sopenharmony_ci struct v4l2_ctrl_handler hdl_gpio; 64362306a36Sopenharmony_ci struct v4l2_subdev sd_gpio; /* GPIO sub-device */ 64462306a36Sopenharmony_ci u16 instance; 64562306a36Sopenharmony_ci 64662306a36Sopenharmony_ci /* High-level state info */ 64762306a36Sopenharmony_ci unsigned long i_flags; /* global ivtv flags */ 64862306a36Sopenharmony_ci u8 is_50hz; /* 1 if the current capture standard is 50 Hz */ 64962306a36Sopenharmony_ci u8 is_60hz /* 1 if the current capture standard is 60 Hz */; 65062306a36Sopenharmony_ci u8 is_out_50hz /* 1 if the current TV output standard is 50 Hz */; 65162306a36Sopenharmony_ci u8 is_out_60hz /* 1 if the current TV output standard is 60 Hz */; 65262306a36Sopenharmony_ci int output_mode; /* decoder output mode: NONE, MPG, YUV, UDMA YUV, passthrough */ 65362306a36Sopenharmony_ci u32 audio_input; /* current audio input */ 65462306a36Sopenharmony_ci u32 active_input; /* current video input */ 65562306a36Sopenharmony_ci u32 active_output; /* current video output */ 65662306a36Sopenharmony_ci v4l2_std_id std; /* current capture TV standard */ 65762306a36Sopenharmony_ci v4l2_std_id std_out; /* current TV output standard */ 65862306a36Sopenharmony_ci u8 audio_stereo_mode; /* decoder setting how to handle stereo MPEG audio */ 65962306a36Sopenharmony_ci u8 audio_bilingual_mode; /* decoder setting how to handle bilingual MPEG audio */ 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_ci /* Locking */ 66262306a36Sopenharmony_ci spinlock_t lock; /* lock access to this struct */ 66362306a36Sopenharmony_ci struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */ 66462306a36Sopenharmony_ci 66562306a36Sopenharmony_ci /* Streams */ 66662306a36Sopenharmony_ci int stream_buf_size[IVTV_MAX_STREAMS]; /* stream buffer size */ 66762306a36Sopenharmony_ci struct ivtv_stream streams[IVTV_MAX_STREAMS]; /* stream data */ 66862306a36Sopenharmony_ci atomic_t capturing; /* count number of active capture streams */ 66962306a36Sopenharmony_ci atomic_t decoding; /* count number of active decoding streams */ 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci /* ALSA interface for PCM capture stream */ 67262306a36Sopenharmony_ci struct snd_ivtv_card *alsa; 67362306a36Sopenharmony_ci void (*pcm_announce_callback)(struct snd_ivtv_card *card, u8 *pcm_data, 67462306a36Sopenharmony_ci size_t num_bytes); 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ci /* Used for ivtv-alsa module loading */ 67762306a36Sopenharmony_ci struct work_struct request_module_wk; 67862306a36Sopenharmony_ci 67962306a36Sopenharmony_ci /* Interrupts & DMA */ 68062306a36Sopenharmony_ci u32 irqmask; /* active interrupts */ 68162306a36Sopenharmony_ci u32 irq_rr_idx; /* round-robin stream index */ 68262306a36Sopenharmony_ci struct kthread_worker irq_worker; /* kthread worker for PIO/YUV/VBI actions */ 68362306a36Sopenharmony_ci struct task_struct *irq_worker_task; /* task for irq_worker */ 68462306a36Sopenharmony_ci struct kthread_work irq_work; /* kthread work entry */ 68562306a36Sopenharmony_ci spinlock_t dma_reg_lock; /* lock access to DMA engine registers */ 68662306a36Sopenharmony_ci int cur_dma_stream; /* index of current stream doing DMA (-1 if none) */ 68762306a36Sopenharmony_ci int cur_pio_stream; /* index of current stream doing PIO (-1 if none) */ 68862306a36Sopenharmony_ci u32 dma_data_req_offset; /* store offset in decoder memory of current DMA request */ 68962306a36Sopenharmony_ci u32 dma_data_req_size; /* store size of current DMA request */ 69062306a36Sopenharmony_ci int dma_retries; /* current DMA retry attempt */ 69162306a36Sopenharmony_ci struct ivtv_user_dma udma; /* user based DMA for OSD */ 69262306a36Sopenharmony_ci struct timer_list dma_timer; /* timer used to catch unfinished DMAs */ 69362306a36Sopenharmony_ci u32 last_vsync_field; /* last seen vsync field */ 69462306a36Sopenharmony_ci wait_queue_head_t dma_waitq; /* wake up when the current DMA is finished */ 69562306a36Sopenharmony_ci wait_queue_head_t eos_waitq; /* wake up when EOS arrives */ 69662306a36Sopenharmony_ci wait_queue_head_t event_waitq; /* wake up when the next decoder event arrives */ 69762306a36Sopenharmony_ci wait_queue_head_t vsync_waitq; /* wake up when the next decoder vsync arrives */ 69862306a36Sopenharmony_ci 69962306a36Sopenharmony_ci 70062306a36Sopenharmony_ci /* Mailbox */ 70162306a36Sopenharmony_ci struct ivtv_mailbox_data enc_mbox; /* encoder mailboxes */ 70262306a36Sopenharmony_ci struct ivtv_mailbox_data dec_mbox; /* decoder mailboxes */ 70362306a36Sopenharmony_ci struct ivtv_api_cache api_cache[256]; /* cached API commands */ 70462306a36Sopenharmony_ci 70562306a36Sopenharmony_ci 70662306a36Sopenharmony_ci /* I2C */ 70762306a36Sopenharmony_ci struct i2c_adapter i2c_adap; 70862306a36Sopenharmony_ci struct i2c_algo_bit_data i2c_algo; 70962306a36Sopenharmony_ci struct i2c_client i2c_client; 71062306a36Sopenharmony_ci int i2c_state; /* i2c bit state */ 71162306a36Sopenharmony_ci struct mutex i2c_bus_lock; /* lock i2c bus */ 71262306a36Sopenharmony_ci 71362306a36Sopenharmony_ci struct IR_i2c_init_data ir_i2c_init_data; 71462306a36Sopenharmony_ci 71562306a36Sopenharmony_ci /* Program Index information */ 71662306a36Sopenharmony_ci u32 pgm_info_offset; /* start of pgm info in encoder memory */ 71762306a36Sopenharmony_ci u32 pgm_info_num; /* number of elements in the pgm cyclic buffer in encoder memory */ 71862306a36Sopenharmony_ci u32 pgm_info_write_idx; /* last index written by the card that was transferred to pgm_info[] */ 71962306a36Sopenharmony_ci u32 pgm_info_read_idx; /* last index in pgm_info read by the application */ 72062306a36Sopenharmony_ci struct v4l2_enc_idx_entry pgm_info[IVTV_MAX_PGM_INDEX]; /* filled from the pgm cyclic buffer on the card */ 72162306a36Sopenharmony_ci 72262306a36Sopenharmony_ci 72362306a36Sopenharmony_ci /* Miscellaneous */ 72462306a36Sopenharmony_ci u32 open_id; /* incremented each time an open occurs, is >= 1 */ 72562306a36Sopenharmony_ci int search_pack_header; /* 1 if ivtv_copy_buf_to_user() is scanning for a pack header (0xba) */ 72662306a36Sopenharmony_ci int speed; /* current playback speed setting */ 72762306a36Sopenharmony_ci u8 speed_mute_audio; /* 1 if audio should be muted when fast forward */ 72862306a36Sopenharmony_ci u64 mpg_data_received; /* number of bytes received from the MPEG stream */ 72962306a36Sopenharmony_ci u64 vbi_data_inserted; /* number of VBI bytes inserted into the MPEG stream */ 73062306a36Sopenharmony_ci u32 last_dec_timing[3]; /* cache last retrieved pts/scr/frame values */ 73162306a36Sopenharmony_ci unsigned long dualwatch_jiffies;/* jiffies value of the previous dualwatch check */ 73262306a36Sopenharmony_ci u32 dualwatch_stereo_mode; /* current detected dualwatch stereo mode */ 73362306a36Sopenharmony_ci 73462306a36Sopenharmony_ci 73562306a36Sopenharmony_ci /* VBI state info */ 73662306a36Sopenharmony_ci struct vbi_info vbi; /* VBI-specific data */ 73762306a36Sopenharmony_ci 73862306a36Sopenharmony_ci 73962306a36Sopenharmony_ci /* YUV playback */ 74062306a36Sopenharmony_ci struct yuv_playback_info yuv_info; /* YUV playback data */ 74162306a36Sopenharmony_ci 74262306a36Sopenharmony_ci 74362306a36Sopenharmony_ci /* OSD support */ 74462306a36Sopenharmony_ci unsigned long osd_video_pbase; 74562306a36Sopenharmony_ci int osd_global_alpha_state; /* 1 = global alpha is on */ 74662306a36Sopenharmony_ci int osd_local_alpha_state; /* 1 = local alpha is on */ 74762306a36Sopenharmony_ci int osd_chroma_key_state; /* 1 = chroma-keying is on */ 74862306a36Sopenharmony_ci u8 osd_global_alpha; /* current global alpha */ 74962306a36Sopenharmony_ci u32 osd_chroma_key; /* current chroma key */ 75062306a36Sopenharmony_ci struct v4l2_rect osd_rect; /* current OSD position and size */ 75162306a36Sopenharmony_ci struct v4l2_rect main_rect; /* current Main window position and size */ 75262306a36Sopenharmony_ci struct osd_info *osd_info; /* ivtvfb private OSD info */ 75362306a36Sopenharmony_ci void (*ivtvfb_restore)(struct ivtv *itv); /* Used for a warm start */ 75462306a36Sopenharmony_ci}; 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_cistatic inline struct ivtv *to_ivtv(struct v4l2_device *v4l2_dev) 75762306a36Sopenharmony_ci{ 75862306a36Sopenharmony_ci return container_of(v4l2_dev, struct ivtv, v4l2_dev); 75962306a36Sopenharmony_ci} 76062306a36Sopenharmony_ci 76162306a36Sopenharmony_ci/* ivtv extensions to be loaded */ 76262306a36Sopenharmony_ciextern int (*ivtv_ext_init)(struct ivtv *); 76362306a36Sopenharmony_ci 76462306a36Sopenharmony_ci/* Globals */ 76562306a36Sopenharmony_ciextern int ivtv_first_minor; 76662306a36Sopenharmony_ci 76762306a36Sopenharmony_ci/*==============Prototypes==================*/ 76862306a36Sopenharmony_ci 76962306a36Sopenharmony_ci/* Hardware/IRQ */ 77062306a36Sopenharmony_civoid ivtv_set_irq_mask(struct ivtv *itv, u32 mask); 77162306a36Sopenharmony_civoid ivtv_clear_irq_mask(struct ivtv *itv, u32 mask); 77262306a36Sopenharmony_ci 77362306a36Sopenharmony_ci/* try to set output mode, return current mode. */ 77462306a36Sopenharmony_ciint ivtv_set_output_mode(struct ivtv *itv, int mode); 77562306a36Sopenharmony_ci 77662306a36Sopenharmony_ci/* return current output stream based on current mode */ 77762306a36Sopenharmony_cistruct ivtv_stream *ivtv_get_output_stream(struct ivtv *itv); 77862306a36Sopenharmony_ci 77962306a36Sopenharmony_ci/* Return non-zero if a signal is pending */ 78062306a36Sopenharmony_ciint ivtv_msleep_timeout(unsigned int msecs, int intr); 78162306a36Sopenharmony_ci 78262306a36Sopenharmony_ci/* Wait on queue, returns -EINTR if interrupted */ 78362306a36Sopenharmony_ciint ivtv_waitq(wait_queue_head_t *waitq); 78462306a36Sopenharmony_ci 78562306a36Sopenharmony_ci/* Read Hauppauge eeprom */ 78662306a36Sopenharmony_cistruct tveeprom; /* forward reference */ 78762306a36Sopenharmony_civoid ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv); 78862306a36Sopenharmony_ci 78962306a36Sopenharmony_ci/* First-open initialization: load firmware, init cx25840, etc. */ 79062306a36Sopenharmony_ciint ivtv_init_on_first_open(struct ivtv *itv); 79162306a36Sopenharmony_ci 79262306a36Sopenharmony_ci/* Test if the current VBI mode is raw (1) or sliced (0) */ 79362306a36Sopenharmony_cistatic inline int ivtv_raw_vbi(const struct ivtv *itv) 79462306a36Sopenharmony_ci{ 79562306a36Sopenharmony_ci return itv->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE; 79662306a36Sopenharmony_ci} 79762306a36Sopenharmony_ci 79862306a36Sopenharmony_ci/* This is a PCI post thing, where if the pci register is not read, then 79962306a36Sopenharmony_ci the write doesn't always take effect right away. By reading back the 80062306a36Sopenharmony_ci register any pending PCI writes will be performed (in order), and so 80162306a36Sopenharmony_ci you can be sure that the writes are guaranteed to be done. 80262306a36Sopenharmony_ci 80362306a36Sopenharmony_ci Rarely needed, only in some timing sensitive cases. 80462306a36Sopenharmony_ci Apparently if this is not done some motherboards seem 80562306a36Sopenharmony_ci to kill the firmware and get into the broken state until computer is 80662306a36Sopenharmony_ci rebooted. */ 80762306a36Sopenharmony_ci#define write_sync(val, reg) \ 80862306a36Sopenharmony_ci do { writel(val, reg); readl(reg); } while (0) 80962306a36Sopenharmony_ci 81062306a36Sopenharmony_ci#define read_reg(reg) readl(itv->reg_mem + (reg)) 81162306a36Sopenharmony_ci#define write_reg(val, reg) writel(val, itv->reg_mem + (reg)) 81262306a36Sopenharmony_ci#define write_reg_sync(val, reg) \ 81362306a36Sopenharmony_ci do { write_reg(val, reg); read_reg(reg); } while (0) 81462306a36Sopenharmony_ci 81562306a36Sopenharmony_ci#define read_enc(addr) readl(itv->enc_mem + (u32)(addr)) 81662306a36Sopenharmony_ci#define write_enc(val, addr) writel(val, itv->enc_mem + (u32)(addr)) 81762306a36Sopenharmony_ci#define write_enc_sync(val, addr) \ 81862306a36Sopenharmony_ci do { write_enc(val, addr); read_enc(addr); } while (0) 81962306a36Sopenharmony_ci 82062306a36Sopenharmony_ci#define read_dec(addr) readl(itv->dec_mem + (u32)(addr)) 82162306a36Sopenharmony_ci#define write_dec(val, addr) writel(val, itv->dec_mem + (u32)(addr)) 82262306a36Sopenharmony_ci#define write_dec_sync(val, addr) \ 82362306a36Sopenharmony_ci do { write_dec(val, addr); read_dec(addr); } while (0) 82462306a36Sopenharmony_ci 82562306a36Sopenharmony_ci/* Call the specified callback for all subdevs matching hw (if 0, then 82662306a36Sopenharmony_ci match them all). Ignore any errors. */ 82762306a36Sopenharmony_ci#define ivtv_call_hw(itv, hw, o, f, args...) \ 82862306a36Sopenharmony_ci v4l2_device_mask_call_all(&(itv)->v4l2_dev, hw, o, f, ##args) 82962306a36Sopenharmony_ci 83062306a36Sopenharmony_ci#define ivtv_call_all(itv, o, f, args...) ivtv_call_hw(itv, 0, o, f , ##args) 83162306a36Sopenharmony_ci 83262306a36Sopenharmony_ci/* Call the specified callback for all subdevs matching hw (if 0, then 83362306a36Sopenharmony_ci match them all). If the callback returns an error other than 0 or 83462306a36Sopenharmony_ci -ENOIOCTLCMD, then return with that error code. */ 83562306a36Sopenharmony_ci#define ivtv_call_hw_err(itv, hw, o, f, args...) \ 83662306a36Sopenharmony_ci v4l2_device_mask_call_until_err(&(itv)->v4l2_dev, hw, o, f, ##args) 83762306a36Sopenharmony_ci 83862306a36Sopenharmony_ci#define ivtv_call_all_err(itv, o, f, args...) ivtv_call_hw_err(itv, 0, o, f , ##args) 83962306a36Sopenharmony_ci 84062306a36Sopenharmony_ci#endif 841